Skip to content

Commit f4aa151

Browse files
address some TODOs and then make new ones
1 parent 5261258 commit f4aa151

File tree

1 file changed

+27
-15
lines changed

1 file changed

+27
-15
lines changed

src/unix/lwt_unix.cppo.ml

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
22352231
external set_signal : int -> int -> bool -> unit = "lwt_unix_set_signal"
22362232
external remove_signal : int -> bool -> unit = "lwt_unix_remove_signal"
22372233
external init_signals : unit -> unit = "lwt_unix_init_signals"
22382234
external handle_signal : int -> unit = "lwt_unix_handle_signal"
22392235

2236+
let signal_setting_mutex = Mutex.create ()
2237+
22402238
let () = init_signals ()
22412239

22422240
let set_signal signum notification =
@@ -2254,22 +2252,28 @@ type signal_handler = {
22542252

22552253
and 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
22592259
let signal_count () =
22602260
Signal_map.fold
22612261
(fun _signum (_notification, actions) len -> len + Lwt_sequence.length actions)
22622262
!signals
22632263
0
22642264

22652265
let 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

22912296
let 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

23072314
let 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

23172326
external reset_after_fork : unit -> unit = "lwt_unix_reset_after_fork"
23182327

2328+
(* TODO: replace fork with something thread+domain safe *)
23192329
let fork () =
23202330
match Unix.fork () with
23212331
| 0 ->
@@ -2367,7 +2377,6 @@ let do_wait4 flags pid =
23672377
let wait_children = Lwt_sequence.create ()
23682378
let wait_count () = Lwt_sequence.length wait_children
23692379

2370-
(* TODO: what to do about signals? especially sigchld signal? *)
23712380
let sigchld_handler_installed = ref false
23722381

23732382
let 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). *)
23982407
let () =
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

24062418
let _waitpid flags pid =
24072419
Lwt.catch

0 commit comments

Comments
 (0)