@@ -33,20 +33,22 @@ void PrintLockContention(const char* pszName, const char* pszFile, int nLine)
3333//
3434
3535struct CLockLocation {
36- CLockLocation (const char * pszName, const char * pszFile, int nLine)
36+ CLockLocation (const char * pszName, const char * pszFile, int nLine, bool fTryIn )
3737 {
3838 mutexName = pszName;
3939 sourceFile = pszFile;
4040 sourceLine = nLine;
41+ fTry = fTryIn ;
4142 }
4243
4344 std::string ToString () const
4445 {
45- return mutexName + " " + sourceFile + " :" + itostr (sourceLine);
46+ return mutexName + " " + sourceFile + " :" + itostr (sourceLine) + ( fTry ? " (TRY) " : " " ) ;
4647 }
4748
4849 std::string MutexName () const { return mutexName; }
4950
51+ bool fTry ;
5052private:
5153 std::string mutexName;
5254 std::string sourceFile;
@@ -62,23 +64,52 @@ static boost::thread_specific_ptr<LockStack> lockstack;
6264
6365static void potential_deadlock_detected (const std::pair<void *, void *>& mismatch, const LockStack& s1, const LockStack& s2)
6466{
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+
6577 LogPrintf (" POTENTIAL DEADLOCK DETECTED\n " );
6678 LogPrintf (" Previous lock order was:\n " );
6779 BOOST_FOREACH (const PAIRTYPE (void *, CLockLocation) & i, s2) {
68- if (i.first == mismatch.first )
80+ if (i.first == mismatch.first ) {
6981 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 ) {
7187 LogPrintf (" (2)" );
88+ if (!secondLocked && firstLocked && i.second .fTry )
89+ onlyMaybeDeadlock = true ;
90+ secondLocked = true ;
91+ }
7292 LogPrintf (" %s\n " , i.second .ToString ());
7393 }
94+ firstLocked = false ;
95+ secondLocked = false ;
7496 LogPrintf (" Current lock order is:\n " );
7597 BOOST_FOREACH (const PAIRTYPE (void *, CLockLocation) & i, s1) {
76- if (i.first == mismatch.first )
98+ if (i.first == mismatch.first ) {
7799 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 ) {
79105 LogPrintf (" (2)" );
106+ if (!secondLocked && firstLocked && i.second .fTry )
107+ onlyMaybeDeadlock = true ;
108+ secondLocked = true ;
109+ }
80110 LogPrintf (" %s\n " , i.second .ToString ());
81111 }
112+ assert (onlyMaybeDeadlock);
82113}
83114
84115static 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)
101132 lockorders[p1] = (*lockstack);
102133
103134 std::pair<void *, void *> p2 = std::make_pair (c, i.first );
104- if (lockorders.count (p2)) {
135+ if (lockorders.count (p2))
105136 potential_deadlock_detected (p1, lockorders[p2], lockorders[p1]);
106- break ;
107- }
108137 }
109138 }
110139 dd_mutex.unlock ();
@@ -119,7 +148,7 @@ static void pop_lock()
119148
120149void EnterCritical (const char * pszName, const char * pszFile, int nLine, void * cs, bool fTry )
121150{
122- push_lock (cs, CLockLocation (pszName, pszFile, nLine), fTry );
151+ push_lock (cs, CLockLocation (pszName, pszFile, nLine, fTry ), fTry );
123152}
124153
125154void LeaveCritical ()
0 commit comments