Boost logo

Boost :

From: Michael Glassford (glassfordm_at_[hidden])
Date: 2004-07-22 15:03:41

Howard Hinnant wrote:
> 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'm not worried about that; I've forgotten who said what myself. I just
wondered if you remembered that it had come up before. For what it's
worth, I believe my final proposal looked as follows (the items marked
"-" are possible constructors that I intentionally rejected):

     lock(m, unlocked)

- lock(m, locked)
- lock(m, locked, blocking)
- lock(m, blocking)

- try_lock(m) //locked, blocking
     try_lock(m, unlocked)
     try_lock(m, blocking)
     try_lock(m, non_blocking)

- try_lock(m, locked, blocking)
- try_lock(m, locked, non_blocking)

- timed_lock(m) //locked, blocking
     timed_lock(m, unlocked)
     timed_lock(m, blocking)
     timed_lock(m, non_blocking)
     timed_lock(m, t)

- timed_lock(m, locked, blocking)
- timed_lock(m, locked, non_blocking)
- timed_lock(m, t, locked)
- timed_lock(m, t, locked, blocking)
- timed_lock(m, t, blocking)

>>> 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();
> }

No, but the lock still unlocks when it goes out of scope and the mutex
doesn't, which is some difference.

Do you know of a way to prohibit such code?

> 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,

I don't agree.

> 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); // ? :-)

scoped_lock l(m, non_blocking);


Boost list run by bdawes at, gregod at, cpdaniel at, john at