mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
mutexdebugger
This commit is contained in:
parent
c0ee1ec9aa
commit
3598534982
@ -25,6 +25,7 @@ namespace mongo {
|
||||
extern bool __destroyingStatics;
|
||||
|
||||
class mutex;
|
||||
// only used on _DEBUG builds:
|
||||
class MutexDebugger {
|
||||
typedef const char * mid; // mid = mutex ID
|
||||
typedef map<mid,int> Preceeding;
|
||||
@ -34,15 +35,31 @@ namespace mongo {
|
||||
boost::mutex &x;
|
||||
unsigned magic;
|
||||
public:
|
||||
// set these to create an assert that
|
||||
// b must never be locked before a
|
||||
// so
|
||||
// a.lock(); b.lock(); is fine
|
||||
// b.lock(); alone is fine too
|
||||
// only checked on _DEBUG builds.
|
||||
string a,b;
|
||||
|
||||
void programEnding();
|
||||
MutexDebugger() : x( *(new boost::mutex()) ), magic(0x12345678) { }
|
||||
MutexDebugger();
|
||||
void entering(mid m) {
|
||||
if( magic != 0x12345678 ) return;
|
||||
|
||||
Preceeding *_preceeding = us.get();
|
||||
if( _preceeding == 0 )
|
||||
us.reset( _preceeding = new Preceeding() );
|
||||
Preceeding &preceeding = *_preceeding;
|
||||
|
||||
if( a == m ) {
|
||||
if( preceeding[b.c_str()] ) {
|
||||
cout << "mutex problem " << b << " was locked before " << a << endl;
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
preceeding[m]++;
|
||||
if( preceeding[m] > 1 ) {
|
||||
// recursive re-locking.
|
||||
@ -65,7 +82,8 @@ namespace mongo {
|
||||
mid bad = i->first;
|
||||
ss << "mutex problem" <<
|
||||
"\n when locking " << m <<
|
||||
"\n " << bad << " was already locked and should not be.\n";
|
||||
"\n " << bad << " was already locked and should not be."
|
||||
"\n set a and b above to debug.\n";
|
||||
stringstream q;
|
||||
for( Preceeding::iterator i = preceeding.begin(); i != preceeding.end(); i++ ) {
|
||||
if( i->first != m && i->first != bad && i->second > 0 )
|
||||
|
@ -25,6 +25,15 @@ namespace mongo {
|
||||
mutex _atomicMutex("_atomicMutex");
|
||||
MutexDebugger mutexDebugger;
|
||||
|
||||
MutexDebugger::MutexDebugger() :
|
||||
x( *(new boost::mutex()) ), magic(0x12345678) {
|
||||
// optional way to debug lock order
|
||||
/*
|
||||
a = "a_lock";
|
||||
b = "b_lock";
|
||||
*/
|
||||
}
|
||||
|
||||
void MutexDebugger::programEnding() {
|
||||
if( followers.size() ) {
|
||||
std::cout << followers.size() << " mutexes in program" << endl;
|
||||
|
Loading…
Reference in New Issue
Block a user