Browse Source

process: use uv_signal instead of ev_signal

v0.9.1-release
Bert Belder 12 years ago
parent
commit
600a6468dc
  1. 2
      node.gyp
  2. 4
      src/node.cc
  3. 39
      src/node.js
  4. 4
      src/node_constants.cc
  5. 4
      src/node_extensions.h
  6. 132
      src/signal_wrap.cc

2
node.gyp

@ -87,6 +87,7 @@
'src/node_string.cc',
'src/node_zlib.cc',
'src/pipe_wrap.cc',
'src/signal_wrap.cc',
'src/stream_wrap.cc',
'src/slab_allocator.cc',
'src/tcp_wrap.cc',
@ -205,7 +206,6 @@
}, { # POSIX
'defines': [ '__POSIX__' ],
'sources': [
'src/node_signal_watcher.cc',
'src/node_io_watcher.cc',
],
}],

4
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

39
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];
}
}

4
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

4
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

132
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)
Loading…
Cancel
Save