Boost logo

Boost :

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


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