$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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):
ScopedLock
----------
     lock(m)
     lock(m, unlocked)
-   lock(m, locked)
-   lock(m, locked, blocking)
-   lock(m, blocking)
ScopedTryLock
-------------
-   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)
ScopedTimedLock
---------------
-   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);
Mike