def relay src, dst = nil, t = nil
send_dst =
if dst.respond_to?(:call)
lambda{|buf| dst.call(buf)}
else
lambda{|buf| dst << buf}
end
unless src.nil?
if src.respond_to? :gets
while buf = to(t){ src.gets }
send_dst[buf]
end
elsif src.respond_to? :each
q = Queue.new
th = nil
timer_set = lambda do |t|
th = new_thread{ to(t){ q.pop } }
end
timer_cancel = lambda do |t|
th.kill if th rescue nil
end
timer_set[t]
begin
src.each do |buf|
timer_cancel[t]
send_dst[buf]
timer_set[t]
end
ensure
timer_cancel[t]
end
elsif src.respond_to? :read
buf = to(t){ src.read }
send_dst[buf]
else
buf = to(t){ src.to_s }
send_dst[buf]
end
end
end