• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1const runningProcs = new Set()
2let handlersInstalled = false
3
4// NOTE: these signals aren't actually forwarded anywhere. they're trapped and
5// ignored until all child processes have exited. in our next breaking change
6// we should rename this
7const forwardedSignals = [
8  'SIGINT',
9  'SIGTERM',
10]
11
12// no-op, this is so receiving the signal doesn't cause us to exit immediately
13// instead, we exit after all children have exited when we re-send the signal
14// to ourselves. see the catch handler at the bottom of run-script-pkg.js
15// istanbul ignore next - this function does nothing
16const handleSignal = () => {}
17const setupListeners = () => {
18  for (const signal of forwardedSignals) {
19    process.on(signal, handleSignal)
20  }
21  handlersInstalled = true
22}
23
24const cleanupListeners = () => {
25  if (runningProcs.size === 0) {
26    for (const signal of forwardedSignals) {
27      process.removeListener(signal, handleSignal)
28    }
29    handlersInstalled = false
30  }
31}
32
33const add = proc => {
34  runningProcs.add(proc)
35  if (!handlersInstalled) {
36    setupListeners()
37  }
38
39  proc.once('exit', () => {
40    runningProcs.delete(proc)
41    cleanupListeners()
42  })
43}
44
45module.exports = {
46  add,
47  handleSignal,
48  forwardedSignals,
49}
50