lwt
lwt copied to clipboard
Windows Unix.select bug impacts Lwt_engine.select
I had previously run into a bug with Unix.select
on Windows, but I only just reported it: https://caml.inria.fr/mantis/view.php?id=7665
Long story short, when you have a fd set which is a mix of sockets and non-sockets, sometimes some fds are not reported as being ready even though they are totally ready.
Personally, I'm working around this by replacing the engine like so
class windows_select = object
inherit Lwt_engine.select_based
method private select fds_r fds_w timeout =
(* Figure out which fds are already ready to be read *)
let ready_r = List.fold_left (fun ready_r fd_r ->
match Unix.select [fd_r] [] [] 0.0 with
| [], _, _ -> ready_r
| _ -> fd_r::ready_r
) [] fds_r in
(* Figure out which fds are already ready to be written *)
let ready_w = List.fold_left (fun ready_w fd_w ->
match Unix.select [] [fd_w] [] 0.0 with
| _, [], _ -> ready_w
| _ -> fd_w::ready_w
) [] fds_w in
(* If nothing is ready, then do a multi-fd select with the timeout *)
if ready_r = [] && ready_w = []
then
let fds_r, fds_w, _ = Unix.select fds_r fds_w [] timeout in
(fds_r, fds_w)
else (ready_r, ready_w)
end
...
if Sys.win32 then Lwt_engine.set (new windows_select);
Thanks for the link. I understand that this is a bug in OCaml's Unix
library rather than Lwt, but, indeed, it would be nice if Lwt did the right thing anyway :) At least, having this here helps people find a workaround, while we figure out what to do.