1. camlspotter
  2. lwt_cancel_glitch

Overview

HTTPS SSH

A glich of Lwt.cancel

In lwt.2.7.0, it seems that Lwt.cancel cannot cancel the thread itself in which Lwt.cancel is called. The call of Lwt.cancel has no effect. For example, the following code cannot cancel the thread execution:

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

In order to kill the current thread, it seems that we need to call Lwt.cancel from another thread. For example, the following code wraps the call of Lwt.cancel by Lwt.async (fun () -> Lwt.pause () >>= fun () -> ...):

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);
    prerr_endline "cancel called";
    return ());
  pause () >>= fun () ->
  prerr_endline "not dead";
  return ()

let () =
  self := Some s;
  prerr_endline "set";
  Lwt_main.run @@ s