summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBert Belder <bertbelder@gmail.com>2012-08-20 23:59:21 +0200
committerBert Belder <bertbelder@gmail.com>2012-08-21 00:18:10 +0200
commit600a6468dc9067a358893f26ff46f1cd865f3c97 (patch)
treee7ba9665359f4903be52c9af5bb9511899d03bec /src
parent6bec5440ebced1bc2b91c1c9f3fbc7a361995331 (diff)
downloadnode-new-600a6468dc9067a358893f26ff46f1cd865f3c97.tar.gz
process: use uv_signal instead of ev_signal
Diffstat (limited to 'src')
-rw-r--r--src/node.cc4
-rw-r--r--src/node.js39
-rw-r--r--src/node_constants.cc4
-rw-r--r--src/node_extensions.h4
-rw-r--r--src/signal_wrap.cc132
5 files changed, 164 insertions, 19 deletions
diff --git a/src/node.cc b/src/node.cc
index 44a77f8eb6..261a28e489 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -694,6 +694,10 @@ const char *signo_string(int signo) {
SIGNO_CASE(SIGTSTP);
#endif
+#ifdef SIGBREAK
+ SIGNO_CASE(SIGBREAK);
+#endif
+
#ifdef SIGTTIN
SIGNO_CASE(SIGTTIN);
#endif
diff --git a/src/node.js b/src/node.js
index 07db3f0963..3811bd32ed 100644
--- a/src/node.js
+++ b/src/node.js
@@ -562,40 +562,47 @@
startup.processSignalHandlers = function() {
// Load events module in order to access prototype elements on process like
// process.addListener.
- var signalWatchers = {};
+ var signalWraps = {};
var addListener = process.addListener;
var removeListener = process.removeListener;
function isSignal(event) {
- return event.slice(0, 3) === 'SIG' && startup.lazyConstants()[event];
+ return event.slice(0, 3) === 'SIG' &&
+ startup.lazyConstants().hasOwnProperty(event);
}
// Wrap addListener for the special signal types
process.on = process.addListener = function(type, listener) {
- var ret = addListener.apply(this, arguments);
- if (isSignal(type)) {
- if (!signalWatchers.hasOwnProperty(type)) {
- var b = process.binding('signal_watcher');
- var w = new b.SignalWatcher(startup.lazyConstants()[type]);
- w.callback = function() { process.emit(type); };
- signalWatchers[type] = w;
- w.start();
-
- } else if (this.listeners(type).length === 1) {
- signalWatchers[type].start();
+ if (isSignal(type) &&
+ !signalWraps.hasOwnProperty(type)) {
+ var Signal = process.binding('signal_wrap').Signal;
+ var wrap = new Signal();
+
+ wrap.unref();
+
+ wrap.onsignal = function () { process.emit(type); };
+
+ var signum = startup.lazyConstants()[type];
+ var r = wrap.start(signum);
+ if (r) {
+ wrap.close();
+ throw errnoException(errno, "uv_signal_start");
}
+
+ signalWraps[type] = wrap;
}
- return ret;
+ return addListener.apply(this, arguments);
};
process.removeListener = function(type, listener) {
var ret = removeListener.apply(this, arguments);
if (isSignal(type)) {
- assert(signalWatchers.hasOwnProperty(type));
+ assert(signalWraps.hasOwnProperty(type));
if (this.listeners(type).length === 0) {
- signalWatchers[type].stop();
+ signalWraps[type].close();
+ delete signalWraps[type];
}
}
diff --git a/src/node_constants.cc b/src/node_constants.cc
index 7999f51ea4..06397b9280 100644
--- a/src/node_constants.cc
+++ b/src/node_constants.cc
@@ -791,6 +791,10 @@ void DefineConstants(Handle<Object> target) {
NODE_DEFINE_CONSTANT(target, SIGTSTP);
#endif
+#ifdef SIGBREAK
+ NODE_DEFINE_CONSTANT(target, SIGBREAK);
+#endif
+
#ifdef SIGTTIN
NODE_DEFINE_CONSTANT(target, SIGTTIN);
#endif
diff --git a/src/node_extensions.h b/src/node_extensions.h
index 7a7702c9fb..c96c670af9 100644
--- a/src/node_extensions.h
+++ b/src/node_extensions.h
@@ -29,9 +29,6 @@ NODE_EXT_LIST_ITEM(node_crypto)
NODE_EXT_LIST_ITEM(node_evals)
NODE_EXT_LIST_ITEM(node_fs)
NODE_EXT_LIST_ITEM(node_http_parser)
-#ifdef __POSIX__
-NODE_EXT_LIST_ITEM(node_signal_watcher)
-#endif
NODE_EXT_LIST_ITEM(node_os)
NODE_EXT_LIST_ITEM(node_zlib)
@@ -44,6 +41,7 @@ NODE_EXT_LIST_ITEM(node_cares_wrap)
NODE_EXT_LIST_ITEM(node_tty_wrap)
NODE_EXT_LIST_ITEM(node_process_wrap)
NODE_EXT_LIST_ITEM(node_fs_event_wrap)
+NODE_EXT_LIST_ITEM(node_signal_wrap)
NODE_EXT_LIST_END
diff --git a/src/signal_wrap.cc b/src/signal_wrap.cc
new file mode 100644
index 0000000000..b39049001a
--- /dev/null
+++ b/src/signal_wrap.cc
@@ -0,0 +1,132 @@
+// 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.
+
+#include "node.h"
+#include "handle_wrap.h"
+
+
+namespace node {
+
+using v8::Object;
+using v8::Handle;
+using v8::Local;
+using v8::Persistent;
+using v8::Value;
+using v8::HandleScope;
+using v8::FunctionTemplate;
+using v8::String;
+using v8::Function;
+using v8::TryCatch;
+using v8::Context;
+using v8::Arguments;
+using v8::Integer;
+
+static Persistent<String> onsignal_sym;
+
+
+class SignalWrap : public HandleWrap {
+ public:
+ static void Initialize(Handle<Object> target) {
+ HandleScope scope;
+
+ HandleWrap::Initialize(target);
+
+ Local<FunctionTemplate> constructor = FunctionTemplate::New(New);
+ constructor->InstanceTemplate()->SetInternalFieldCount(1);
+ constructor->SetClassName(String::NewSymbol("Signal"));
+
+ NODE_SET_PROTOTYPE_METHOD(constructor, "close", HandleWrap::Close);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "ref", HandleWrap::Ref);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "unref", HandleWrap::Unref);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "start", Start);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "stop", Stop);
+
+ onsignal_sym = NODE_PSYMBOL("onsignal");
+
+ target->Set(String::NewSymbol("Signal"), constructor->GetFunction());
+ }
+
+ private:
+ static Handle<Value> New(const Arguments& args) {
+ // This constructor should not be exposed to public javascript.
+ // Therefore we assert that we are not trying to call this as a
+ // normal function.
+ assert(args.IsConstructCall());
+
+ HandleScope scope;
+ SignalWrap* wrap = new SignalWrap(args.This());
+
+ return scope.Close(args.This());
+ }
+
+ SignalWrap(Handle<Object> object)
+ : HandleWrap(object, reinterpret_cast<uv_handle_t*>(&handle_)) {
+ int r = uv_signal_init(uv_default_loop(), &handle_);
+ assert(r == 0);
+ }
+
+ ~SignalWrap() {
+ }
+
+ static Handle<Value> Start(const Arguments& args) {
+ HandleScope scope;
+
+ UNWRAP(SignalWrap)
+
+ int signum = args[0]->Int32Value();
+
+ int r = uv_signal_start(&wrap->handle_, OnSignal, signum);
+
+ if (r) SetErrno(uv_last_error(uv_default_loop()));
+
+ return scope.Close(Integer::New(r));
+ }
+
+ static Handle<Value> Stop(const Arguments& args) {
+ HandleScope scope;
+
+ UNWRAP(SignalWrap)
+
+ int r = uv_signal_stop(&wrap->handle_);
+
+ if (r) SetErrno(uv_last_error(uv_default_loop()));
+
+ return scope.Close(Integer::New(r));
+ }
+
+ static void OnSignal(uv_signal_t* handle, int signum) {
+ HandleScope scope;
+
+ SignalWrap* wrap = container_of(handle, SignalWrap, handle_);
+ assert(wrap);
+
+ Local<Value> argv[1] = { Integer::New(signum) };
+ MakeCallback(wrap->object_, onsignal_sym, ARRAY_SIZE(argv), argv);
+ }
+
+ uv_signal_t handle_;
+};
+
+
+} // namespace node
+
+
+NODE_MODULE(node_signal_wrap, node::SignalWrap::Initialize)