Hello,

I'm using the ThreadPool class as defined in the Ruby Cookbook, recipe
20.7 and running on Windows XP with the One Click installer of Ruby
1.8.6 patch level 0.  Normally it works fine.  However, whenever I call
a command using backticks I get a deadlock.  The script I'm running is
below, followed by the output.  To see it succeed, comment out the
backtick line and uncomment out the system line.

Does anyone know what the problem is?

Thanks,
Justin

##### BEGIN FILE ######
require 'thread'

class ThreadPool
  def initialize(max_size)
    @pool = []
    @max_size = max_size
    @pool_mutex = Mutex.new
    @pool_cv = ConditionVariable.new
  end
#---
  def dispatch(*args)
    Thread.new do
      # Wait for space in the pool.
      @pool_mutex.synchronize do
        while @pool.size >= @max_size
          print "Pool is full; waiting to run #{args.join(',')}...\n" if
$DEBUG
          # Sleep until some other thread calls @pool_cv.signal.
          @pool_cv.wait(@pool_mutex)
        end
      end
#---
      @pool << Thread.current
      begin
        yield(*args)
      rescue => e
        exception(self, e, *args)
      ensure
        @pool_mutex.synchronize do
          # Remove the thread from the pool.
          @pool.delete(Thread.current)
          # Signal the next waiting thread that there's a space in the
pool.
          @pool_cv.signal
        end
      end
    end
  end

  def shutdown
    @pool_mutex.synchronize { @pool_cv.wait(@pool_mutex) until
@pool.empty? }
  end

  def exception(thread, exception, *original_args)
    # Subclass this method to handle an exception within a thread.
    puts "Exception in thread #{thread}: #{exception}"
  end
end
#---



pool = ThreadPool.new 2
begin
  1.upto(200) do |i|
    pool.dispatch do
      puts "Job #{i} started."
      `dir c:\\winnt > NUL`
      #system("dir c:\\winnt > NUL")
      puts "Job #{i} stopped."
    end
  end
ensure
  pool.shutdown
end
##### END FILE ######


##### BEGIN OUTPUT ######
C:\temp>ruby thread_test.rb
Job 1 started.
Job 2 started.
Job 1 stopped.
Job 2 stopped.
Job 3 started.
Job 6 started.
Job 5 started.
Job 4 started.
Job 3 stopped.
Job 6 stopped.
Job 5 stopped.
Job 4 stopped.
deadlock 0x2b45008: sleep:-  - thread_test.rb:18
deadlock 0x2b450d0: sleep:-  - thread_test.rb:18
deadlock 0x2b45198: sleep:-  - thread_test.rb:18
deadlock 0x2b45260: sleep:-  - thread_test.rb:18
... Skip many similar lines ...
deadlock 0x2b5627c: sleep:-  - thread_test.rb:28
deadlock 0x2b5636c: sleep:-  - thread_test.rb:28
deadlock 0x27ac748: sleep:- (main) - thread_test.rb:39
thread_test.rb:39:in `wait': Thread(0x27ac748): deadlock (fatal)
        from thread_test.rb:39:in `shutdown'
        from thread_test.rb:39:in `synchronize'
        from thread_test.rb:39:in `shutdown'
        from thread_test.rb:62

C:\temp>
##### END OUTPUT ######
-- 
Posted via http://www.ruby-forum.com/.