RE: Boost.Threads proposed change: lock constructors

Mike, With all due respect I am not sure that the additional complexity you are proposing is justified. It appears that the differences in lock and try_lock default constructors' behavior are consistent with other libraries and actually feel intuitive and natural to me. After all, it is reflected in what I do -- with lock I try until I succeed (that is [Batov, Vladimir] the lock blocks until succeeds), with try_lock I try once and may fail (that is it unconditionally falls through for me to check the result). Best, V. Date: Thu, 24 Jun 2004 14:14:02 -0400 From: Michael Glassford <glassfordm@hotmail.com> Subject: [boost] Boost.Threads proposed change: lock constructors To: boost@lists.boost.org Message-ID: <cbf5as$hvv$1@sea.gmane.org> Content-Type: text/plain; charset=us-ascii; format=flowed Below I detail proposed changes to the Boost.Threads lock class constructors. Comments? Questions? Mike ----------------------------------------------------------------- The Boost.Threads lock concept constructors are currently defined as follows: Definitions ----------- L: lock type l: lock variable (type L) m: mutex variable (appropriate Mutex type) s: initial lock state (type bool, true=locked, false=unlocked) Lock Concept ------------ L l(m,s) //Blocking lock if s L l(m) //Blocking lock TryLock Concept --------------- L l(m,s) //Blocking lock if s L l(m) //Non-blocking lock TimedLock Concept ----------------- L l(m,s) //Blocking lock if s L l(m,t) //Blocking lock, failing if not obtained by time t These definitions have the following drawbacks: 1) That one of the TryLock constructors blocks while the other doesn't is neither obvious nor very consistent. 2) That the single-parameter constructor of Lock blocks while the single-parameter constructor of TryLock doesn't is neither obvious nor very consistent. 3) Part of the reason for the above inconsistencies is that it's not clear whether the constructors of TryLock should block or not. 4) The TimedLock constructors have no way to request a non-blocking lock. To address these problems, I would like to redefine the lock concept constructors as follows (changes indicated with "^"): Definitions ----------- L: lock type l: lock variable (type L) m: mutex variable (appropriate Mutex type) s: initial lock state (enum type {NO_LOCK=0, LOCK=1}) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ b: block? (enum type blocking_state {NON_BLOCKING=0, BLOCKING=1}) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Lock Concept ------------ L l(m,s) //Blocking lock if s L l(m) //Blocking lock TryLock Concept --------------- L l(m,s,b) //Lock if s; blocking if b ^ ^^^^^^^^^^^^^ L l(m,b) //Lock; blocking if b ^ ^^^^^^^^^^^^^ TimedLock Concept ----------------- L l(m,s,b) //Lock if s; blocking if b ^ ^^^^^^^^^^^^^ L l(m,t) //Blocking lock, failing if not obtained by time t Note: s and b are defined as enums rather than bools to prevent existing code from breaking silently: e.g., if s and b were bools, "TryLock l(m, false)", which currently means "construct a lock object but don't obtain a lock", would change with the new definitions to mean "construct a lock and make a non-blocking attempt to obtain a lock". Also, enums are more explicit than bools. Note: these changes will cause some existing code to break by producing compile errors; the compile errors can be fixed by appropriately adding or changing parameters being passed to the changed TryLock and TimedLock constructors. Mike

Batov, Vladimir wrote:
Mike,
With all due respect I am not sure that the additional complexity you are proposing is justified. It appears that the differences in lock and try_lock default constructors' behavior are consistent with other libraries and actually feel intuitive and natural to me. After all, it is reflected in what I do -- with lock I try until I succeed (that is [Batov, Vladimir] the lock blocks until succeeds), with try_lock I try once and may fail (that is it unconditionally falls through for me to check the result).
Part of the point, though, is that try_lock doesn't actually work that way: one of the try_lock constructors does a non-blocking try_lock(), and the other does a blocking lock(). Without looking, do you always remember which one does which? I don't. Mike
participants (2)
-
Batov, Vladimir
-
Michael Glassford