Link to home
Start Free TrialLog in
Avatar of yoffe
yoffe

asked on

Read/Write lock

I have a large piece of code that is blowing up on a SMP machine.   The suspect is a class was one written by me over a year ago.  

Its purpose was to provide a ReadLock()/ReadUnlock() method locking a resource non-exclusively and a WriteLock()/WriteUnlock() for an exclusive lock.

After reviewing it, I think that it was poorly implemented to start with.   So, I would like to create another less complicated but complete class to drop in its place.

The API of the class must include:

ReadLock()
ReadUnlock()
WriteLock()
WriteUnlock()

-alternatively-
Lock(BOOL bReadOnly)
Unlock(BOOL bReadOnly)


This is the behavior that I expect.

1.   Multiple threads should be able to obtain a ReadLock as long as there is no WriteLock by another thread.

2.   WriteLock and ReadLock are blocking (until lock obtained).   If WriteLock is called, it will get the WriteLock after ALL ReadLock threads release their ReadLocks.   During that time, no other thread may obtain a ReadLock.

2.   Recursed locking should be supported.  

Ex a.   A thread calls WriteLock several times.   Then it calls another function that calls ReadLock.   Because this class already has a WriteLock, the read lock should succeed.

Ex b.   A thread calls ReadLock (perhaps several times) and then calls WriteLock.   This is an exception case - not supported.

Ex c.   A thread gets a ReadLock.   Now another thread gets a WriteLock.   Now the original thread requests a ReadLock.   It IS granted a ReadLock so that deadlock is avoid.   To generalize, any thread that has a ReadLock is granted a readlock.

Let me know if I have left anything out.
If need be, I can post my code.   Knowing now what I didnt know then, I am a bit embarassed to post this code based to the MFC-SDK mixture - absolutely NO consistancy.

Thanks
Yoffe
Avatar of yoffe
yoffe

ASKER

Adjusted points from 200 to 400
Well I have been doing lots of multithreading programming. Please send me the code at
avinash_sahay@hotmail.com
What are your target platforms?

For robust, multi threaded locking schemes you need to use some primitive provided by the operating system.
Avatar of yoffe

ASKER

NT/98.   In this case, you can expect many readers to maintain locks of up to 4-5 seconds.   There is 1 reader thread that rarely needs Lock, but when it does, the readers must wait to get a read lock.
Avatar of yoffe

ASKER

Typo:

There is 1 writer thread that rarely needs Lock, but when it does, the readers must wait to get a read lock.
Win32 (and MFC) already provide classes for synchronisation.

Use one of these.



For example, you can use a CEvent to indicate that you are writing.  Readers would then wait until the writer sets the event to say that the resource is ready.

Check out the docs on these.
Avatar of yoffe

ASKER

I am familiar with all the MFC sync wrappers.   The solution of using merely a CEvent does not solve the problem.

Ex.

A writer is using a resource.   Upon completion, the writer sets an event (say manual reset), which 1+ reader threads are waiting on.    At this point the writer thread possibly waits for console IO.   The reader begin using the resource, and they check the event periodically.   The writer needs to update the resource, so it resets the event.   At this point, how can the writer know if all readers have released the resource?    

For arguments sake, we will keep a counter of how many readers have are looking at the resource (Crit Sec protected, or interlockInc/Dec).  Sounds good.  Unfortunately Rule 2 (the second 2 from my original question - great math skills I have) 2.a/b/c are all not supported.    So, I dont think that the simple win32 wrapper classes that MFC provides brings me any closes to solving the problem that I am having.

Feel free to correct me or enlighten me on the issue if I am just flat out wrong in my assertions (MFC humor).

Thanks,
Brian
Avatar of yoffe

ASKER

My original class used the MFC Classes (several of them in conjunction) to solve the problem.   I think the question I am asking is a bit more complex - look at it again.   Or maybe I am making a mountain out of a molehill.
ASKER CERTIFIED SOLUTION
Avatar of stefanr
stefanr

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of yoffe

ASKER

Stefan,

Thanks for the reply.
I looked over your implementation.   I was not able to substitute it directly for my class, but it did help me to determine what my problem was.   I was using a CMutex in my class instead of a CCriticalSection.   It turns out that CMutex does not support recursed locking.   CCriticalSection does.   I substututed CCriticalSection in for CMutex in my code and it made all my problems disappear.   My implementation is VERY heavy compared to yours, but it does allow locking in a call chain.   It does NOT upgrade read locks to write locks - this is an exception case.   If you are interested, let me know.
Avatar of yoffe

ASKER

Comment accepted as answer