Skip to content

Instantly share code, notes, and snippets.

@rafkhan
Created August 25, 2012 17:54
Show Gist options
  • Save rafkhan/3468518 to your computer and use it in GitHub Desktop.
Save rafkhan/3468518 to your computer and use it in GitHub Desktop.
class RPool
attr_accessor :max_size
attr_reader :workers
def initialize(max_size = 128)
@max_size = max_size
@workers = Array.new
@mutex = Mutex.new
end
def size()
@mutex.synchronize{ @workers.size }
end
def busy?()
@mutex.synchronize{ @workers.any?{|w| w.busy?} }
end
# prevent program from exiting while
# there are working workers
def join()
sleep 0.01 while busy?
end
# do something
def do(&b)
wait_for_worker.set_job(&b)
end
def wait_for_worker()
while true
#find free worker, or create one
worker = @mutex.synchronize{ get_free_worker || create_worker }
return worker if worker
sleep 0.01
end
end
def get_free_worker
@workers.each {|w| return w unless w.busy?}; nil
end
def create_worker
return nil if @workers.size >= @max_size
worker = RWorker.new nil
@workers << worker
worker
end
end
class RWorker
def initialize(&b)
@mutex = Mutex.new #for accessing block in thread
@job = &b
end
def run()
@thread = Thread.new do
while true
sleep 0.001
job = @mutex.synchronize{@job}
if !job.nil?
job.call #Run task
@mutex.synchronize{@job = nil} #Then remove job
else
sleep 0.01 #Waiting for a job
end
end
end
end
def busy?()
@mutex.synchronize{ !@job.nil? }
end
def set_job(&b)
@mutex.synchronize do
if @block
@block = &b
else
raise RuntimeError, "Thread is busy."
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment