Skip to content

Commit 5014802

Browse files
Jonas Pfennigerry
authored andcommitted
Thinner SignalWatcher, only using callback
Since it is only used internally, we don't need the complexity of EventEmitter. The new SignalWatcher's design was copied from IdleWatcher.
1 parent 9599607 commit 5014802

3 files changed

Lines changed: 62 additions & 32 deletions

File tree

src/node.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,10 @@ process.addListener("newListener", function (event) {
7474
if (isSignal(event) && process.listeners(event).length === 0) {
7575
var b = process.binding('signal_watcher');
7676
var w = new b.SignalWatcher(process[event]);
77-
w.addListener("signal", function () {
77+
w.callback = function () {
7878
process.emit(event);
79-
});
79+
};
80+
w.start();
8081
}
8182
});
8283

src/node_signal_watcher.cc

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,46 @@ namespace node {
77
using namespace v8;
88

99
Persistent<FunctionTemplate> SignalWatcher::constructor_template;
10-
static Persistent<String> signal_symbol;
10+
static Persistent<String> callback_symbol;
1111

1212
void SignalWatcher::Initialize(Handle<Object> target) {
1313
HandleScope scope;
1414

1515
Local<FunctionTemplate> t = FunctionTemplate::New(SignalWatcher::New);
1616
constructor_template = Persistent<FunctionTemplate>::New(t);
17-
constructor_template->Inherit(EventEmitter::constructor_template);
1817
constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
1918
constructor_template->SetClassName(String::NewSymbol("SignalWatcher"));
2019

20+
NODE_SET_PROTOTYPE_METHOD(constructor_template, "start", SignalWatcher::Start);
2121
NODE_SET_PROTOTYPE_METHOD(constructor_template, "stop", SignalWatcher::Stop);
2222

23-
signal_symbol = NODE_PSYMBOL("signal");
24-
2523
target->Set(String::NewSymbol("SignalWatcher"),
2624
constructor_template->GetFunction());
25+
26+
callback_symbol = NODE_PSYMBOL("callback");
2727
}
2828

29-
void SignalWatcher::OnSignal(EV_P_ ev_signal *watcher, int revents) {
29+
void SignalWatcher::Callback(EV_P_ ev_signal *watcher, int revents) {
3030
SignalWatcher *w = static_cast<SignalWatcher*>(watcher->data);
31+
32+
assert(watcher == &w->watcher_);
33+
3134
HandleScope scope;
3235

33-
assert(revents == EV_SIGNAL);
36+
Local<Value> callback_v = w->handle_->Get(callback_symbol);
37+
if (!callback_v->IsFunction()) {
38+
w->Stop();
39+
return;
40+
}
3441

35-
w->Emit(signal_symbol, 0, NULL);
36-
}
42+
Local<Function> callback = Local<Function>::Cast(callback_v);
3743

38-
SignalWatcher::~SignalWatcher() {
39-
if (watcher_.active) {
40-
ev_ref(EV_DEFAULT_UC);
41-
ev_signal_stop(EV_DEFAULT_UC_ &watcher_);
44+
TryCatch try_catch;
45+
46+
callback->Call(w->handle_, 0, NULL);
47+
48+
if (try_catch.HasCaught()) {
49+
FatalException(try_catch);
4250
}
4351
}
4452

@@ -51,30 +59,40 @@ Handle<Value> SignalWatcher::New(const Arguments& args) {
5159

5260
int sig = args[0]->Int32Value();
5361

54-
SignalWatcher *w = new SignalWatcher();
62+
SignalWatcher *w = new SignalWatcher(sig);
5563
w->Wrap(args.Holder());
5664

57-
ev_signal_init(&w->watcher_, SignalWatcher::OnSignal, sig);
58-
w->watcher_.data = w;
59-
// Give signal handlers very high priority. The only thing that has higher
60-
// priority is the garbage collector check.
61-
ev_set_priority(&w->watcher_, EV_MAXPRI-1);
62-
ev_signal_start(EV_DEFAULT_UC_ &w->watcher_);
63-
ev_unref(EV_DEFAULT_UC);
65+
return args.This();
66+
}
6467

65-
w->Ref();
68+
Handle<Value> SignalWatcher::Start(const Arguments& args) {
69+
HandleScope scope;
70+
SignalWatcher *w = ObjectWrap::Unwrap<SignalWatcher>(args.Holder());
71+
w->Start();
72+
return Undefined();
73+
}
6674

67-
return args.This();
75+
void SignalWatcher::Start () {
76+
if (!watcher_.active) {
77+
ev_signal_start(EV_DEFAULT_UC_ &watcher_);
78+
ev_unref(EV_DEFAULT_UC);
79+
Ref();
80+
}
6881
}
6982

7083
Handle<Value> SignalWatcher::Stop(const Arguments& args) {
7184
HandleScope scope;
72-
7385
SignalWatcher *w = ObjectWrap::Unwrap<SignalWatcher>(args.Holder());
74-
ev_ref(EV_DEFAULT_UC);
75-
ev_signal_stop(EV_DEFAULT_UC_ &w->watcher_);
76-
w->Unref();
86+
w->Stop();
7787
return Undefined();
7888
}
7989

90+
void SignalWatcher::Stop () {
91+
if (watcher_.active) {
92+
ev_ref(EV_DEFAULT_UC);
93+
ev_signal_stop(EV_DEFAULT_UC_ &watcher_);
94+
Unref();
95+
}
96+
}
97+
8098
} // namespace node

src/node_signal_watcher.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,32 @@
1010

1111
namespace node {
1212

13-
class SignalWatcher : EventEmitter {
13+
class SignalWatcher : ObjectWrap {
1414
public:
1515
static void Initialize(v8::Handle<v8::Object> target);
1616

1717
protected:
1818
static v8::Persistent<v8::FunctionTemplate> constructor_template;
1919

20-
SignalWatcher() : EventEmitter() { }
21-
~SignalWatcher();
20+
SignalWatcher(int sig) : ObjectWrap() {
21+
ev_signal_init(&watcher_, SignalWatcher::Callback, sig);
22+
watcher_.data = this;
23+
}
24+
25+
~SignalWatcher() {
26+
ev_signal_stop(EV_DEFAULT_UC_ &watcher_);
27+
}
2228

2329
static v8::Handle<v8::Value> New(const v8::Arguments& args);
30+
static v8::Handle<v8::Value> Start(const v8::Arguments& args);
2431
static v8::Handle<v8::Value> Stop(const v8::Arguments& args);
2532

2633
private:
27-
static void OnSignal(EV_P_ ev_signal *watcher, int revents);
34+
static void Callback(EV_P_ ev_signal *watcher, int revents);
35+
36+
void Start();
37+
void Stop();
38+
2839
ev_signal watcher_;
2940
};
3041

0 commit comments

Comments
 (0)