
Michael Glassford
Matt Hurd wrote:
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),
Yep, promotion is generally poor practice in my book as you have to try hard if you don't want to deadlock or end up with a false economy. Having a special mutex/lock that supports it is my preferred option for keeping it away from normal behaviour. "It's over there in the closet if you really insist..." ;-)
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).
It still not clear to me how the lock transfers operate under simultaneous requests. What does the transfer object buy you over: That is, why l = m.promote(l.transfer()); l = m.promote(l); By the way I think the l is a bad name to use in examples as it is hard to see 1 l for I. lk might be better short hand.
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.
Should locks really be transferable or should shared_ptr< lock > be the idiom if you want to go beyond scoping?
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?
Yes. It works just dandy as the precondition is weaker and the post condition is stronger. In a similar vein, shared and exclusive do nothing on the null mutex. Write to a shared model and get non-concurrent and exclusive model behaviour also. This is only possible if you write to a shared model as there is no real way to write from a simpler model and have sharing introduced automagically. As an aside, I guess writing to a promotable shareable model would like wise be substitutable back if the promotion always fails (shareable model) or always succeeds (exclusive model). This gives you a substitutable taxonomy of null->exclusive->shareable->promotable. Write the appropriate model and the "lesser" models work making architectural components much more flexible. Similar thing to what ACE has been doing for over a decade... Regards, Matt.