Creating a new socketpair/pipe is pretty too much imho (no matter it's a
very
small object, but it exists and must be handled). I thought about some
kind of
semaphore, then process would look like:
in thread:
semaphore.wait_for_event
in main:
semaphore.emit_event
I've found the way how to do this, here is code + example:
#!/usr/bin/ruby -w
require 'thread'
class MassSemaphoreEmulator
def initialize
@mutex=Mutex.new # we can have race condition on a variable below,
so avoid it with mutex
@waiting_threads=[]
end
def wait
@mutex.synchronize { @waiting_threads<<Thread.current } # add
current thread to waiting ones
Thread.stop
end
def signal
@mutex.synchronize do # wakeup all threads
@waiting_threads.each {|t| t.wakeup}
@waiting_threads.clear
end
end
end
semaphore=MassSemaphoreEmulator.new
threads=(1..10).map do |i|
Thread.new(i*1) do |v|
print "#{v} is waiting...\n"
semaphore.wait # wait for our mutex
print "#{v} got signal.\n"
end
end
semaphore.signal # get all waiting threads up
threads.each {|t| t.join}
I've also tried to do something with ConditionalVariable, but no luck,
it didn't stop waiting threads.
now I need to find a way for interrupting select call