Skip to content

Commit 16cac51

Browse files
committed
src: make start of signal_wrap reenterable
1 parent 639c096 commit 16cac51

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

src/signal_wrap.cc

+6-1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ class SignalWrap : public HandleWrap {
118118
}
119119
}
120120
#endif
121+
// Save the old signum
122+
int old_signum = wrap->handle_.signum;
121123
int err = uv_signal_start(
122124
&wrap->handle_,
123125
[](uv_signal_t* handle, int signum) {
@@ -131,7 +133,10 @@ class SignalWrap : public HandleWrap {
131133
signum);
132134

133135
if (err == 0) {
134-
CHECK(!wrap->active_);
136+
// Subtract 1 if previously registered
137+
if (wrap->active_) {
138+
DecreaseSignalHandlerCount(old_signum);
139+
}
135140
wrap->active_ = true;
136141
Mutex::ScopedLock lock(handled_signals_mutex);
137142
handled_signals[signum]++;

test/parallel/test-signal-reuse.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Flags: --expose-internals
2+
'use strict';
3+
const common = require('../common');
4+
const { internalBinding } = require('internal/test/binding');
5+
const { signals } = internalBinding('constants').os;
6+
const Signal = internalBinding('signal_wrap').Signal;
7+
8+
common.skipIfWorker();
9+
10+
const signal = new Signal();
11+
signal.start(signals.SIGUSR2);
12+
signal.onsignal = common.mustCall(() => {
13+
process.nextTick(common.mustCall(() => {
14+
signal.start(signals.SIGINT);
15+
signal.onsignal = common.mustCall(() => {
16+
signal.close();
17+
});
18+
process.kill(0, signals.SIGINT);
19+
}));
20+
});
21+
process.kill(0, signals.SIGUSR2);

0 commit comments

Comments
 (0)