0 | module IO.Async.Loop.Sync
2 | import Data.Linear.Traverse1
4 | import Data.SortedMap
5 | import public IO.Async.Loop
6 | import IO.Async.Loop.TimerH
7 | import IO.Async.Loop.TimerST
8 | import IO.Async.Internal.Ref
23 | queue : IORef (SnocList $
FbrState SyncST)
24 | running : IORef Bool
28 | primWait s dur f = schedule s.timer dur f
35 | spawnImpl : SyncST -> FbrState SyncST -> IO1 ()
37 | export %inline covering
38 | EventLoop SyncST where
43 | checkTimers, checkQueue : SyncST -> IO1 ()
48 | run : SyncST -> List (FbrState SyncST) -> IO1 ()
49 | run s [] t = checkTimers s t
51 | case runFbr s x t of
52 | Cont fst # t => let _ # t := mod1 s.queue (:< fst) t in run s xs t
53 | Done # t => run s xs t
58 | let sa # t := read1 s.queue t
59 | _ # t := write1 s.queue [<] t
60 | in case sa <>> [] of
64 | doSleep : Integer -> IO1 ()
66 | let v := cast {to = Int} (n `div` 1000)
67 | in case choose (v >= 0) of
68 | Left x => ioToF1 (usleep v) t
73 | case runDueTimers s.timer t of
74 | 0 # t => checkQueue s t
75 | n # t => case read1 s.queue t of
76 | [<] # t => let _ # t := doSleep n t in checkTimers s t
77 | _ # t => checkQueue s t
80 | let _ # t := mod1 s.queue (:< pkg) t
81 | False # t := read1 s.running t | _ # t => () # t
82 | _ # t := write1 s.running True t
92 | sync = [| SST (runIO timer) (newref [<]) (newref False) |]