MenTaLguY
3/25/2008 6:01:00 PM
On Tue, 25 Mar 2008 12:32:38 +0900, "Adam Bender" <abender@gmail.com> wrote:
> require 'thread.so'
> -----------------------
> Does this mean the Ruby code for Queue is compiled into a shared
> library? Is it possible to edit the code? (I know I can modify the
> class from outside the file, and that is probably what I will end up
> doing, but I'm rather surprised by the above file contents and would
> like to know more about it).
Yes, it's implemented in C. In JRuby, it's implemented in Java.
I do agree that the following thread.rb operations need to directly
support timeouts, though:
ConditionVariable#wait
Queue#pop
SizedQueue#pop
SizedQueue#push
Unfortunately, there is no _reliable_ way to patch timeouts in after
the fact. The support needs to be added to Ruby core.
In the interim, I think the best you can do is to implement your own
queue data structure which supports timeouts using Mutex,
ConditionVariable and the 'scheduler' gem. For instance:
require 'thread'
require 'scheduler'
class MyQueue
def initialize
@lock = Mutex.new
@values = []
@readers = []
end
class Timeout < Interrupt
end
class Reader
def initialize
@condition = ConditionVariable.new
@state = :waiting
@value = nil
end
def timeout
@state = :timeout
@condition.signal
self
end
def value=(value)
@value = value
@state = :ready
@condition.signal
self
end
def wait_for_value(lock)
@condition.wait(lock) while @state == :waiting
raise Timeout, "timed out" unless @state == :ready
@value
end
end
def push(value)
@lock.synchronize do
if @readers.empty?
@values.push value
else
@readers.pop.value = value
end
end
self
end
def pop(timeout=nil)
@lock.synchronize do
unless @values.empty?
@values.pop
else
reader = Reader.new
@readers.push reader
begin
if timeout
timeout = Scheduler.after_delay!(timeout) do
@lock.synchronize do
reader.timeout if @readers.delete reader
end
end
end
reader.wait_for_value(@lock)
finally
@readers.delete reader
timeout.cancel if timeout
end
end
end
end
end
(This is untested, but should basically do what you need and you're
welcome to use it. Feel free to ask any questions you might have.)
-mental