@@ -14,7 +14,6 @@ import Data.Foldable (traverse_)
14
14
import Data.Maybe (Maybe(..), fromMaybe)
15
15
import Data.Monoid (guard)
16
16
import Data.Nullable (Nullable, notNull, null, toMaybe, toNullable)
17
- import Data.Posix (Pid)
18
17
import Data.Set (Set)
19
18
import Data.Set as Set
20
19
import Data.Traversable (for)
@@ -23,10 +22,12 @@ import Effect.Exception (try)
23
22
import Effect.Ref (Ref)
24
23
import Effect.Ref as Ref
25
24
import Effect.Uncurried (EffectFn1, EffectFn2, EffectFn3, mkEffectFn1, mkEffectFn2, mkEffectFn3, runEffectFn1, runEffectFn2, runEffectFn3)
26
- import Node.EventEmitter (EventEmitter, EventHandle(..), on, unsafeEmitFn)
25
+ import Node.EventEmitter (EventEmitter, EventHandle(..), listenerCount, on, unsafeEmitFn)
27
26
import Node.EventEmitter as EventEmitter
28
27
import Node.Platform (Platform(..))
28
+ import Node.Process (Process, mkSignalH', process)
29
29
import Node.Process as Process
30
+ import Unsafe.Coerce (unsafeCoerce)
30
31
31
32
foreign import unsafeProcessHasProp :: EffectFn1 String Boolean
32
33
foreign import unsafeReadProcessProp :: forall a. EffectFn1 String a
@@ -36,12 +37,10 @@ foreign import data ProcessEmitFn :: Type
36
37
foreign import data ProcessReallyExitFn :: Type
37
38
foreign import processCallFn :: EffectFn2 ProcessReallyExitFn (Nullable Int) Unit
38
39
39
- foreign import processOn :: forall cb. EffectFn2 String cb Unit
40
- foreign import processOff :: forall cb. EffectFn2 String cb Unit
41
- foreign import processKill :: EffectFn2 Pid String Unit
42
- foreign import processListenersLength :: EffectFn1 String Int
43
40
foreign import customProcessEmit :: EffectFn3 (EffectFn1 ProcessEmitFn Boolean) String (Nullable Int) Boolean -> EffectFn2 String (Nullable Int) Boolean
44
- foreign import processExitCode :: Effect (Nullable Int)
41
+
42
+ processToEventEmitter :: Process -> EventEmitter
43
+ processToEventEmitter = unsafeCoerce
45
44
46
45
isWin :: Boolean
47
46
isWin = Just Win32 == Process.platform
@@ -148,17 +147,17 @@ onExit' cb options = do
148
147
-- for that to occur.
149
148
signalListeners <- for signals \sig -> map hush $ try do
150
149
let listener = mkListener sig countRef
151
- runEffectFn2 processOn sig listener
150
+ rm <- process # on (mkSignalH' sig) listener
152
151
pure $ void $ try do
153
- runEffectFn2 processOff sig listener
152
+ rm
154
153
Ref.write signalListeners signalListenersRef
155
154
runEffectFn2 unsafeWriteProcessProp "emit" processEmitFn
156
155
runEffectFn2 unsafeWriteProcessProp "reallyExit" processReallyExitFn
157
156
158
157
-- Good
159
158
mkListener :: String -> Ref Int -> Effect Unit
160
159
mkListener sig countRef = do
161
- listenersLen <- runEffectFn1 processListenersLength sig
160
+ listenersLen <- listenerCount (processToEventEmitter process) sig
162
161
count <- Ref.read countRef
163
162
when (listenersLen == count) do
164
163
unload
@@ -167,7 +166,7 @@ onExit' cb options = do
167
166
-- "SIGHUP" throws an `ENOSYS` error on Windows,
168
167
-- so use a supported signal instead
169
168
let sig' = if isWin && sig == "SIGHUP" then "SIGINT" else sig
170
- runEffectFn2 processKill Process.pid sig'
169
+ Process.killStr Process.pid sig'
171
170
172
171
processReallyExitFn = mkEffectFn1 \(code :: Nullable Int) -> do
173
172
{ emitter
@@ -183,9 +182,10 @@ onExit' cb options = do
183
182
{ originalProcessEmit } <- getGlobalRecOnProcessObject
184
183
if ev == exitEvent then do
185
184
exitCode <- case toMaybe arg of
186
- Nothing -> processExitCode
185
+ Nothing ->
186
+ map toNullable $ Process.getExitCode
187
187
Just exitCode' -> do
188
- runEffectFn2 unsafeWriteProcessProp exitEvent exitCode'
188
+ Process.setExitCode exitCode'
189
189
pure $ notNull exitCode'
190
190
191
191
ret <- runEffectFn1 runOriginalProcessEmit originalProcessEmit
@@ -266,17 +266,17 @@ getGlobalRecOnProcessObject =
266
266
-- state from which it is not safe to try and enter JS
267
267
-- listeners.
268
268
signals :: Array String
269
- signals = normal <> windows <> linux
269
+ signals = normal <> nonWindows <> linux
270
270
where
271
271
normal =
272
- [ "SIGABRT"
273
- , "SIGALRM"
274
- , "SIGHUP"
272
+ [ "SIGHUP"
275
273
, "SIGINT"
276
274
, "SIGTERM"
277
275
]
278
- windows = guard isWin
279
- [ "SIGVTALRM"
276
+ nonWindows = guard (not isWin)
277
+ [ "SIGABRT"
278
+ , "SIGALRM"
279
+ , "SIGVTALRM"
280
280
, "SIGXCPU"
281
281
, "SIGXFSZ"
282
282
, "SIGUSR2"
@@ -297,5 +297,4 @@ signals = normal <> windows <> linux
297
297
, "SIGPOLL"
298
298
, "SIGPWR"
299
299
, "SIGSTKFLT"
300
- , "SIGUNUSED"
301
300
]
0 commit comments