diff options
author | Bert Belder <bertbelder@gmail.com> | 2012-08-20 23:59:21 +0200 |
---|---|---|
committer | Bert Belder <bertbelder@gmail.com> | 2012-08-21 00:18:10 +0200 |
commit | 600a6468dc9067a358893f26ff46f1cd865f3c97 (patch) | |
tree | e7ba9665359f4903be52c9af5bb9511899d03bec /src | |
parent | 6bec5440ebced1bc2b91c1c9f3fbc7a361995331 (diff) | |
download | node-new-600a6468dc9067a358893f26ff46f1cd865f3c97.tar.gz |
process: use uv_signal instead of ev_signal
Diffstat (limited to 'src')
-rw-r--r-- | src/node.cc | 4 | ||||
-rw-r--r-- | src/node.js | 39 | ||||
-rw-r--r-- | src/node_constants.cc | 4 | ||||
-rw-r--r-- | src/node_extensions.h | 4 | ||||
-rw-r--r-- | src/signal_wrap.cc | 132 |
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) |