def relay src, dst = nil, t = nil
unless src.nil?
if src.respond_to? :gets
while buf = to(t){ src.gets }
dst << buf if dst
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]
dst << buf if dst
timer_set[t]
end
ensure
timer_cancel[t]
end
elsif src.respond_to? :read
buf = to(t){ src.read }
dst << buf if dst
else
buf = to(t){ src.to_s }
dst << buf if dst
end
end
end