0 | ||| Mutable references exposed in `PrimIO`. This includes the ability
 1 | ||| to mutate via a CAS-loop to avoid locking with a mutex in certain
 2 | ||| occasions.
 3 | module IO.Async.Internal.Ref
 4 |
 5 | import Data.Array
 6 | import Data.Array.Mutable
 7 | import Data.Queue
 8 | import public IO.Async.Loop
 9 |
10 | %default total
11 |
12 | ||| Guaranteed to run the given cleanup function exactly once:
13 | ||| The boolean flag is atomically read and set to false before running the
14 | ||| cleanup hook, and `act` is only run if the flag has been `True`.
15 | export
16 | once : (r : IORef Bool) -> (act : IO1 ()) -> IO1 ()
17 | once r act t =
18 |   assert_total $ case read1 r t of
19 |     True # t => case caswrite1 r True False t of
20 |       True # t => act t
21 |       _    # t => once r act t
22 |     _ # t => () # t
23 |