
Matt Hurd wrote: [snip other stuff]
#2: instead of the following, which in my mind leaves an ambiguity of whether the mutex should be unlocked, shared-locked, or exclusive-locked at the end:
shared_lock l1(shared_mutex, SHARED_LOCK); ... { exclusive_lock l2 = l1.promote(); ... }
It is possible to write this, which removes the ambiguity:
lock l = shared_mutex.shared_lock(); ... l = shared_mutex.promote(l.transfer()); ...
Comments?
Mike
Bad example I think. Personally, the risk of dead lock from trying to promote shared to an exclusive lock strikes me as goto-esque. I really struggle to find a compelling use case that makes the danger involved worthwhile. I recall suggesting that if the dangerous efficiency was really required it should be through a special promotable shareable mutex rather than the normal shareable one.
If I read this correctly, it's an objection to the idea of promotion in general (except for the special case of a promoteable shared lock), in which case I tend to agree; however, I want to specify the syntax that promotion would use even if the Boost.Threads shared_mutex ends up not using it, because I want to allow custom shared_mutex classes that do use it to be used with Boost.Threads lock classes (better support for custom classes being used with Boost.Threads classes is something I plan to cover in a later posting).
I agree with your push to clean up the lock constructor interface. I currently wrap them all and use my own interface so I can have generic code for null, exclusive and shared ops.
Not sure about the lock transfer object as it is really just another name for a lock. After all it is the token representing the locked state, or a lock by another name... Perhaps just being able to return a lock from a mutex and being able to transfer ownership by copying a lock like an auto ptr would give you the same thing. I need to think about this some more.
Except that lock objects can only be transferred explicitly by calling their transfer() method and have public constructors, while lock_transfer objects transfer implicitly and can only be constructed by mutex and lock objects. You can't tell this from what I posted, however.
Importantly, I believe you need to be able to request a share lock even of an exclusive mutex or null mutex so that you can write generic concurrent code. You write to a shared model and the other models work.
I was intending to have better support for generic code, though I planned to cover that in a later posting. What happens when you request a shared lock from a non-shared mutex? It just gives you an exclusive lock? [snip code] Mike