forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
process: add one-shot signal handler support
`one-shot` signal handlers reset the handler once the signal is received and not when the signal notification reaches the main loop. This commit adds support for this functionality when *only* there are `once` listeners on a specific signal. Refs: nodejs#9050 Refs: libuv/libuv#1104 Refs: libuv/libuv#1106
- Loading branch information
1 parent
52f6ab8
commit e403bae
Showing
3 changed files
with
121 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
const assert = require('assert'); | ||
const spawn = require('child_process').spawn; | ||
|
||
if (common.isWindows) | ||
common.skip('Sending signals is not supported'); | ||
|
||
if (process.argv[2] === 'child') { | ||
if (process.argv[3] === 'once') { | ||
const on_sigint = () => {}; | ||
process.on('SIGINT', on_sigint); | ||
process.once('SIGINT', () => {}); | ||
process.removeListener('SIGINT', on_sigint); | ||
process.once('message', common.mustCall((msg) => { | ||
assert.strictEqual(msg, 'signal'); | ||
process.send('signal'); | ||
while (true) {} | ||
})); | ||
} else if (process.argv[3] === 'on') { | ||
let signals = 0; | ||
process.once('SIGINT', common.mustCall(() => { | ||
process.send('signal'); | ||
})); | ||
|
||
process.on('SIGINT', common.mustCall(() => { | ||
if (++signals === 2) | ||
process.exit(0); | ||
}, 2)); | ||
} | ||
|
||
process.send('signal'); | ||
setTimeout(() => {}, 100000); | ||
|
||
return; | ||
} | ||
|
||
{ | ||
const child = spawn(process.execPath, [__filename, 'child', 'once'], { | ||
stdio: ['pipe', 'pipe', 'pipe', 'ipc'] | ||
}); | ||
|
||
child.on('exit', common.mustCall((code, signal) => { | ||
assert.strictEqual(code, null); | ||
assert.strictEqual(signal, 'SIGINT'); | ||
})); | ||
|
||
child.on('message', (msg) => { | ||
assert.strictEqual(msg, 'signal'); | ||
child.kill('SIGINT'); | ||
child.send('signal'); | ||
}); | ||
} | ||
|
||
{ | ||
const child = spawn(process.execPath, [__filename, 'child', 'on'], { | ||
stdio: ['pipe', 'pipe', 'pipe', 'ipc'] | ||
}); | ||
|
||
child.on('exit', common.mustCall((code, signal) => { | ||
assert.strictEqual(code, 0); | ||
assert.strictEqual(signal, null); | ||
})); | ||
|
||
child.on('message', (msg) => { | ||
assert.strictEqual(msg, 'signal'); | ||
child.kill('SIGINT'); | ||
}); | ||
} |