(proc, { forceKillTimeoutMs = DEFAULT_FORCE_KILL_TIMEOUT_MS } = {})
| 84 | } |
| 85 | |
| 86 | async function terminateProcess(proc, { forceKillTimeoutMs = DEFAULT_FORCE_KILL_TIMEOUT_MS } = {}) { |
| 87 | if (!proc) return |
| 88 | |
| 89 | if (proc.exitCode !== null || proc.signalCode !== null) { |
| 90 | return |
| 91 | } |
| 92 | |
| 93 | await new Promise((resolve) => { |
| 94 | let resolved = false |
| 95 | let forceKillTimer = null |
| 96 | |
| 97 | const exitHandler = () => { |
| 98 | if (!resolved) { |
| 99 | resolved = true |
| 100 | if (forceKillTimer) clearTimeout(forceKillTimer) |
| 101 | resolve() |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | proc.once('exit', exitHandler) |
| 106 | proc.kill('SIGTERM') |
| 107 | |
| 108 | forceKillTimer = setTimeout(() => { |
| 109 | if (!resolved) { |
| 110 | try { |
| 111 | proc.kill(0) |
| 112 | proc.kill('SIGKILL') |
| 113 | } catch { |
| 114 | // process already exited |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | if (!resolved) { |
| 119 | resolved = true |
| 120 | resolve() |
| 121 | } |
| 122 | }, forceKillTimeoutMs) |
| 123 | }) |
| 124 | } |
| 125 | |
| 126 | function releaseReservation(reservationServer) { |
| 127 | safeCloseServer(reservationServer) |
no test coverage detected