diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index d6ef327a8a..41cf8e89cc 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -386,17 +386,23 @@ function maybeReadMore(stream, state) { if (!state.readingMore) { state.readingMore = true; process.nextTick(function() { - state.readingMore = false; maybeReadMore_(stream, state); }); } } function maybeReadMore_(stream, state) { - if (!state.reading && !state.flowing && !state.ended && - state.length < state.highWaterMark) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && + state.length < state.highWaterMark) { stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break; + else + len = state.length; } + state.readingMore = false; } // abstract method. to be overridden in specific implementation classes. diff --git a/test/simple/test-stream2-unpipe-leak.js b/test/simple/test-stream2-unpipe-leak.js index c2cf9077f3..b9e8a960d8 100644 --- a/test/simple/test-stream2-unpipe-leak.js +++ b/test/simple/test-stream2-unpipe-leak.js @@ -24,6 +24,8 @@ var common = require('../common.js'); var assert = require('assert'); var stream = require('stream'); +var chunk = new Buffer('hallo'); + var util = require('util'); function TestWriter() { @@ -37,13 +39,15 @@ TestWriter.prototype._write = function(buffer, encoding, callback) { var dest = new TestWriter(); +// Set this high so that we'd trigger a nextTick warning +// and/or RangeError if we do maybeReadMore wrong. function TestReader() { - stream.Readable.call(this); + stream.Readable.call(this, { highWaterMark: 0x10000 }); } util.inherits(TestReader, stream.Readable); TestReader.prototype._read = function(size) { - this.push(new Buffer('hallo')); + this.push(chunk); }; var src = new TestReader(); @@ -61,3 +65,10 @@ assert.equal(dest.listeners('drain').length, 0); assert.equal(dest.listeners('error').length, 0); assert.equal(dest.listeners('close').length, 0); assert.equal(dest.listeners('finish').length, 0); + +console.error(src._readableState); +process.on('exit', function() { + assert(src._readableState.length >= src._readableState.highWaterMark); + src._readableState.buffer.length = 0; + console.error(src._readableState); +});