|
Boost : |
From: Howard Hinnant (hinnant_at_[hidden])
Date: 2006-10-09 11:22:01
On Oct 8, 2006, at 5:29 AM, Anthony Williams wrote:
>> 3) I don't like the lock(), unlock() etc member functions being
>> public.. forcing scoped_lock is a great cheap idiom for exception
>> safety and saving people from deadlocks. Even with scoped_lock also
>> available - it isn't something found in other languages so I fear new
>> developers will flock to using the simpler and more familiar public
>> members instead.
>
> Howard's proposal has them as public members, so that's what I
> implemented.
>
> I can see the arguments both ways. Making the functions private is
> easy, and what boost does already.
>
> There are certainly use cases where pure scoped locks get in the way.
The motivation for making them public in N2094 is that to support
those use cases where scoped locking is not the desired behavior.
Simply saying that if you want to lock/unlock a mutex in a non-scope
pattern then install it in a lock, essentially confuses what a lock is.
condition is an example application that needs to lock/unlock a mutex
in a non-scoped pattern. boost solves this problem by making
condition a friend of the mutex (if I recall correctly). Can it
really be true that condition is the only application in need of this
service?
Don't get me wrong, scoped_lock is great. It is not only the safest
way to use a mutex, it is also the easiest. And for most use cases
it is exactly what is needed. It is just that scoped_lock isn't the
only way to use a mutex.
Here are some of the features enabled in N2094 by making mutex::lock/
unlock public:
* Clients can write their own mutex types which conform to this concept.
* condition can be made to work with any lock *or mutex* which
conforms (including client written mutexes). I.e. condition<Mutex>.
* Code which is generic in its mutex can be written. Examples
include mutex adaptors that turn one type of mutex into another
(recursive_mutex_adaptor<Mutex>). Here's another one that makes the
"read lock" interface of a read/write mutex look like lock/unlock:
template <class Mutex>
class sharable_adaptor
{
private:
Mutex& mut_;
public:
explicit sharable_adaptor(Mutex& mut) : mut_(mut) {}
void lock() {mut_.lock_sharable();}
bool try_lock() {return mut_.try_lock_sharable();}
void unlock() {mut_.unlock_sharable();}
};
Now you can use condition variables with a read-locked mutex.
--- If safety is easy, it will be used most of the time. If safety is mandated, programmers will be forced into expensive or excessively dangerous workarounds for unanticipated use cases. -Howard
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk