Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
process: use uv_signal instead of ev_signal
Browse files Browse the repository at this point in the history
  • Loading branch information
piscisaureus committed Aug 20, 2012
1 parent 6bec544 commit 600a646
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 20 deletions.
2 changes: 1 addition & 1 deletion node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -205,7 +206,6 @@
}, { # POSIX
'defines': [ '__POSIX__' ],
'sources': [
'src/node_signal_watcher.cc',
'src/node_io_watcher.cc',
],
}],
Expand Down
4 changes: 4 additions & 0 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 23 additions & 16 deletions src/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/node_constants.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 1 addition & 3 deletions src/node_extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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 changes: 132 additions & 0 deletions src/signal_wrap.cc
Original file line number Diff line number Diff line change
@@ -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)

0 comments on commit 600a646

Please sign in to comment.