diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown index 2f399a77aa..bdd709f7e2 100644 --- a/doc/api/stream.markdown +++ b/doc/api/stream.markdown @@ -310,6 +310,24 @@ readable.on('data', function(chunk) { }) ``` +#### readable.isPaused() + +* Return: `Boolean` + +This method returns whether or not the `readable` has been **explicitly** +paused by client code (using `readable.pause()` without a corresponding +`readable.resume()`). + +```javascript +var readable = new stream.Readable + +readable.isPaused() // === false +readable.pause() +readable.isPaused() // === true +readable.resume() +readable.isPaused() // === false +``` + #### readable.pipe(destination, [options]) * `destination` {[Writable][] Stream} The destination for writing data diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index b1b89392a5..c691137374 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -131,6 +131,10 @@ Readable.prototype.unshift = function(chunk) { return readableAddChunk(this, state, chunk, '', true); }; +Readable.prototype.isPaused = function() { + return this._readableState.flowing === false; +}; + function readableAddChunk(stream, state, chunk, encoding, addToFront) { var er = chunkInvalid(state, chunk); if (er) { diff --git a/lib/net.js b/lib/net.js index c653c814b7..5746b1c55c 100644 --- a/lib/net.js +++ b/lib/net.js @@ -970,7 +970,7 @@ function afterConnect(status, handle, req, readable, writable) { // start the first read, or get an immediate EOF. // this doesn't actually consume any bytes, because len=0. - if (readable) + if (readable && !self.isPaused()) self.read(0); } else { diff --git a/test/simple/test-net-connect-paused-connection.js b/test/simple/test-net-connect-paused-connection.js new file mode 100644 index 0000000000..c38f51e36e --- /dev/null +++ b/test/simple/test-net-connect-paused-connection.js @@ -0,0 +1,35 @@ +// Copyright Joyent, Inc. and other Node contributors. + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var assert = require('assert'); +var common = require('../common'); + +var net = require('net'); + +net.createServer(function(conn) { + conn.unref(); +}).listen(8124).unref(); + +net.connect(8124, 'localhost').pause(); + +setTimeout(function() { + assert.fail('expected to exit'); +}, 1000).unref(); diff --git a/test/simple/test-stream-ispaused.js b/test/simple/test-stream-ispaused.js new file mode 100644 index 0000000000..91f4f512f0 --- /dev/null +++ b/test/simple/test-stream-ispaused.js @@ -0,0 +1,44 @@ +// Copyright Joyent, Inc. and other Node contributors. + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var assert = require('assert'); +var common = require('../common'); + +var stream = require('stream'); + +var readable = new stream.Readable; + +// _read is a noop, here. +readable._read = Function(); + +// default state of a stream is not "paused" +assert.ok(!readable.isPaused()); + +// make the stream start flowing... +readable.on('data', Function()); + +// still not paused. +assert.ok(!readable.isPaused()); + +readable.pause(); +assert.ok(readable.isPaused()); +readable.resume(); +assert.ok(!readable.isPaused());