From 906ef81f2d67e57cc8a02751bfc4d1b3d5a828b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5ivo=20Leedj=C3=A4rv?= Date: Sun, 31 Mar 2024 14:36:41 +0200 Subject: [PATCH] Fix a recursion to allow tail call elimination The code in question seems to work in some cases (for remote syncs only?) but under some circumstances (local syncs?) it results in plain old recursion which can exhaust the stack. This patch changes the code such that tail call elimination should always work properly. --- src/transport.ml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/transport.ml b/src/transport.ml index 6d0a6e38f..5d3c558fb 100644 --- a/src/transport.ml +++ b/src/transport.ml @@ -58,19 +58,21 @@ let run dispenseTask = let avail = ref limit in let rec runTask thr = Lwt.try_bind thr - (fun () -> nextTask (); Lwt.return ()) - (fun _ -> nextTask (); assert false) + (fun () -> nextTask ()) + (fun _ -> assert false) (* It is a programming error for an exception to reach this far. *) - |> ignore and nextTask () = match dispenseTask () with - | None -> incr avail + | None -> Lwt.return (incr avail) | Some thr -> runTask thr in let rec fillPool () = match dispenseTask () with | None -> () - | Some thr -> decr avail; runTask thr; if !avail > 0 then fillPool () + | Some thr -> + decr avail; + let _ : unit Lwt.t = runTask thr in + if !avail > 0 then fillPool () in fillPool () in