Define callback function (int -> int -> unit) that can pause lwt thread it is called from?

apologies if this is a common question or indeed impossible,

I am using some library code that runs a big computation as an 'a Lwt.t promise, the library code calls out to a user-defined callback function : int → int → unit (I’ve simplified here but key point is that it returns unit), I want to pause that same 'a Lwt.t when that callback is invoked and for the Ui to unpause it.

Here is a simplified example (I know that using read_line blocks everything but it almost illustrates what I am after): :

(* this Worker module would be library code, ie I cant edit it *)
(* but I can implement my own pauser.stop function *)
module Worker = struct

  type pauser = {
    stop: int -> int -> unit;
  }

  let long_running_lwt n pauser =
    let rec aux i () =
      match i with
      | 0 -> Lwt.return_unit
      | _ ->
        (* the library calls out to the callback and then does some work *)
        let _ = pauser.stop i n in
        (Lwt_unix.sleep 0.2) >>=
        aux (i-1)
    in
    aux n

end

(* this Ui module is my code, am free to write whatever *)
module Ui = struct

  let ui_thread n =
    let rec aux i () =
      match i with
      | 0 -> Lwt.return_unit
      | _ ->
        Lwt_io.printlf "ui thread doing stuff %d/%d" (n-i+1) n >>=
        (fun _ -> Lwt_io.(flush stdout)) >>=
        (fun _ -> Lwt_unix.sleep 1.1) >>=
        aux (i-1)
    in
    aux n

end

(* likewise I'm free to write my own pauser callback *)
let p : Worker.pauser = {
  stop=fun i n ->
    print_endline @@ Printf.sprintf "hello from pauser %d/%d\n" (n-i+1) n;
    let ch = read_line () in (* this line blocks everything, want to only block worker thread until Ui unpauses*)
    print_endline @@ Printf.sprintf "echo: %s" ch;
}

let () =
  let w = Worker.long_running_lwt 5 p () in
  let ui = Ui.ui_thread 10 () in
  Lwt_main.run @@ (Lwt.join [w; ui])