@@ -14,6 +14,7 @@ type state =
1414 If a function can succeed in a separate domain,
1515 the user's cancel function is responsible for ensuring that this is done atomically. *)
1616type t = {
17+ id : Trace .id ;
1718 mutable state : state ;
1819 children : t Lwt_dllist .t ;
1920 fibers : fiber_context Lwt_dllist .t ;
@@ -89,10 +90,12 @@ let move_fiber_to t fiber =
8990 fiber.cancel_node < - Some new_node
9091
9192(* Note: the new value is not linked into the cancellation tree. *)
92- let create ~protected =
93+ let create ~protected purpose =
9394 let children = Lwt_dllist. create () in
9495 let fibers = Lwt_dllist. create () in
95- { state = Finished ; children; protected; fibers; domain = Domain. self () }
96+ let id = Trace. mint_id () in
97+ Trace. create_cc id purpose;
98+ { id; state = Finished ; children; protected; fibers; domain = Domain. self () }
9699
97100(* Links [t] into the tree as a child of [parent] and returns a function to remove it again. *)
98101let activate t ~parent =
@@ -106,19 +109,19 @@ let activate t ~parent =
106109 Lwt_dllist. remove node
107110
108111(* Runs [fn] with a fresh cancellation context. *)
109- let with_cc ~ctx :fiber ~parent ~protected fn =
112+ let with_cc ~ctx :fiber ~parent ~protected purpose fn =
110113 if not protected then check parent;
111- let t = create ~protected in
114+ let t = create ~protected purpose in
112115 let deactivate = activate t ~parent in
113116 move_fiber_to t fiber;
114117 let cleanup () = move_fiber_to parent fiber; deactivate () in
115118 match fn t with
116- | x -> cleanup () ; x
117- | exception ex -> cleanup () ; raise ex
119+ | x -> cleanup () ; Trace. exit_cc () ; x
120+ | exception ex -> cleanup () ; Trace. error t.id ex; Trace. exit_cc () ; raise ex
118121
119122let protect fn =
120123 let ctx = Effect. perform Get_context in
121- with_cc ~ctx ~parent: ctx.cancel_context ~protected: true @@ fun _ ->
124+ with_cc ~ctx ~parent: ctx.cancel_context ~protected: true Protect @@ fun _ ->
122125 (* Note: there is no need to check the new context after [fn] returns;
123126 the goal of cancellation is only to finish the thread promptly, not to report the error.
124127 We also do not check the parent context, to make sure the caller has a chance to handle the result. *)
@@ -167,18 +170,21 @@ let cancel t ex =
167170 Printexc. raise_with_backtrace ex bt
168171 )
169172
170- let sub fn =
173+ let sub_checked purpose fn =
171174 let ctx = Effect. perform Get_context in
172175 let parent = ctx.cancel_context in
173- with_cc ~ctx ~parent ~protected: false @@ fun t ->
176+ with_cc ~ctx ~parent ~protected: false purpose @@ fun t ->
174177 fn t
175178
179+ let sub fn =
180+ sub_checked Sub fn
181+
176182(* Like [sub], but it's OK if the new context is cancelled.
177183 (instead, return the parent context on exit so the caller can check that) *)
178- let sub_unchecked fn =
184+ let sub_unchecked purpose fn =
179185 let ctx = Effect. perform Get_context in
180186 let parent = ctx.cancel_context in
181- with_cc ~ctx ~parent ~protected: false @@ fun t ->
187+ with_cc ~ctx ~parent ~protected: false purpose @@ fun t ->
182188 fn t;
183189 parent
184190
@@ -198,17 +204,18 @@ module Fiber_context = struct
198204
199205 let make ~cc ~vars =
200206 let tid = Trace. mint_id () in
201- Trace. create tid Fiber ;
207+ Trace. create_fiber tid ~cc: cc.id ;
202208 let t = { tid; cancel_context = cc; cancel_node = None ; cancel_fn = ignore; vars } in
203209 t.cancel_node < - Some (Lwt_dllist. add_r t cc.fibers);
204210 t
205211
206212 let make_root () =
207- let cc = create ~protected: false in
213+ let cc = create ~protected: false Root in
208214 cc.state < - On ;
209215 make ~cc ~vars: Hmap. empty
210216
211217 let destroy t =
218+ Trace. exit_fiber t.tid;
212219 Option. iter Lwt_dllist. remove t.cancel_node
213220
214221 let vars t = t.vars
0 commit comments