I am curious as to whether FANOUT STOP is completely deterministic, and would appreciate some feedback from the experts. Consider the following pipe:
pipe (end ?) literal a | literal b | f: fanout STOP 1 | spec /X/ 1 | cons ? f: | take 1 | spec /Y/ 1 | cons I would expect to see something like: X Y However, I was wondering about a (very timing dependant) situation where perhaps I could end up with a second record on the primary output stream. The Author's Edition of the manual has this to say: "fanout writes the input record to all connected output streams before it tests for the number of streams at end-of-file." So, as I understand it, the normal case would pretty much consist of this sequence: 1. FANOUT writes a record to the primary stream (where it is consumed by SPEC and eventually CONS). 2. FANOUT then writes the same record to the secondary output stream where TAKE is blocked waiting for a record. 3. TAKE wakes up from its peekto() and checks if it has hit the record count limit 4. TAKE calls readto() to consume the record 5. TAKE exits 6. FANOUT is dispatched (released from its call to output()) 7. FANOUT checks to see if there are any output streams at EOF 8. FANOUT exits because the EOF stream count is 1 (TAKE's streams were severed when it exited) However, if my understanding of the dispatcher is correct, I can imagine an alternative case for step 5 and later: ... 5. TAKE's call to readto() causes FANOUT to be dispatched (instead of TAKE) 6. FANOUT checks to see if there are any output streams at EOF (TAKE hasn't exited yet, so there are none) 7. FANOUT calls readto() to read another input record 8. TAKE gets dispatched, returns from readto() and exits 9. FANOUT writes the newly read record to the primary output stream. The key thing I am trying to understand is what happens when TAKE calls readto(). At that point, there is a FANOUT stage currently waiting in output(), so the dispatcher has a rendesvouz where it has to make a decision: 1. Mark FANOUT as dispatchable, but allow TAKE to continue running (ie. dispatch TAKE) 2. Mark TAKE as dispatchable, but actually dispatch FANOUT I am curious as to whether the second scenario listed above could actually happen, and assuming not, what is it about the dispatching process that I am misunderstanding. My apologies for the long winded post... I hope it makes some sense. Cheers, Craig
