@@ -24,6 +24,7 @@ module Make (Data : Binable.S) = struct
2424 (* * A list of ids that are no longer reachable from OCaml runtime, but
2525 haven't been cleared inside the LMDB disk cache *)
2626 ; queue_guard : Error_checking_mutex .t
27+ ; gc_freezed : bool ref
2728 }
2829
2930 (* * How big can the queue [reusable_keys] be before we do a cleanup *)
@@ -38,15 +39,16 @@ module Make (Data : Binable.S) = struct
3839 ; counter = ref 0
3940 ; reusable_keys = Queue. create ()
4041 ; queue_guard = Error_checking_mutex. create ()
42+ ; gc_freezed = ref false
4143 } )
4244
4345 type id = { idx : int }
4446
4547 let get ({ env; db; _ } : t ) ({ idx } : id ) : Data.t =
4648 Rw. get ~env db idx |> Option. value_exn
4749
48- let put ({ env; db; counter; reusable_keys; queue_guard } : t ) ( x : Data.t ) :
49- id =
50+ let put ({ env; db; counter; reusable_keys; queue_guard; gc_freezed } : t )
51+ ( x : Data.t ) : id =
5052 let idx =
5153 match
5254 Error_checking_mutex. critical_section queue_guard ~f: (fun () ->
@@ -63,12 +65,13 @@ module Make (Data : Binable.S) = struct
6365 let res = { idx } in
6466 (* When this reference is GC'd, delete the file. *)
6567 Gc.Expert. add_finalizer_last_exn res (fun () ->
66- (* The actual deletion is delayed, as GC maybe triggered in LMDB's
67- critical section. LMDB critical section then will be re-entered if
68- it's invoked directly in a GC hook.
69- This causes mutex double-acquiring and node freezes. *)
70- Error_checking_mutex. critical_section queue_guard ~f: (fun () ->
71- Queue. enqueue reusable_keys idx ) ) ;
68+ if not ! gc_freezed then
69+ (* The actual deletion is delayed, as GC maybe triggered in LMDB's
70+ critical section. LMDB critical section then will be re-entered if
71+ it's invoked directly in a GC hook.
72+ This causes mutex double-acquiring and node freezes. *)
73+ Error_checking_mutex. critical_section queue_guard ~f: (fun () ->
74+ Queue. enqueue reusable_keys idx ) ) ;
7275
7376 Error_checking_mutex. critical_section queue_guard ~f: (fun () ->
7477 if Queue. length reusable_keys > = reuse_size_limit then (
@@ -77,6 +80,8 @@ module Make (Data : Binable.S) = struct
7780 Rw. set ~env db idx x ;
7881 res
7982
83+ let freeze_gc ({ gc_freezed; _ } : t ) = gc_freezed := true
84+
8085 let iteri ({ env; db; _ } : t ) ~f = Rw. iter ~env db ~f
8186
8287 let count ({ env; db; _ } : t ) =
0 commit comments