$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Howard Hinnant (hinnant_at_[hidden])
Date: 2004-07-21 20:19:15
On Jul 21, 2004, at 7:16 PM, Batov, Vladimir wrote:
> Howard,
>
> Thank you for taking on the task of shaping up the interface. That
> activity is of great importance. A few comments.
>
>     explicit scoped_lock(mutex_type& m);
>     scoped_lock(mutex_type& m, detail::defer_lock_type);
>     scoped_lock(mutex_type& m, detail::try_lock_type);
>     scoped_lock(mutex_type& m, const elapsed_time& elps_time);
>
> The problem (as I can see it) with the set above is that "deferred",
> "tried" and "timed" appear to be alternatives or mutually exclusive.
> However, "deferred" and, say, "try" functionalities are orthogonal. 
> That
> is, as one might need to defer a blocking lock
>
>     scoped_lock l(m, deferred);
>
> one might need a deferred try_lock as well. Therefore, as we are trying
> to provide one universal lock, it appears we have to have something
> complex like
>
>     basic_lock(mutex_type&, const elapsed_time&, defer_type);
>
> that would address all the lock variability/configurability.
I'm not seeing that the combination of time and defer always make sense:
time         defer           description
---------------------------------------------------
0             yes            interpret as don't lock
0             no             interpret as try-lock
finite        yes            no interpretation
finite        no             lock if you can get it in time
infinite      yes            no interpretation
infinite      no             interpret as lock
Some of the combinations don't appear to have clear meanings.
Even more importantly, the underlying mutex might not support time.  
Below is a list of mutex functionality that I have so far identified in 
the spec.  Recursion is ignored for this discussion (it isn't relevant 
to locks, and thus not relevant to mutex interface, only to mutex 
implementation details):
Mutex interface:
----------------
void lock();
void unlock();
bool try_lock();
bool timed_lock(const elapsed_time&);
void lock_sharable();
void unlock_sharable();
bool try_lock_sharable();
bool timed_lock_sharable(const elapsed_time&);
void lock_upgradable();
void unlock_upgradable();
bool try_lock_upgradable();
bool timed_lock_upgradable(const elapsed_time&);
void unlock_and_lock_sharable();
void unlock_and_lock_upgradable();
void unlock_upgradable_and_lock();
void try_unlock_upgradable_and_lock();
The spaces between signatures are relevant.  They represent groupings 
where I believe it is reasonable for a mutex to support a group of 
signatures, but exclude other groups.  For example, it is very 
reasonable for a mutex to support lock and unlock but not try_lock.  Or 
perhaps lock, unlock and try_lock, but not timed_lock.  If a lock 
constructor forces the semantics of "deferred lock" to call 
m_.timed_lock(elps_time), then a compile time error results if the 
mutex does not support timed_lock(), even though timed_lock isn't 
needed to support "deferred lock" (no mutex interface is required to 
support deferred lock).  So I'm very reluctant to have a lock function 
that calls two mutex functions that can reasonably be expected to not 
be implemented in the same mutex.
-Howard