Problems with ReadWriteLock

Hi, I’m trying to use the ReadWriteLock (v1.45) for a database interface. I read the description of ReadWriteLock a little too hastily and missed some of the last points about lock upgrades.

It would be nice if you could remove the functionality where “a thread already has a read lock and tries to obtain a write lock, it will succeed if there are no other readers”. Will it not then deadlock depending on the runtime situation, isn’t it better if it always deadlocks instead?

BR
Markus

That’s what it does, isn’t it?

Always deadlock or sometimes deadlock?

Not sure you’re using the term “deadlock” correctly then? Deadlock is when 2 threads/2 locks get blocked on each other and can never get freed.

Maybe I have misunderstood the interface, I just mean that a thread that gets a read lock and then later a write lock maybe escapes testing only to dead lock depending on the run time situation in the field.

I wonder if it’s maybe better for the thread to deadlock at once instead of being able to acquire the write lock so it can’t escape testing.

Sorry, don’t understand. It’s never better to deadlock. Deadlocking is always a fatal error, as those threads are permanently stuck.

Yes, deadlock is always fatal to the threads involved.

What I mean is that getting a writers lock when you’ve got a read lock, two situations may form:

  1. There is only 1 reader (the current thread), the juce code grants the writers lock

  2. There are other readers beside this thread => the juce code will wait for the writers lock (and dead lock as ther will never be 0 readers?)

  3. happens depending on the runtime situation and may ot show up during testing.

Does it work like this?

Like it says in the comments, if you try to get the write lock, it’ll wait until all readers and writers have released it first.

Sorry for being a bit obstinate here, but:

if it’s gonna wait for all readers and writers to release it first, it WILL wait forever (e.g. deadlock) won’t it since it has a readers lock itself that will never be released!!! Or will it auto-release the read lock then?

example1:

Thread1

enterRead()
enterWrite()
.
. // success
.

example2:

Thread1 Thread2

                                       enterRead

enterRead()

(there are now two readers)

enterWrite() // !!! Deadlock?

1 Like

surely your example answers itself here. Thread 1 will eventually let go of the read lock 'cos it’s done doing whatever it is it was doing. Thread 2 then gets the write lock and can do whatever it wants to do.

I think what you are trying to say is what happens if two threads both hold a read lock, and both of them try to upgrade to write locks. At that point neither can get a write lock because the other already has a read lock.

This isn’t a fault of the ReadWriteLock class though, it’s just a deliberately contrived error. If you know that it’s a risk that more than one thread may need to write, and you are doing lots of read verify operations before writing, either just get the write lock before doing anything, or call exitRead() before trying to get the write lock.

Ah… I see what you’re getting at now. Sorry if I was a bit slow there. Yes, there’s no magical fix for that situation, any more than there’s a magical fix for ordinary deadlock situations. It’s all just part of the fun of threaded programming…

No offense taken :slight_smile:

My point is that the acceptance of a write lock request when being the only current reader only hides the deadlock situation, such code is a programming error and can never work (when a read lock is held elsewhere)! That’s why I think the RW lock should not accept that situation but deadlock directly so that it can be intercepted in testing.

How could it be removed it without ruining the RW lock?

I don’t agree.

If I know that only one thread can ever be a writer, but many threads can be a reader, then there is no reason for me to release the read lock before trying to gain a write lock. Conversely, if I know that many threads might need to write, I need to plan for that accordingly.

The thread model should provide the tools to allow you to produce as efficient an implementation as possible. It’s up to you, on a case by case basis, to determine which tools are appropriate to your needs.

Why force the locking model to use the lowest common denominator approach (whatever that might be where threads are concerned)?