Skip to content

Commit 7710c0b

Browse files
authored
Merge pull request #168 from ocsigen/mem-leaks
Ot_nodeready: do not watch elements forever, to avoid memory leaks
2 parents 56685f7 + ee94921 commit 7710c0b

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

src/widgets/ot_nodeready.eliom

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,30 @@ let rec node_in_document node =
2424
node == (Dom_html.document :> Dom.node Js.t) ||
2525
Js.Opt.case (node##.parentNode) (fun () -> false) node_in_document
2626

27+
let age = ref 0
2728
let watched = ref []
2829

30+
(* We remove watched elements after two unload events to avoid memory
31+
leaks due to elements that are never inserted in the page. *)
32+
let active = ref false
33+
let remove_from_dead_pages () =
34+
let rec loop () =
35+
Eliom_client.onunload @@ fun () ->
36+
let (live, dead) =
37+
List.partition (fun (age', _, _) -> !age = age') !watched in
38+
watched := live;
39+
incr age;
40+
List.iter (fun (_, _, s) -> Lwt.wakeup s ()) dead;
41+
if !watched = [] then
42+
active := false
43+
else
44+
loop ()
45+
in
46+
if not !active then begin
47+
active := true;
48+
loop ()
49+
end
50+
2951
let handler records observer =
3052
let changes = ref false in
3153
for i = 0 to records##.length - 1 do
@@ -34,10 +56,10 @@ let handler records observer =
3456
done;
3557
if !changes then begin
3658
let (ready, not_ready) =
37-
List.partition (fun (n, _) -> node_in_document n) !watched in
59+
List.partition (fun (_, n, _) -> node_in_document n) !watched in
3860
watched := not_ready;
3961
if not_ready = [] then observer##disconnect;
40-
List.iter (fun (_, s) -> Lwt.wakeup s ()) ready
62+
List.iter (fun (_, _, s) -> Lwt.wakeup s ()) ready
4163
end
4264

4365
let observer =
@@ -54,6 +76,7 @@ let nodeready node =
5476
if node_in_document node then Lwt.return_unit else begin
5577
let t, s = Lwt.wait () in
5678
if !watched = [] then observer##observe Dom_html.document config;
57-
watched := (node, s) :: !watched;
79+
watched := (!age, node, s) :: !watched;
80+
remove_from_dead_pages ();
5881
t
5982
end

0 commit comments

Comments
 (0)