0 | module IO.Async.Loop.SignalST
2 | import Data.Linear.Ref1
3 | import Data.Linear.Traverse1
4 | import Data.SortedMap
6 | import System.Posix.Signal.Prim
11 | SigMap = SortedMap Signal (List (Nat, Siginfo -> IO1 ()))
13 | record SignalST where
19 | await_ : IORef SignalST -> List Signal -> (Siginfo -> IO1 ()) -> IO1 Nat
20 | await_ r sigs act t =
21 | let SST id m # t := read1 r t
22 | _ # t := write1 r (SST (S id) (go id sigs m)) t
25 | go : Nat -> List Signal -> SigMap -> SigMap
29 | Nothing => go id ss $
insert s [(id,act)] m
30 | Just ps => go id ss $
insert s ((id,act)::ps) m
32 | drop_ : List Signal -> Nat -> SignalST -> SignalST
34 | drop_ (s::ss) x (SST id m) =
36 | Nothing => drop_ ss x (SST id m)
37 | Just vs => case filter ((x /=) . fst) vs of
38 | [] => drop_ ss x $
(SST id $
delete s m)
39 | ws => drop_ ss x $
(SST id $
insert s ws m)
41 | dropRef : IORef SignalST -> List Signal -> Nat -> IO1 ()
42 | dropRef r ss n t = let st # t := read1 r t in write1 r (drop_ ss n st) t
45 | hasHandle : SignalST -> Signal -> Bool
47 | case lookup sig s.map of
56 | record Sighandler where
58 | ref : IORef SignalST
61 | sighandler : IO1 Sighandler
63 | let st # t := ref1 (SST 0 empty) t
66 | parameters (si : Sighandler)
73 | await : List Signal -> (Siginfo -> IO1 ()) -> IO1 (IO1 ())
75 | let ix # t := await_ si.ref sigs act t
76 | in dropRef si.ref sigs ix # t
81 | checkSignals : IO1 ()
83 | let st # t := read1 si.ref t
84 | in case null st.map of
86 | False => case toF1 sigpending t of
88 | ss # t => case filter (hasHandle st) ss of
90 | ss => case sigwaitinfo {es = [Errno]} ss t of
92 | R inf t => case lookup inf.signal st.map of
95 | let _ # t := write1 si.ref ({map $= delete inf.signal} st) t
96 | in traverse1_ (\h => snd h inf) hs t