Hello all,

I recently made an "improvement" to a little piece of code...
and it quit working. (I call that "rebugging." Yeah, YOU'VE
never done it. Right...)

I really thought this code was correct... I was implementing
a protected queue for a simple producer-consumer problem.
(Yes, I know about the existing one. This was an exercise.)
I used a mutex and a pair of condition variables. At least,
that's what I meant to do.

Everything works fine in the code as shown. I even added a
little extra delay to the consumer so the queue would get 
"fuller" -- that worked fine.

But when I replace the lock/unlock sequences with a block
passed to mutex.synchronize, it doesn't work anymore!

What have I done wrong?

Thanks much,
Hal Fulton

===========================
require "thread"

class ProtectedBuffer

  def initialize(n)
    @max = n
    @buff = []
    @mutex = Mutex.new
    @notFull = ConditionVariable.new
    @notEmpty = ConditionVariable.new
  end

  def enqueue x
    @mutex.lock
    while self.full? do
      @notFull.wait(@mutex)
    end
    @buff.push x
    @notEmpty.signal
    @mutex.unlock
  end

  def dequeue
    @mutex.lock
    while self.empty? do
      @notEmpty.wait(@mutex)
    end
    x = @buff.shift
    @notFull.signal
    @mutex.unlock
    return x
  end

  def empty?
    @buff.size == 0
  end

  def full?
    @buff.size == @max
  end

  def size
    @buff.size
  end

end


# Main...


buffer = ProtectedBuffer.new(10)


producer = Thread.new do
  item = 0
  loop do
    sleep rand 0
    puts "Producer makes #{item}"
    buffer.enqueue item
    item += 1
  end
end

consumer = Thread.new do
  loop do
    sleep (rand 0)+0.3
    item = buffer.dequeue
    puts "Consumer retrieves #{item}"
  end
end


sleep 60   # Run a minute, then die and kill threads