Note deadlock prevention:
(1) Before writing a multithreaded program, first write correct programs and then transplanted to a multi-threaded
(2) the time to write their own inspection procedures have not forgotten when out of the lock is released
(3) if own modules may reuse a lock, we recommend using a nested lock
(4) for some lock the code, do not re-write temporary, it is recommended to use the library inside the lock, or locked themselves had written
(5) If a business needs to obtain multiple locks, the lock must be guaranteed access to some order, otherwise surely deadlock
(6) write a simple test to verify there is no deadlock
(7) programming verification deadlock, from the source to avoid deadlock
First, define the basic data structures and macros,
typedef struct _LOCK_INFO
{
char lockName[32];
HANDLE hLock;
}LOCK_INFO:
typedef struct _THREAD_LOCK
{
int threadId;
LOCK_INFO* pLockInfo[32];
}THREAD_LOCK;
#define CRITICAL_SECTION_TYPE 1
#define MUTEX_LOCK_TYPE 2
#define SEMAPHORE_LOCK_TYPE 3
#define NORMAL_LOCK_TYPE 4
#define WaitForSingleObject(a, b) \
WaitForSingleObject_stub((void*)a, NORMAL_LOCK_TYPE)
#define EnterCriticalSection(a) \
WaitForSingleObject_stub((void*)a, CRITICAL_SECTION_TYPE)
#define ReleaseMutex(a) \
ReleaseLock_stub((void*)a, MUTEX_LOCK_TYPE))
#define ReleaseSemaphore(a, b, c) \
ReleaseLock_stub((void*)a, SEMAPHORE_LOCK_TYPE))
#define LeaveCriticalSection(a) \
ReleaseLock_stub((void*)a, CRITICAL_SECTION_TYPE))
Then, rewrite the application lock function,
void WaitForSingleObject_stub(void* hLock, int type)
{
/* step 1 */
WaitForSingleObject(hDbgLock);
/* check if lock loops arounds threads */
ReleaseMutex(hDbgLock);
/* step 2 */
if(NORMAL_LOCK_TYPE == type)
WaitForSingleObject((HANDLE)hLock, INFINITE);
else if(CRITICAL_SECTION_TYPE == type)
EnterCriticalSection((LPCRITICAL_SECTION)hLock);
else
assert(0);
/* step 3 */
WaitForSingleObject(hDbgLock);
/* add lock to specified threadid list */
ReleaseMutex(hDbgLock);
}
Finally, the need to rewrite the function to release the lock.
void ReleaseLock_stub(void* hLock, int type)
{
/* step 1 */
WaitForSingleObject(hDbgLock);
/* remove lock from specified threadid list */
ReleaseMutex(hDbgLock);
/* step 2 */
if(MUTEX_LOCK_TYPE))== type)
ReleaseMutex(HANDLE)hLock);
else if(SEMAPHORE_LOCK_TYPE == type)
ReleaseSemaphore((HANDLE)hLock, 1, NULL);
else if(CRITICAL_SECTION_TYPE == type)
LeaveCriticalSection((LPCRITICAL_SECTION)hLock);
assert(0);
}