From: hipster Date: 2000-10-05T23:47:42+09:00 Subject: [ruby-talk:5309] Re: Proper ConditionVariable usage? On Thu, 05 Oct 2000 23:06:08 +0900, YANAGAWA Kazuhisa wrote: > In message <877l7o375b.wl@studly.netlab.co.jp> > shugo@ruby-lang.org writes: > > > > class YASizedQueue < YAQueue > > (snip) > > > def enq(obj) > > > @mutex.synchronize do > > > while @que.length >= @max > > > @full_cond.wait(@mutex) > > > end > > > super(obj) > > > end > > > end > > > > Sorry, Mutex is not re-entrant. (So this program cause dead-lock.) > > Please use Monitor instead of Mutex. > > NOTE: A problem above is a one of similar situations known as > ``inheritance anomaly'' --- embedded synchronization codes prevent > ``normal'' inheritance where one can use super class's code without > knowledge of its implementation. Even merely adding constraints may > need to reimplement other methods. Agreed. Not only do you inherit an interface, you also inherit (a) state (machine) that defines the interface's behaviour. This violates the encapsulation principle. To solve this we could refactor Queue and siblings: AbstractQueue - a generic queue w/o synchronisation stuff Queue - or `SynchronizedQueue', a synced queue SizedQueue - does _not_ inherit from Queue due to ``inheritance anomaly'' ... The synced variants are probably best made `final'. We should analyze this a bit deeper and maybe introduce some patterns. State, Strategy and Adapter come to mind. And another thing (which follows from the above): To acquire a clean, simple and understandable set of synchronisation primitives it would, IMO, be a Good Thing to implement all of them _only_ using the Thread.critical primitive (which Thread.exclusive nicely wraps). At the possible cost of some code duplication, decoupling is achieved. Easier to test, easier to maintain. - Michel