Compare commits

..

No commits in common. "9537ca1810686b7ba185ff96a496ce4f24029a36" and "bc1e231b64a69af5226d998d3286d235b61b0f5f" have entirely different histories.

5 changed files with 15 additions and 10 deletions

View File

@ -76,10 +76,10 @@ They are run against whichever backend `Eio_main.run` selects, and therefore mus
`lib_eio/tests` tests some internal data structures, such as the lock-free cells abstraction.
The `.md` files in that directory provide a simple walk-through to demonstrate the basic operation,
while `lib_eio/tests/dscheck` uses [dscheck][] to perform exhaustive testing of all atomic interleavings.
while `lib_eio/tests/dscheck` uses [dscheck][] to perform exhaustive testing of all atomic interleavings
At the time of writing, dscheck has some performance problems that make it unusable by default, so
you must use the version in https://github.com/ocaml-multicore/dscheck/pull/22 instead.
you must use the version in https://github.com/ocaml-multicore/dscheck/pull/3 instead.
### Benchmarks

View File

@ -1,4 +1,5 @@
exception Cancelled = Exn.Cancelled
exception Cancel_hook_failed = Exn.Cancel_hook_failed
type state =
| On
@ -155,16 +156,12 @@ let cancel t ex =
x.cancel_fn <- ignore;
match fn cex with
| () -> aux xs
| exception ex2 ->
let bt = Printexc.get_raw_backtrace () in
(ex2, bt) :: aux xs
| exception ex2 -> ex2 :: aux xs
in
if fibers <> [] then (
match aux fibers with
| [] -> ()
| ex :: exs ->
let ex, bt = List.fold_left Exn.combine ex exs in
Printexc.raise_with_backtrace ex bt
| exns -> raise (Cancel_hook_failed exns)
)
let sub fn =

View File

@ -526,6 +526,9 @@ module Cancel : sig
The nested exception is only intended for debug-level logging and should generally be ignored. *)
exception Cancel_hook_failed of exn list
(** Raised by {!cancel} if any of the cancellation hooks themselves fail. *)
val sub : (t -> 'a) -> 'a
(** [sub fn] installs a new cancellation context [t], runs [fn t] inside it, and then restores the old context.
@ -558,7 +561,9 @@ module Cancel : sig
If [t] is already cancelled then this does nothing.
Note that the caller of this function is still responsible for handling the error somehow
(e.g. reporting it to the user); it does not become the responsibility of the cancelled thread(s). *)
(e.g. reporting it to the user); it does not become the responsibility of the cancelled thread(s).
@raise Cancel_hook_failed if one or more hooks fail. *)
val dump : t Fmt.t
(** Show the cancellation sub-tree rooted at [t], for debugging. *)

View File

@ -16,6 +16,8 @@ type err += Multiple_io of (err * context * Printexc.raw_backtrace) list
exception Cancelled of exn
exception Cancel_hook_failed of exn list
let create err = Io (err, { steps = [] })
let add_context ex fmt =
@ -88,6 +90,7 @@ let () =
Printexc.register_printer @@ function
| Io _ as ex -> Some (Fmt.str "@[<v>%a@]" pp ex)
| Multiple exns -> Some (Fmt.str "%a" pp_multiple exns)
| Cancel_hook_failed exns -> Some ("During cancellation:\n" ^ String.concat "\nand\n" (List.map Printexc.to_string exns))
| Cancelled ex -> Some ("Cancelled: " ^ Printexc.to_string ex)
| _ -> None

View File

@ -55,7 +55,7 @@ let fail ?(bt=Printexc.get_raw_backtrace ()) t ex =
t.exs <- Some (combine_exn (ex, bt) t.exs);
try
Cancel.cancel t.cancel ex
with ex ->
with Exn.Cancel_hook_failed _ as ex ->
let bt = Printexc.get_raw_backtrace () in
t.exs <- Some (combine_exn (ex, bt) t.exs)