Guarded Suspension

 require 'thread'
 
 #class RequestQueue
 # def initialize
 #   @mutex = Mutex.new
 #   @cv = ConditionVariable.new
 #   @queue = []
 # end
 # 
 # def pop
 #   @mutex.synchronize {
 #     while(@queue.size <=  0) do
 #     puts "#invoke wait"
 #       @cv.wait(@mutex)
 #     puts "#after wait"
 #     end
 #     return @queue.pop
 #   }
 # end
 # 
 # def push request
 #   @mutex.synchronize {
 #     @queue << request
 #     @cv.signal
 #   }
 # end
 #end
 
 class Request
   attr_accessor :name
   def initialize name
     @name = name
   end
 end
 
 class Client
   def initialize(queue, name)
     @queue = queue
     @name = name
     @t = Thread.new {
       do_run
     }
   end
   
   def do_run
     for i in 0..4 do
       request = Request.new("#{@name}:no#{i}")
       puts "#{Time.now.usec} [request] #{request.inspect}"
       @queue.push request
       sleep(rand(5))
     end
   end
   
   def join
     @t.join
   end
 end
 
 class Server
   def initialize(queue, name)
     @queue = queue
     @name = name
     @t = Thread.new {
       do_run
     }
   end
   def do_run 
       for i in 0..30 do
         req = @queue.pop
         puts "#{Time.now.usec} [handle]  #{req.inspect}" 
         sleep(rand(1))
       end
   end
   def join
     @t.join
   end
 end
 
 #queue = RequestQueue.new
 queue = Queue.new
 s = Server.new(queue, "server")
 c1 = Client.new(queue, "A client")
 c2 = Client.new(queue, "B client")
 c3 = Client.new(queue, "C client")
 
 s.join
 c1.join
 c2.join
 c3.join

C:\rubywork\thread>ruby guarded_suspension.rb
432000 [request] #
432000 [handle]  #
432000 [request] #
432000 [handle]  #
432000 [request] #
432000 [handle]  #
433000 [request] #
433000 [handle]  #
435000 [request] #
435000 [handle]  #
436000 [request] #
436000 [handle]  #
438000 [request] #
438000 [request] #
438000 [request] #
438000 [handle]  #
438000 [handle]  #
438000 [handle]  #
440000 [request] #
440000 [request] #
440000 [handle]  #
440000 [handle]  #
443000 [request] #
443000 [handle]  #
443000 [request] #
443000 [handle]  #
445000 [request] #
445000 [handle]  #
449000 [request] #
449000 [handle]  #
deadlock 0x2925d00: sleep:-  - c:/ruby/lib/ruby/1.8/thread.rb:281
deadlock 0x2955628: sleep:J(0x2925d00) (main) - guarded_suspension.rb:75
guarded_suspension.rb:40:in `join': Thread(0x2924a88): deadlock (fatal)
        from guarded_suspension.rb:86