|
Boost : |
From: Michael Glassford (glassfordm_at_[hidden])
Date: 2004-07-07 09:31:42
Peter Dimov wrote:
> Michael Glassford wrote:
>
>>Peter Dimov wrote:
>>
>>>Howard Hinnant wrote:
>>>
>>>[ read/write mutexes and locks ]
>>>
>>>Seems very good to me. Also demonstrates a better lock taxonomy
>>
>>Better compared to what? The current read/write lock taxonomy? One of
>>the many suggestions in this discussion?
>
>
> Better compared to the current non-read-write lock taxonomy.
>
>
>>>Lock
>>>
>>> Lock( Mutex&, bool = true );
>>> void lock();
>>> void unlock();
>>> bool locked() const;
>>> operator int bool_type::* () const;
>>>
>>>TryLock: Lock
>>>
>>> +bool try_lock();
>>>
>>>TimedLock: TryLock
>>>
>>> +bool timed_lock( xtime const & );
>>
>>The point being that TryLock is a refinement of Lock, and TimedLock
>>is a refinement of TryLock? If so, I agree that's better than TryLock
>>and TimedLock both refining Lock. There are still the constructor
>>issues to deal with in such a lock taxonomy, however.
>
>
> I don't see any. There is one constructor, with the same behavior.
OK. I hadn't realized that you meant there to be literally only one
constructor; I do now.
>>The main one: how do you
>>define destructors that are consistent within a lock concept and also
>>consistent between concepts.
>
>
> ~Lock { if( locked() ) unlock(); }
>
> however it looks like you meant 'constructor'.
Sorry, I did mean constructor.
>>E.g., on the one hand it seems that a
>>one-parameter constructor should do the same thing in all lock
>>types--so
>>it would have to block; on the other hand, it seems that TryLock
>>constructors should not block unless instructed to do otherwise.
>
>
> I meant what I said. There is a single constructor. Its behavior is
> consistent across all lock concepts (it it weren't, a TryLock would not be a
> Lock). A mutex exposes a single lock type, which is as refined as possible.
OK, that makes sense and is consistent (which I like). What about the
following as an alternative? I retain the hierarchy (a TryLock is a
Lock, a TimedLock is a TryLock) and resolve the conflict (of consistency
within a concept and consistency across concepts) by the principle that
a constructor always blocks unless you specifically tell it not to:
Definitions
-----------
M: appropriate mutex type
namespace lock_state {
typedef enum
{
unlocked=0,
locked=1
} lock_state;
} //namespace lock_state
namespace read_write_lock_state {
typedef enum
{
unlocked=0,
read_locked=1,
write_locked=2
} read_write_lock_state;
} //namespace read_write_lock_state
namespace blocking_mode {
typedef enum
{
non_blocking=0,
blocking=1
} blocking_mode;
} //namespace blocking_mode
ScopedLock / ScopedReadLock / ScopedWriteLock
---------------------------------------------
lock(M) //always locking, blocking
lock(M, lock_state) //blocking
ScopedTryLock / ScopedTryReadLock / ScopedTryWriteLock
------------------------------------------------------
try_lock(M) //always locking, BLOCKING
try_lock(M, lock_state) //BLOCKING
try_lock(M, lock_state, blocking_mode)
try_lock(M, blocking_mode) //always locking
ScopedTimedLock / ScopedTimedReadLock / ScopedTimedWriteLock
------------------------------------------------------------
timed_lock(M) //always locking, blocking
timed_lock(M, lock_state) //blocking
timed_lock(M, lock_state, blocking_mode)
timed_lock(M, blocking_mode) //always locking
timed_lock(M, t) //always locking, blocking for time t
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk