@@ -2228,15 +2228,13 @@ let init_domain () =
22282228 | Signals |
22292229 +-----------------------------------------------------------------+ *)
22302230
2231- (* TODO: should all notifications for signals be on domain0? or should each
2232- domain be able to install their own signal handler? what domain receives a
2233- signal? *)
2234-
22352231external set_signal : int -> int -> bool -> unit = " lwt_unix_set_signal"
22362232external remove_signal : int -> bool -> unit = " lwt_unix_remove_signal"
22372233external init_signals : unit -> unit = " lwt_unix_init_signals"
22382234external handle_signal : int -> unit = " lwt_unix_handle_signal"
22392235
2236+ let signal_setting_mutex = Mutex. create ()
2237+
22402238let () = init_signals ()
22412239
22422240let set_signal signum notification =
@@ -2254,22 +2252,28 @@ type signal_handler = {
22542252
22552253and signal_handler_id = signal_handler option ref
22562254
2257- (* TODO: make parallel safe *)
2258- let signals : (notification * ((signal_handler_id -> file_perm -> unit) Lwt_sequence.t) ) Signal_map.t ref = ref Signal_map. empty
2255+ let signals
2256+ (* a simple ref, but all access for write are behind a mutex *)
2257+ : (notification * ((signal_handler_id -> file_perm -> unit ) Lwt_sequence. t ) ) Signal_map. t ref
2258+ = ref Signal_map. empty
22592259let signal_count () =
22602260 Signal_map. fold
22612261 (fun _signum (_notification , actions ) len -> len + Lwt_sequence. length actions)
22622262 ! signals
22632263 0
22642264
22652265let on_signal_full signum handler =
2266+ Mutex. lock signal_setting_mutex;
22662267 let id = ref None in
22672268 let _, actions =
22682269 try
22692270 Signal_map. find signum ! signals
22702271 with Not_found ->
22712272 let actions = Lwt_sequence. create () in
22722273 let notification =
2274+ (* TODO: this assumes `on_signal` is called from domain0 where an lwt
2275+ scheduler is running running, should it be possible to set a signal
2276+ handler to execute in a specific domain?? *)
22732277 make_notification
22742278 (fun () ->
22752279 Lwt_sequence. iter_l
@@ -2286,6 +2290,7 @@ let on_signal_full signum handler =
22862290 in
22872291 let node = Lwt_sequence. add_r handler actions in
22882292 id := Some { sh_num = signum; sh_node = node };
2293+ Mutex. unlock signal_setting_mutex;
22892294 id
22902295
22912296let on_signal signum f = on_signal_full signum (fun _notification num -> f num)
@@ -2295,27 +2300,32 @@ let disable_signal_handler id =
22952300 | None ->
22962301 ()
22972302 | Some sh ->
2303+ Mutex. lock signal_setting_mutex;
22982304 id := None ;
22992305 Lwt_sequence. remove sh.sh_node;
23002306 let notification, actions = Signal_map. find sh.sh_num ! signals in
23012307 if Lwt_sequence. is_empty actions then begin
23022308 remove_signal sh.sh_num;
23032309 signals := Signal_map. remove sh.sh_num ! signals;
23042310 stop_notification notification
2305- end
2311+ end ;
2312+ Mutex. unlock signal_setting_mutex
23062313
23072314let reinstall_signal_handler signum =
23082315 match Signal_map. find signum ! signals with
23092316 | exception Not_found -> ()
23102317 | notification , _ ->
2311- set_signal signum notification.id
2318+ Mutex. lock signal_setting_mutex;
2319+ set_signal signum notification.id;
2320+ Mutex. unlock signal_setting_mutex
23122321
23132322(* +-----------------------------------------------------------------+
23142323 | Processes |
23152324 +-----------------------------------------------------------------+ *)
23162325
23172326external reset_after_fork : unit -> unit = " lwt_unix_reset_after_fork"
23182327
2328+ (* TODO: replace fork with something thread+domain safe *)
23192329let fork () =
23202330 match Unix. fork () with
23212331 | 0 ->
@@ -2367,7 +2377,6 @@ let do_wait4 flags pid =
23672377let wait_children = Lwt_sequence. create ()
23682378let wait_count () = Lwt_sequence. length wait_children
23692379
2370- (* TODO: what to do about signals? especially sigchld signal? *)
23712380let sigchld_handler_installed = ref false
23722381
23732382let install_sigchld_handler () =
@@ -2396,12 +2405,15 @@ let install_sigchld_handler () =
23962405 install the SIGCHLD handler, in order to cause any EINTR-unsafe code to
23972406 fail (as it should). *)
23982407let () =
2399- (* TODO: figure out what to do about signals *)
2400- (* TODO: this interferes with tests because it leaves a pause hanging? *)
2401- if (Domain. self () :> int ) = 0 then
2402- Lwt. async (fun () ->
2403- Lwt. pause () > |= fun () ->
2404- install_sigchld_handler () )
2408+ (* TODO: this assumes that an Lwt main loop will be started in domain0 (where
2409+ this value is allocated bc top-level initialisation), instead
2410+ [install_sigchld_handler] should be called when the first lwt-scheduler is
2411+ started which could be in a non-zero domain
2412+
2413+ or TODO: remove sigchld handler if fork is completely abandonned?? *)
2414+ Lwt. async (fun () ->
2415+ Lwt. pause () > |= fun () ->
2416+ install_sigchld_handler () )
24052417
24062418let _waitpid flags pid =
24072419 Lwt. catch
0 commit comments