Hi,

At Wed, 4 Oct 2000 21:24:28 +0900,
kjana / os.xaxon.ne.jp (YANAGAWA Kazuhisa) wrote:
> > Apperently CV::wait should use mutex.synchronize instead of exclusive
> > unlock.
> 
> That's because ConditionVariable is NOT for general synchronization,
> but condition variables in a monitor like context.
> ConditionVariable#wait(mutex) means ``wait on a condition represented
> by ConditionVariable, releasing lock for other threads do their job in
> a critical region the waiting thread was held and the condition is
> met.

Here is a simple example.

class YAQueue
  def initialize
    @que = []
    @mutex = Mutex.new
    @empty_cond = ConditionVariable.new
  end

  def enq(obj)
    @mutex.synchronize do
      @que.push(obj)
      @empty_cond.signal
    end
  end

  def deq
    @mutex.synchronize do
      while @que.empty?
        @empty_cond.wait(@mutex)
      end
      return @que.shift
    end
  end
end

YAQueue implements a yet another Queue class using ConditionVariable.

You can wait multiple conditions for one mutex.

class YASizedQueue < YAQueue
  attr :max
  
  def initialize(max)
    @max = max
    @full_cond = ConditionVariable.new
    super()
  end

  def enq(obj)
    @mutex.synchronize do
      while @que.length >= @max
        @full_cond.wait(@mutex)
      end
      super(obj)
    end
  end

  def deq
    @mutex.synchronize do
      obj = super
      if @que.length < @max
        @full_cond.signal
      end
      return obj
    end
  end
  
  def max=(max)
    @mutex.synchronize do
      @max = max
      @full_cond.broadcast
    end
  end
end

Shugo