Skip to content

Commit 600a646

Browse files
committed
process: use uv_signal instead of ev_signal
1 parent 6bec544 commit 600a646

6 files changed

Lines changed: 165 additions & 20 deletions

File tree

node.gyp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
'src/node_string.cc',
8888
'src/node_zlib.cc',
8989
'src/pipe_wrap.cc',
90+
'src/signal_wrap.cc',
9091
'src/stream_wrap.cc',
9192
'src/slab_allocator.cc',
9293
'src/tcp_wrap.cc',
@@ -205,7 +206,6 @@
205206
}, { # POSIX
206207
'defines': [ '__POSIX__' ],
207208
'sources': [
208-
'src/node_signal_watcher.cc',
209209
'src/node_io_watcher.cc',
210210
],
211211
}],

src/node.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,10 @@ const char *signo_string(int signo) {
694694
SIGNO_CASE(SIGTSTP);
695695
#endif
696696

697+
#ifdef SIGBREAK
698+
SIGNO_CASE(SIGBREAK);
699+
#endif
700+
697701
#ifdef SIGTTIN
698702
SIGNO_CASE(SIGTTIN);
699703
#endif

src/node.js

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -562,40 +562,47 @@
562562
startup.processSignalHandlers = function() {
563563
// Load events module in order to access prototype elements on process like
564564
// process.addListener.
565-
var signalWatchers = {};
565+
var signalWraps = {};
566566
var addListener = process.addListener;
567567
var removeListener = process.removeListener;
568568

569569
function isSignal(event) {
570-
return event.slice(0, 3) === 'SIG' && startup.lazyConstants()[event];
570+
return event.slice(0, 3) === 'SIG' &&
571+
startup.lazyConstants().hasOwnProperty(event);
571572
}
572573

573574
// Wrap addListener for the special signal types
574575
process.on = process.addListener = function(type, listener) {
575-
var ret = addListener.apply(this, arguments);
576-
if (isSignal(type)) {
577-
if (!signalWatchers.hasOwnProperty(type)) {
578-
var b = process.binding('signal_watcher');
579-
var w = new b.SignalWatcher(startup.lazyConstants()[type]);
580-
w.callback = function() { process.emit(type); };
581-
signalWatchers[type] = w;
582-
w.start();
583-
584-
} else if (this.listeners(type).length === 1) {
585-
signalWatchers[type].start();
576+
if (isSignal(type) &&
577+
!signalWraps.hasOwnProperty(type)) {
578+
var Signal = process.binding('signal_wrap').Signal;
579+
var wrap = new Signal();
580+
581+
wrap.unref();
582+
583+
wrap.onsignal = function () { process.emit(type); };
584+
585+
var signum = startup.lazyConstants()[type];
586+
var r = wrap.start(signum);
587+
if (r) {
588+
wrap.close();
589+
throw errnoException(errno, "uv_signal_start");
586590
}
591+
592+
signalWraps[type] = wrap;
587593
}
588594

589-
return ret;
595+
return addListener.apply(this, arguments);
590596
};
591597

592598
process.removeListener = function(type, listener) {
593599
var ret = removeListener.apply(this, arguments);
594600
if (isSignal(type)) {
595-
assert(signalWatchers.hasOwnProperty(type));
601+
assert(signalWraps.hasOwnProperty(type));
596602

597603
if (this.listeners(type).length === 0) {
598-
signalWatchers[type].stop();
604+
signalWraps[type].close();
605+
delete signalWraps[type];
599606
}
600607
}
601608

src/node_constants.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,10 @@ void DefineConstants(Handle<Object> target) {
791791
NODE_DEFINE_CONSTANT(target, SIGTSTP);
792792
#endif
793793

794+
#ifdef SIGBREAK
795+
NODE_DEFINE_CONSTANT(target, SIGBREAK);
796+
#endif
797+
794798
#ifdef SIGTTIN
795799
NODE_DEFINE_CONSTANT(target, SIGTTIN);
796800
#endif

src/node_extensions.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ NODE_EXT_LIST_ITEM(node_crypto)
2929
NODE_EXT_LIST_ITEM(node_evals)
3030
NODE_EXT_LIST_ITEM(node_fs)
3131
NODE_EXT_LIST_ITEM(node_http_parser)
32-
#ifdef __POSIX__
33-
NODE_EXT_LIST_ITEM(node_signal_watcher)
34-
#endif
3532
NODE_EXT_LIST_ITEM(node_os)
3633
NODE_EXT_LIST_ITEM(node_zlib)
3734

@@ -44,6 +41,7 @@ NODE_EXT_LIST_ITEM(node_cares_wrap)
4441
NODE_EXT_LIST_ITEM(node_tty_wrap)
4542
NODE_EXT_LIST_ITEM(node_process_wrap)
4643
NODE_EXT_LIST_ITEM(node_fs_event_wrap)
44+
NODE_EXT_LIST_ITEM(node_signal_wrap)
4745

4846
NODE_EXT_LIST_END
4947

src/signal_wrap.cc

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// Copyright Joyent, Inc. and other Node contributors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to permit
8+
// persons to whom the Software is furnished to do so, subject to the
9+
// following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included
12+
// in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
#include "node.h"
23+
#include "handle_wrap.h"
24+
25+
26+
namespace node {
27+
28+
using v8::Object;
29+
using v8::Handle;
30+
using v8::Local;
31+
using v8::Persistent;
32+
using v8::Value;
33+
using v8::HandleScope;
34+
using v8::FunctionTemplate;
35+
using v8::String;
36+
using v8::Function;
37+
using v8::TryCatch;
38+
using v8::Context;
39+
using v8::Arguments;
40+
using v8::Integer;
41+
42+
static Persistent<String> onsignal_sym;
43+
44+
45+
class SignalWrap : public HandleWrap {
46+
public:
47+
static void Initialize(Handle<Object> target) {
48+
HandleScope scope;
49+
50+
HandleWrap::Initialize(target);
51+
52+
Local<FunctionTemplate> constructor = FunctionTemplate::New(New);
53+
constructor->InstanceTemplate()->SetInternalFieldCount(1);
54+
constructor->SetClassName(String::NewSymbol("Signal"));
55+
56+
NODE_SET_PROTOTYPE_METHOD(constructor, "close", HandleWrap::Close);
57+
NODE_SET_PROTOTYPE_METHOD(constructor, "ref", HandleWrap::Ref);
58+
NODE_SET_PROTOTYPE_METHOD(constructor, "unref", HandleWrap::Unref);
59+
NODE_SET_PROTOTYPE_METHOD(constructor, "start", Start);
60+
NODE_SET_PROTOTYPE_METHOD(constructor, "stop", Stop);
61+
62+
onsignal_sym = NODE_PSYMBOL("onsignal");
63+
64+
target->Set(String::NewSymbol("Signal"), constructor->GetFunction());
65+
}
66+
67+
private:
68+
static Handle<Value> New(const Arguments& args) {
69+
// This constructor should not be exposed to public javascript.
70+
// Therefore we assert that we are not trying to call this as a
71+
// normal function.
72+
assert(args.IsConstructCall());
73+
74+
HandleScope scope;
75+
SignalWrap* wrap = new SignalWrap(args.This());
76+
77+
return scope.Close(args.This());
78+
}
79+
80+
SignalWrap(Handle<Object> object)
81+
: HandleWrap(object, reinterpret_cast<uv_handle_t*>(&handle_)) {
82+
int r = uv_signal_init(uv_default_loop(), &handle_);
83+
assert(r == 0);
84+
}
85+
86+
~SignalWrap() {
87+
}
88+
89+
static Handle<Value> Start(const Arguments& args) {
90+
HandleScope scope;
91+
92+
UNWRAP(SignalWrap)
93+
94+
int signum = args[0]->Int32Value();
95+
96+
int r = uv_signal_start(&wrap->handle_, OnSignal, signum);
97+
98+
if (r) SetErrno(uv_last_error(uv_default_loop()));
99+
100+
return scope.Close(Integer::New(r));
101+
}
102+
103+
static Handle<Value> Stop(const Arguments& args) {
104+
HandleScope scope;
105+
106+
UNWRAP(SignalWrap)
107+
108+
int r = uv_signal_stop(&wrap->handle_);
109+
110+
if (r) SetErrno(uv_last_error(uv_default_loop()));
111+
112+
return scope.Close(Integer::New(r));
113+
}
114+
115+
static void OnSignal(uv_signal_t* handle, int signum) {
116+
HandleScope scope;
117+
118+
SignalWrap* wrap = container_of(handle, SignalWrap, handle_);
119+
assert(wrap);
120+
121+
Local<Value> argv[1] = { Integer::New(signum) };
122+
MakeCallback(wrap->object_, onsignal_sym, ARRAY_SIZE(argv), argv);
123+
}
124+
125+
uv_signal_t handle_;
126+
};
127+
128+
129+
} // namespace node
130+
131+
132+
NODE_MODULE(node_signal_wrap, node::SignalWrap::Initialize)

0 commit comments

Comments
 (0)