Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: nodejs/node-v0.x-archive
base: 440bc060b985
Choose a base ref
...
head repository: nodejs/node-v0.x-archive
compare: b0de1e4a4161
Choose a head ref
  • 1 commit
  • 3 files changed
  • 1 contributor

Commits on Apr 11, 2013

  1. stream: Fix unshift() race conditions

    Fix #5272
    
    The consumption of a readable stream is a dance with 3 partners.
    
    1. The specific stream Author (A)
    2. The Stream Base class (B), and
    3. The Consumer of the stream (C)
    
    When B calls the _read() method that A implements, it sets a 'reading'
    flag, so that parallel calls to _read() can be avoided.  When A calls
    stream.push(), B knows that it's safe to start calling _read() again.
    
    If the consumer C is some kind of parser that wants in some cases to
    pass the source stream off to some other party, but not before "putting
    back" some bit of previously consumed data (as in the case of Node's
    websocket http upgrade implementation).  So, stream.unshift() will
    generally *never* be called by A, but *only* called by C.
    
    Prior to this patch, stream.unshift() *also* unset the state.reading
    flag, meaning that C could indicate the end of a read, and B would
    dutifully fire off another _read() call to A.  This is inappropriate.
    In the case of fs streams, and other variably-laggy streams that don't
    tolerate overlapped _read() calls, this causes big problems.
    
    Also, calling stream.shift() after the 'end' event did not raise any
    kind of error, but would cause very strange behavior indeed.  Calling it
    after the EOF chunk was seen, but before the 'end' event was fired would
    also cause weird behavior, and could lead to data being lost, since it
    would not emit another 'readable' event.
    
    This change makes it so that:
    
    1. stream.unshift() does *not* set state.reading = false
    2. stream.unshift() is allowed up until the 'end' event.
    3. unshifting onto a EOF-encountered and zero-length (but not yet
    end-emitted) stream will defer the 'end' event until the new data is
    consumed.
    4. pushing onto a EOF-encountered stream is now an error.
    
    So, if you read(), you have that single tick to safely unshift() data
    back into the stream, even if the null chunk was pushed, and the length
    was 0.
    isaacs committed Apr 11, 2013
    Copy the full SHA
    b0de1e4 View commit details
    Browse the repository at this point in the history