Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2004-07-22 11:10:51


On Jul 22, 2004, at 9:41 AM, Michael Glassford wrote:

>> I agree 100%, though I've spelled deferred_t as defer_lock_type and
>> added try_lock_type. Thanks. You can now:
>> scoped_lock lk1(m, defer_lock); // not locked
>> scoped_lock lk2(m, try_lock); // tries to lock
>
> If you remember, I proposed something along these lines (at the
> suggestion of Vladimir, IIRC) and liked it a lot, but changed my mind
> when it was pointed out that it prevents making the choice at run time
> whether the lock should be locked or not. With movable locks, as you
> point out below, this is changed somewhat.

Sorry, my acknowledgment list has gotten so confused I didn't even
attempt one in the latest spec. The thread has gotten so long I'm
forgetting who's proposed what, and have not taken the time to read
back and check.

>> I've gone with:
>> mutex_type* mutex() const;
>> I don't have very strong feelings on this one, except that the
>> current boost design does not hide the mutex interface as we thought
>> it should. You just get to the mutex interface via the lock instead
>> of directly. So I'm not that anxious to make it difficult to access
>> the mutex and operate on it directly. Sometimes there's good reason
>> to do that.
>
> What can you do to a mutex except lock it with a lock object?

My comments were based on the fact that currently the mutex interface
is private except for construction and destruction. This is meant to
encourage the programmer to use the mutex only in an orderly (RAII)
fashion.

<soapbox>
However we do not currently prohibit code such as the following:

typedef mutex::scoped_lock MyMutex;
mutex m;
MyMutex my_mut(m, false);

void foo()
{
     my_mut.lock();
}

void bar()
{
     my_mut.unlock();
}

int main()
{
     foo();
     bar();
}

I.e. It is not difficult to make a lock look exactly like a mutex with
public member functions, and then use it in whatever way (orderly or
not) you want to. Given that, perhaps it is better to just make the
mutex interface public in the first place, and expose the mutex of a
lock. Afterall, there are legitimate uses for locking and unlocking a
mutex in a non-RAII pattern, and there are legitimate uses for needing
access to a lock's mutex. The tools should not get in the way of the
coder in the name of trying to save the coder from his own stupidity.
Otoh, a good tool will make it easy to avoid stupid mistakes and write
correct, efficient and elegant code. It is always a delicate line to
walk when designing an interface.
</soapbox>

> Another possibility is to name the second parameter as an adjective
> describing the initial state of the lock instead of a verb:
>
> scoped_lock l(m, unlocked);

scoped_lock l(m, tried); // ?
scoped_lock l(m, Heisenberg); // ? :-)

Imho we need to consider both constructors (defer_lock / try_lock)
together for consistency's sake (unless, as Peter suggests, we do not
want the try-ctor at all).

-Howard


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk