|
Boost : |
From: Peter Dimov (pdimov_at_[hidden])
Date: 2004-07-12 10:28:23
Howard Hinnant wrote:
> On Jul 11, 2004, at 8:46 AM, Peter Dimov wrote:
[...]
>> Mutex * mutex() const;
>> // returns: the associated mutex;
>
> Why return a pointer instead of a reference? What about this instead?
>
> Mutex& mutex();
> const Mutex& mutex() const;
Because of the use case shown below:
>> void f( scoped_lock & lock )
>> {
>> // check for lock validity
>> assert( lock.locked() && lock.mutex() == &my_mutex );
>>
>> // proceed with operation
>> }
A pointer makes it clear that it is the identity of the associated mutex
that is being queried. A (const-"correct") reference return implies that the
purpose of the accessor is to return, well, a reference to the mutex object,
presumably so that the client can do something with it.
> That would put to rest any questions about mutex() transferring mutex
> ownership, e.g.:
>
> delete lock.mutex();
I considered
bool is_associated_with( Mutex const & m ) const;
but that's a bit too much of a handholding for my taste, and doesn't allow
us to use mutex() in the Effects clauses. The kind of a person that would
delete lock.mutex() would never get a multithreaded program correct anyway.
>> Now that we got rid of the excess locks, how about doing the same
>> with the mutexes?
>
> That worries me a lot. We need several different flavors of mutex
> because the more functionality you put into a mutex, the more expensive
> it is both in terms of size and speed. Why pay for a recursive mutex
> if you don't need one? Why pay for a timed mutex? But when you need
> one of these more expensive types, then the price is worth it.
First, please note that I never said anything about mutex being recursive
(and the specification says that relocking is undefined behavior). A
recursive mutex is a separate entity (and its specification is slightly
different).
That aside. It is precisely the assertion that (1) a try_mutex is more
expensive than a mutex, and (2) that a timed_mutex is more expensive than a
try_mutex, that I am challenging. I see no evidence for (1). (2) is more
interesting. You will note that POSIX indeed makes you explicitly state
whether you want a recursive mutex or not - because recursive mutexes are
more expensive. However no such requirement exists for "timed mutexes".
Either all mutexes are timed, or they are not. This, for me, indicates that
a timed mutex is not more expensive than a try mutex, just that
pthread_mutex_timedlock is a late addition to the standard.
Do you have data on whether your platforms support pthread_mutex_timedlock?
> I can't speak for the boost implementation (haven't carefully studied
> it), but the Metrowerks implementation also supports conditions
> operating on a recursive mutex.
Interesting. I presume that this was a deliberate design decision. There is
a school of thought that says that a recursive mutex can only be used to
sweep bugs under the carpet and is never needed in a correctly designed
multithreaded program, which probably applies doubly to conditions operating
on a recursive mutex locked more than once. But I'm not qualified to judge.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk