After going through this question with the same title and its answers, I thought to try something that should really work only using critical section and thus should be much faster that existing solutions (which use other kernel objects too like mutex or semaphore)
Here are my Read/Write lock/unlock functions:
#include <windows.h>
typedef struct _RW_LOCK
{
CRITICAL_SECTION readerCountLock;
CRITICAL_SECTION writerLock;
int readerCount;
} RW_LOCK, *PRW_LOCK;
void InitLock(PRW_LOCK rwlock)
{
InitializeCriticalSection(&rwlock->readerCountLock);
InitializeCriticalSection(&rwlock->writerLock);
}
void ReadLock(PRW_LOCK rwlock)
{
EnterCriticalSection(&rwlock->readerCountLock); // In deadlock 1 thread waits here (see description below)
if (++rwlock->readerCount == 1)
{
EnterCriticalSection(&rwlock->writerLock); // In deadlock 1 thread waits here
}
LeaveCriticalSection(&rwlock->readerCountLock);
}
void ReadUnlock(PRW_LOCK rwlock)
{
EnterCriticalSection(&rwlock->readerCountLock);
if (--rwlock->readerCount == 0)
{
LeaveCriticalSection(&rwlock->writerLock);
}
LeaveCriticalSection(&rwlock->readerCountLock);
}
int WriteLock(PRW_LOCK rwlock)
{
EnterCriticalSection(&rwlock->writerLock); // In deadlock 3 threads wait here
}
void WriteUnlock(PRW_LOCK rwlock)
{
LeaveCriticalSection(&rwlock->writerLock);
}
And here is a thread function. After calling InitLock (&g_rwLock);
from main
I created FIVE threads to try these locks.
void thread_function()
{
static int value = 0;
RW_LOCK g_rwLock;
while(1)
{
ReadLock(&g_rwlLock);
BOOL bIsValueOdd = value % 2;
ReadUnlock(&g_rwlLock);
WriteLock(&g_rwlLock);
value ++;
WriteUnlock(&g_rwlLock);
}
}
Ideally this code should keep running forever without any trouble. But to my disappointment, it doesn't run always. Some times it lands up in deadlock. I compiled this and ran it on Windows XP. To create threads using threadpool, I am using third party library. Hence cannot give here all that code which involves lots of initializing routines and other stuff.
But to cut the story short, I like to know if anyone by looking at the code above can point out what is wrong with this approach?
I've commented in the code above where each thread (out of FIVE threads) keeps waiting when deadlock happens. (I found it out by attaching debugger to the deadlocked process)
Any inputs/suggestions would be really great as I've stuck over this for quite some time now (In the greed of making my code run faster than ever).