@@ -33,20 +33,22 @@ void PrintLockContention(const char* pszName, const char* pszFile, int nLine)
33
33
//
34
34
35
35
struct CLockLocation {
36
- CLockLocation (const char * pszName, const char * pszFile, int nLine)
36
+ CLockLocation (const char * pszName, const char * pszFile, int nLine, bool fTryIn )
37
37
{
38
38
mutexName = pszName;
39
39
sourceFile = pszFile;
40
40
sourceLine = nLine;
41
+ fTry = fTryIn ;
41
42
}
42
43
43
44
std::string ToString () const
44
45
{
45
- return mutexName + " " + sourceFile + " :" + itostr (sourceLine);
46
+ return mutexName + " " + sourceFile + " :" + itostr (sourceLine) + ( fTry ? " (TRY) " : " " ) ;
46
47
}
47
48
48
49
std::string MutexName () const { return mutexName; }
49
50
51
+ bool fTry ;
50
52
private:
51
53
std::string mutexName;
52
54
std::string sourceFile;
@@ -62,23 +64,52 @@ static boost::thread_specific_ptr<LockStack> lockstack;
62
64
63
65
static void potential_deadlock_detected (const std::pair<void *, void *>& mismatch, const LockStack& s1, const LockStack& s2)
64
66
{
67
+ // We attempt to not assert on probably-not deadlocks by assuming that
68
+ // a try lock will immediately have otherwise bailed if it had
69
+ // failed to get the lock
70
+ // We do this by, for the locks which triggered the potential deadlock,
71
+ // in either lockorder, checking that the second of the two which is locked
72
+ // is only a TRY_LOCK, ignoring locks if they are reentrant.
73
+ bool firstLocked = false ;
74
+ bool secondLocked = false ;
75
+ bool onlyMaybeDeadlock = false ;
76
+
65
77
LogPrintf (" POTENTIAL DEADLOCK DETECTED\n " );
66
78
LogPrintf (" Previous lock order was:\n " );
67
79
BOOST_FOREACH (const PAIRTYPE (void *, CLockLocation) & i, s2) {
68
- if (i.first == mismatch.first )
80
+ if (i.first == mismatch.first ) {
69
81
LogPrintf (" (1)" );
70
- if (i.first == mismatch.second )
82
+ if (!firstLocked && secondLocked && i.second .fTry )
83
+ onlyMaybeDeadlock = true ;
84
+ firstLocked = true ;
85
+ }
86
+ if (i.first == mismatch.second ) {
71
87
LogPrintf (" (2)" );
88
+ if (!secondLocked && firstLocked && i.second .fTry )
89
+ onlyMaybeDeadlock = true ;
90
+ secondLocked = true ;
91
+ }
72
92
LogPrintf (" %s\n " , i.second .ToString ());
73
93
}
94
+ firstLocked = false ;
95
+ secondLocked = false ;
74
96
LogPrintf (" Current lock order is:\n " );
75
97
BOOST_FOREACH (const PAIRTYPE (void *, CLockLocation) & i, s1) {
76
- if (i.first == mismatch.first )
98
+ if (i.first == mismatch.first ) {
77
99
LogPrintf (" (1)" );
78
- if (i.first == mismatch.second )
100
+ if (!firstLocked && secondLocked && i.second .fTry )
101
+ onlyMaybeDeadlock = true ;
102
+ firstLocked = true ;
103
+ }
104
+ if (i.first == mismatch.second ) {
79
105
LogPrintf (" (2)" );
106
+ if (!secondLocked && firstLocked && i.second .fTry )
107
+ onlyMaybeDeadlock = true ;
108
+ secondLocked = true ;
109
+ }
80
110
LogPrintf (" %s\n " , i.second .ToString ());
81
111
}
112
+ assert (onlyMaybeDeadlock);
82
113
}
83
114
84
115
static void push_lock (void * c, const CLockLocation& locklocation, bool fTry )
@@ -101,10 +132,8 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
101
132
lockorders[p1] = (*lockstack);
102
133
103
134
std::pair<void *, void *> p2 = std::make_pair (c, i.first );
104
- if (lockorders.count (p2)) {
135
+ if (lockorders.count (p2))
105
136
potential_deadlock_detected (p1, lockorders[p2], lockorders[p1]);
106
- break ;
107
- }
108
137
}
109
138
}
110
139
dd_mutex.unlock ();
@@ -119,7 +148,7 @@ static void pop_lock()
119
148
120
149
void EnterCritical (const char * pszName, const char * pszFile, int nLine, void * cs, bool fTry )
121
150
{
122
- push_lock (cs, CLockLocation (pszName, pszFile, nLine), fTry );
151
+ push_lock (cs, CLockLocation (pszName, pszFile, nLine, fTry ), fTry );
123
152
}
124
153
125
154
void LeaveCritical ()
0 commit comments