Skip to content

Instantly share code, notes, and snippets.

@sporkmonger
Created May 6, 2009 00:02
Show Gist options
  • Save sporkmonger/107291 to your computer and use it in GitHub Desktop.
Save sporkmonger/107291 to your computer and use it in GitHub Desktop.
require "sync"
require "blankslate"
class Channel < BlankSlate
def initialize
@sync = Sync.new
@queue = []
end
def queue
@sync.synchronize do
@queue
end
end
def inspect
sprintf("#<Channel:%#0x QUEUED:%d>", __id__, self.queue.size)
end
def method_missing(method, *params, &block)
@sync.synchronize do
@queue.push([method.to_sym, params, block])
end
return true
end
def receive(object, method=nil)
(lambda do
if method.respond_to?(:to_sym)
method = method.to_sym
params, block = nil, nil
found = false
@sync.synchronize do
@queue.each_with_index do |(qmethod, qparams, qblock), index|
if method == qmethod
method, params, block = qmethod, qparams, qblock
@queue.delete_at(index)
found = true
break
end
end
end
if found
return object.send(method, *params, &block)
else
Thread.pass
redo
end
elsif method == nil
@sync.synchronize do
method, params, block = @queue.shift
end
if method
return object.send(method, *params, &block)
else
Thread.pass
redo
end
else
raise TypeError, "Can't convert #{method.class} into Symbol."
end
end).call
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment