Ok, this is some late night brainstorming using mutexes and a seperate monitoring thread:
Lets say that you've go two maps, one called 'waiting for' (DWORD ThreadId, HANDLE hMutex, BOOL bDeadlock), and one called 'holding' (DWORD ThreadId, HANDLE hMutex).
And then some code like this:
Code:
CRITICAL_SECTION global_cs; // accessed only by lock & unlock & scanthreadfunc
void lock(HANDLE hMutex)
{
EnterCriticalSection(global_cs);
// add 'this' thread and hMutex to "waiting for" map
//...
// code here
//...
LeaveCriticalSection(global_cs);
DWORD dwRet;
do
{
// wait for the mutex
dwRet = MsgWaitForSingleObjectEx(1, &hMutex, INFINITE, QS_POSTMESSAGE, 0)
if (dwRet == WAIT_OBJECT_0 + 1)
{
// something woke us up, see if we're in a deadlock situation
// and do something about it
}
} while (dwRet != WAIT_OBJECT_0);
// We hold the lock on the mutex
EnterCriticalSection(global_cs);
// remove 'this' thread and hMutex from the "waiting for" map
// and add 'this' thread and hMutex to the "holding" map
//...
// code here
//...
LeaveCriticalSection(global_cs);
}
void unlock(HANDLE hMutex)
{
EnterCriticalSection(global_cs);
ReleaseMutex(hMutex);
// remove 'this' thread and hMutex from the "holding" map
//...
// code here
//...
LeaveCriticalSection(global_cs);
}
// a thread proc running constantly
void scanthreadfunc(void*)
{
while (true)
{
// sleep for some while
EnterCriticalSection(global_cs);
// Scan "waiting for" & "holding" maps to see if there is a thread 'A' that's waiting for a mutex that's
// locked by a thread 'B' which in turn is waiting for a mutex that is locked by thread 'A'....
// This is a 'recursive' search, there might be a list of threads between 'A' and 'B'.
// If such a situation is found raise a flag (relative to the threads and threir mutexes) in the "waiting for" map
// and post a message to the "deadlocked" threads using PostThreadMessage(...), just to wake them up...
LeaveCriticalSection(global_cs);
}
}
Ok, where would that leave us?
- petter