11open Effect
22open Effect.Deep
3+ module Domain_local_await = Kcas. Domain_local_await
34
45type 'a task = unit -> 'a
56
@@ -80,11 +81,36 @@ let async pool f =
8081 Multi_channel. send pd.task_chan (Work (fun _ -> step (do_task f) p));
8182 p
8283
84+ let prepare_for_await chan _mode =
85+ (* Cancellation is not supported, so mode can be ignored. *)
86+ let promise = Atomic. make (Pending [] ) in
87+ let release () =
88+ match Atomic. get promise with
89+ | (Returned _ | Raised _ ) -> ()
90+ | Pending _ ->
91+ match Atomic. exchange promise (Returned () ) with
92+ | Pending ks ->
93+ ks
94+ |> List. iter @@ fun (k , c ) ->
95+ Multi_channel. send_foreign c (Work (fun _ -> continue k () ))
96+ | _ -> ()
97+ and await () =
98+ match Atomic. get promise with
99+ | (Returned _ | Raised _ ) -> ()
100+ | Pending _ -> perform (Wait (promise, chan))
101+ in
102+ Domain_local_await. { release; await }
103+
83104let rec worker task_chan =
84105 match Multi_channel. recv task_chan with
85106 | Quit -> Multi_channel. clear_local_state task_chan
86107 | Work f -> f () ; worker task_chan
87108
109+ let worker task_chan =
110+ Domain_local_await. using
111+ ~prepare_for_await: (prepare_for_await task_chan)
112+ ~while_running: (fun () -> worker task_chan)
113+
88114let run (type a ) pool (f : unit -> a ) : a =
89115 let pd = get_pool_data pool in
90116 let p = Atomic. make (Pending [] ) in
@@ -105,6 +131,11 @@ let run (type a) pool (f : unit -> a) : a =
105131 in
106132 loop ()
107133
134+ let run pool f =
135+ Domain_local_await. using
136+ ~prepare_for_await: (prepare_for_await (get_pool_data pool).task_chan)
137+ ~while_running: (fun () -> run pool f)
138+
108139let named_pools = Hashtbl. create 8
109140let named_pools_mutex = Mutex. create ()
110141
0 commit comments