summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/net.js4
-rw-r--r--lib/tty.js11
-rw-r--r--src/handle_wrap.cc30
-rw-r--r--src/handle_wrap.h1
-rw-r--r--src/pipe_wrap.cc1
-rw-r--r--src/tty_wrap.cc1
-rw-r--r--test/simple/test-stdin-pause-resume.js37
7 files changed, 78 insertions, 7 deletions
diff --git a/lib/net.js b/lib/net.js
index 13b33a45b7..aa6e043ea4 100644
--- a/lib/net.js
+++ b/lib/net.js
@@ -194,7 +194,9 @@ Object.defineProperty(Socket.prototype, 'bufferSize', {
Socket.prototype.pause = function() {
- this._handle.readStop();
+ if (this._handle) {
+ this._handle.readStop();
+ }
};
diff --git a/lib/tty.js b/lib/tty.js
index 78971dda31..32ba512d52 100644
--- a/lib/tty.js
+++ b/lib/tty.js
@@ -83,8 +83,19 @@ function ReadStream(fd) {
this.on('newListener', onNewListener);
}
inherits(ReadStream, net.Socket);
+
exports.ReadStream = ReadStream;
+ReadStream.prototype.pause = function() {
+ this._handle.unref();
+ return net.Socket.prototype.pause.call(this);
+};
+
+ReadStream.prototype.resume = function() {
+ this._handle.ref();
+ return net.Socket.prototype.resume.call(this);
+};
+
ReadStream.prototype.isTTY = true;
diff --git a/src/handle_wrap.cc b/src/handle_wrap.cc
index 6e07643893..5b6594a3a9 100644
--- a/src/handle_wrap.cc
+++ b/src/handle_wrap.cc
@@ -64,8 +64,10 @@ Handle<Value> HandleWrap::Unref(const Arguments& args) {
UNWRAP
- // Calling this function twice should never happen.
- assert(wrap->unref == false);
+ // Calling unnecessarily is a no-op
+ if (wrap->unref) {
+ return v8::Undefined();
+ }
wrap->unref = true;
uv_unref(uv_default_loop());
@@ -74,6 +76,24 @@ Handle<Value> HandleWrap::Unref(const Arguments& args) {
}
+// Adds a reference to keep uv alive because of this thing.
+Handle<Value> HandleWrap::Ref(const Arguments& args) {
+ HandleScope scope;
+
+ UNWRAP
+
+ // Calling multiple times is a no-op
+ if (!wrap->unref) {
+ return v8::Undefined();
+ }
+
+ wrap->unref = false;
+ uv_ref(uv_default_loop());
+
+ return v8::Undefined();
+}
+
+
Handle<Value> HandleWrap::Close(const Arguments& args) {
HandleScope scope;
@@ -82,10 +102,8 @@ Handle<Value> HandleWrap::Close(const Arguments& args) {
assert(!wrap->object_.IsEmpty());
uv_close(wrap->handle__, OnClose);
- if (wrap->unref) {
- uv_ref(uv_default_loop());
- wrap->unref = false;
- }
+
+ HandleWrap::Ref(args);
wrap->StateChange();
diff --git a/src/handle_wrap.h b/src/handle_wrap.h
index fc6d623ac6..b9cf31e8eb 100644
--- a/src/handle_wrap.h
+++ b/src/handle_wrap.h
@@ -49,6 +49,7 @@ class HandleWrap {
static void Initialize(v8::Handle<v8::Object> target);
static v8::Handle<v8::Value> Close(const v8::Arguments& args);
static v8::Handle<v8::Value> Unref(const v8::Arguments& args);
+ static v8::Handle<v8::Value> Ref(const v8::Arguments& args);
protected:
HandleWrap(v8::Handle<v8::Object> object, uv_handle_t* handle);
diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc
index a2a4203a80..1870837bca 100644
--- a/src/pipe_wrap.cc
+++ b/src/pipe_wrap.cc
@@ -85,6 +85,7 @@ void PipeWrap::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(t, "close", HandleWrap::Close);
NODE_SET_PROTOTYPE_METHOD(t, "unref", HandleWrap::Unref);
+ NODE_SET_PROTOTYPE_METHOD(t, "ref", HandleWrap::Ref);
NODE_SET_PROTOTYPE_METHOD(t, "readStart", StreamWrap::ReadStart);
NODE_SET_PROTOTYPE_METHOD(t, "readStop", StreamWrap::ReadStop);
diff --git a/src/tty_wrap.cc b/src/tty_wrap.cc
index b46e6c4e1f..486c2a70b4 100644
--- a/src/tty_wrap.cc
+++ b/src/tty_wrap.cc
@@ -69,6 +69,7 @@ class TTYWrap : StreamWrap {
NODE_SET_PROTOTYPE_METHOD(t, "close", HandleWrap::Close);
NODE_SET_PROTOTYPE_METHOD(t, "unref", HandleWrap::Unref);
+ NODE_SET_PROTOTYPE_METHOD(t, "ref", HandleWrap::Ref);
NODE_SET_PROTOTYPE_METHOD(t, "readStart", StreamWrap::ReadStart);
NODE_SET_PROTOTYPE_METHOD(t, "readStop", StreamWrap::ReadStop);
diff --git a/test/simple/test-stdin-pause-resume.js b/test/simple/test-stdin-pause-resume.js
new file mode 100644
index 0000000000..cfa44bae2c
--- /dev/null
+++ b/test/simple/test-stdin-pause-resume.js
@@ -0,0 +1,37 @@
+// 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.
+
+console.error("before opening stdin");
+process.stdin.resume();
+console.error("stdin opened");
+setTimeout(function() {
+ console.error("pausing stdin");
+ process.stdin.pause();
+ setTimeout(function() {
+ console.error("opening again");
+ process.stdin.resume();
+ setTimeout(function() {
+ console.error("pausing again");
+ process.stdin.pause();
+ console.error("should exit now");
+ }, 1);
+ }, 1);
+}, 1);