A Glitch of Lwt.cancel
Lwt.cancel cannot cancel the thread in which itself is running in lwt.2.7.0. The following code demostrates what I mean:
(* ocamlfind ocamlopt -linkpkg -package lwt,lwt.unix x.ml *)
open Lwt
module Test1 = struct
let self = ref None
let from_some = function
| Some x -> x
| None -> assert false
let s =
pause () >>= fun () ->
cancel (from_some !self);
prerr_endline "cancel called";
pause () >>= fun () ->
prerr_endline "direct cancel cannot cancel itself";
return ()
let () =
self := Some s;
prerr_endline "set";
Lwt_main.run @@ s
end
module Test2 = struct
let self = ref None
let from_some = function
| Some x -> x
| None -> assert false
let s =
pause () >>= fun () ->
async (fun () ->
pause () >>= fun () ->
cancel (from_some !self); (* should give an exception Canceled *)
prerr_endline "cancel called";
return ());
pause () >>= fun () ->
prerr_endline "not dead";
return ()
let () =
self := Some s;
prerr_endline "set";
Lwt_main.run @@ s
end
TEST1 cannot cancel itself: cancel has no effect. TEST2, however, can. Only the difference is the existence of async and pause:
async (fun () -> pause () >>= fun () -> cancel <self>)
I do not fully understand why this difference we have, but the key seems to be call Lwt.cancel from another thread.
The updated code is found at: https://bitbucket.org/camlspotter/lwt_cancel_glitch