
On Fri, 9 Jul 2004 19:33:39 -0400, Howard Hinnant <hinnant@twcny.rr.com> wrote:
So that's two votes for scary. I'm still undecided if it is "too scary". I.e. will documentation make upgradable_read_lock sufficiently safe? I'm hoping so, because there seems to be a vocal need for that functionality, and I don't see a good alternative at the moment.
Three. Too scary.
A good rule of thumb for using rw_mutex seems to be that you should never hold more than one lock on it in the same thread. Now that I write that though, I'm wondering if holding a recursive read_lock might be safe enough.... haven't looked into yet. But holding a read_lock and an upgradable_read_lock in the same thread is definitely ill-advised, even if only for an instant.
I think a base level shareable mutex (rw_mutex) should not have an upgrade from shared to exclusive. An upgradeable one is perhaps another mutex... but I can't see how one is possible without allowing for a failure/retry on contention of the upgrade. To stop the deadlock an optimization would be if I can get the exclusive 'cause I'm the only one sharing then keep going otherwise release my shared lock and block for a write. That is, you get away with just knowing (atomicly) there was only one reader, yourself, then upgrade to a write otherwise you must release your shared and wait for exclusive otherwise you will allow a deadlock. This will break the atomicity of the op which breaks the paradigm. You'd have to redo your state or fail.
At great extra expense one could put a runtime check into rw_mutex for one thread owning both a read_mutex and an upgradable_read_mutex. It would require storing a vector<thread_id> for every thread sharing read ownership. That would probably make the rw_mutex so expensive as to be useless though.
The more I think about the original use case I'm not sure I follow.
From memory the use case was reading stuff and then if that said I needed to write something, write it by upgrading the lock.
However, you are not going to be able to escape the deadlock in this case _ever_. AFAICT was if two things read concurrently and need to change state, the both can't if the states are dependent and thus you always have a deadlock. If they can, then the reading is independent of the writing and you should use different locks, otherwise you need to use an exclusive lock from the outset. I think the upgradeable readlock is a red herring... Regards, Matt Hurd.