8 #include <boost/foreach.hpp>
10 #ifdef DEBUG_LOCKCONTENTION
11 void PrintLockContention(
const char* pszName,
const char* pszFile,
int nLine)
13 printf(
"LOCKCONTENTION: %s\n", pszName);
14 printf(
"Locker: %s:%d\n", pszFile, nLine);
18 #ifdef DEBUG_LOCKORDER
32 CLockLocation(
const char* pszName,
const char* pszFile,
int nLine)
39 std::string ToString()
const
41 return mutexName+
" "+sourceFile+
":"+
itostr(sourceLine);
45 std::string mutexName;
46 std::string sourceFile;
50 typedef std::vector< std::pair<void*, CLockLocation> > LockStack;
52 static boost::mutex dd_mutex;
53 static std::map<std::pair<void*, void*>, LockStack> lockorders;
54 static boost::thread_specific_ptr<LockStack> lockstack;
57 static void potential_deadlock_detected(
const std::pair<void*, void*>& mismatch,
const LockStack& s1,
const LockStack& s2)
59 printf(
"POTENTIAL DEADLOCK DETECTED\n");
60 printf(
"Previous lock order was:\n");
61 BOOST_FOREACH(
const PAIRTYPE(
void*, CLockLocation)& i, s2)
63 if (i.first == mismatch.first)
printf(
" (1)");
64 if (i.first == mismatch.second)
printf(
" (2)");
65 printf(
" %s\n", i.second.ToString().c_str());
67 printf(
"Current lock order is:\n");
68 BOOST_FOREACH(
const PAIRTYPE(
void*, CLockLocation)& i, s1)
70 if (i.first == mismatch.first)
printf(
" (1)");
71 if (i.first == mismatch.second)
printf(
" (2)");
72 printf(
" %s\n", i.second.ToString().c_str());
76 static void push_lock(
void* c,
const CLockLocation& locklocation,
bool fTry)
78 if (lockstack.get() == NULL)
79 lockstack.reset(
new LockStack);
81 if (
fDebug)
printf(
"Locking: %s\n", locklocation.ToString().c_str());
84 (*lockstack).push_back(std::make_pair(c, locklocation));
87 BOOST_FOREACH(
const PAIRTYPE(
void*, CLockLocation)& i, (*lockstack)) {
88 if (i.first == c)
break;
90 std::pair<void*, void*> p1 = std::make_pair(i.first, c);
91 if (lockorders.count(p1))
93 lockorders[p1] = (*lockstack);
95 std::pair<void*, void*> p2 = std::make_pair(c, i.first);
96 if (lockorders.count(p2))
98 potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
106 static void pop_lock()
110 const CLockLocation& locklocation = (*lockstack).rbegin()->second;
111 printf(
"Unlocked: %s\n", locklocation.ToString().c_str());
114 (*lockstack).pop_back();
118 void EnterCritical(
const char* pszName,
const char* pszFile,
int nLine,
void* cs,
bool fTry)
120 push_lock(cs, CLockLocation(pszName, pszFile, nLine), fTry);
std::string itostr(int n)