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

Reply via email to