# Copyright 2005 Kevin Reid, under the terms of the MIT X license # found at http://www.opensource.org/licenses/mit-license.html ................ pragma.enable("easy-return") pragma.disable("explicit-result-guard") def [=> NOW, => LATER, => WAIT, => ELEMENTS, => STATUS, => ADVANCE, => QUERY] := def eiop { to size() { return 0 } to optExtract(key) { return [E.call(EIO, "get" + key, []), eiop] } } def join implements DeepFrozen { /** Transfers the elements of an InStream to an OutStream. Acts immediately if possible; for non-immediate effects, use join <- (...). The return value will be resolved, to the terminator of the input stream, as soon as no more elements will be delivered to the OutStream; at this time, the output stream will also be terminated. */ to run(input, output) { # XXX incomplete implementation - see stream-misc.updoc def again var queued := false var willLoop := false def transfer() { traceln(`join transfer $input $output: ${input.available()}, ${output.available()}`) output.write(def e := input.read(0, output.available())) traceln(`join transferred: ${E.toQuote(e)}`) if (Ref.isResolved(def t := input.terminates())) { if (Ref.isBroken(t)) { output.fail(Ref.optProblem(t)) } else { output.close() } } else { queued := false if (!willLoop) { again() } } } bind again() { try { willLoop := true __loop(thunk { queued := true output.whenAvailable(1, thunk { input.whenAvailable(1, transfer) }) return !queued }) } finally { willLoop := false } } transfer() return input.terminates() } }