Skip to content

Commit 4da71f3

Browse files
committed
The Fiber.current () operation must never propagate cancelation
The problem is that in order to call `Fiber.forbid fiber (fun () -> ...)` to forbid cancelation, it is necessary to call `Fiber.current ()` to obtain the `fiber`. Hence `Fiber.current ()` must not propagate cancelation. In some cases one could call `Fiber.current ()` well before performing the work that needs to be protected by `Fiber.forbid ...`, but this is not always practical.
1 parent 3cba8bd commit 4da71f3

File tree

4 files changed

+23
-11
lines changed

4 files changed

+23
-11
lines changed

lib/picos/intf.ocaml5.ml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ module type Fiber = sig
8686
(** Schedulers may handle the {!Current} effect to customize the behavior of
8787
[current].
8888
89-
A handler should eventually either continue the fiber or discontinue it in
90-
case the fiber permits propagation of cancelation and the associated
91-
computation has been canceled.
89+
⚠️ A handler should eventually resume the fiber without propagating
90+
cancelation. A scheduler may, of course, decide to reschedule the current
91+
fiber to be resumed later.
9292
93-
Note that in typical use cases of [current] it makes sense to give
93+
Note that in typical use cases of {!current} it makes sense to give
9494
priority to the fiber performing {!Current}, but this is not required. *)
9595
type _ Effect.t += private Current : t Effect.t
9696

lib/picos/picos.mli

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
{{!Fiber.permit} permit} the scheduler from propagating cancelation to it.
9696
This is important for the implementation of some key concurrent abstractions
9797
such as condition variables, where it is necessary to forbid cancelation
98-
when the associated mutex is re-acquired.
98+
when the associated mutex is reacquired.
9999
100100
Each fiber has an associated {!Computation}. A computation is something
101101
that needs to be completed either by {{!Computation.return} returning} a
@@ -814,7 +814,7 @@ module Fiber : sig
814814
(** {2 Interface for rescheduling} *)
815815

816816
val yield : unit -> unit
817-
(** [yield ()] asks the current fiber to be re-scheduled.
817+
(** [yield ()] asks the current fiber to be rescheduled.
818818
819819
ℹ️ The behavior is that
820820
@@ -867,7 +867,11 @@ module Fiber : sig
867867
868868
- on OCaml 5, [current] performs the {!Current} effect, and
869869
- on OCaml 4, [current] will call the [current] operation of the
870-
{{!Handler} current handler}. *)
870+
{{!Handler} current handler}.
871+
872+
⚠️ The [current] operation must always resume the fiber without propagating
873+
cancelation. A scheduler may, of course, decide to reschedule the current
874+
fiber to be resumed later. *)
871875

872876
val has_forbidden : t -> bool
873877
(** [has_forbidden fiber] determines whether the fiber {!forbid}s or
@@ -889,7 +893,7 @@ module Fiber : sig
889893
abstractions that may have to {{!Trigger.await} await} for something, or
890894
may need to perform other effects, and must not be canceled while doing
891895
so. For example, the wait operation on a condition variable typically
892-
re-acquires the associated mutex before returning, which may require
896+
reacquires the associated mutex before returning, which may require
893897
awaiting for the owner of the mutex to release it.
894898
895899
ℹ️ [forbid] does not prevent the fiber or the associated {!computation}

lib/picos_fifos/picos_fifos.ml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,13 @@ type t = {
2525
let rec next t =
2626
match Queue.pop_exn t.ready with
2727
| Spawn (fiber, main) ->
28-
let current = Some (fun k -> Fiber.continue fiber k fiber)
28+
let current =
29+
Some
30+
(fun k ->
31+
(* The current handler must never propagate cancelation, but it
32+
would be possible to continue some other fiber and resume the
33+
current fiber later. *)
34+
Effect.Deep.continue k fiber)
2935
and yield =
3036
Some
3137
(fun k ->

lib/picos_threaded/picos_threaded.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,13 @@ let[@alert "-handler"] rec await fiber trigger =
7272
end
7373

7474
and current fiber =
75-
(* In each handler we need to account for cancelation. *)
76-
Fiber.check fiber;
75+
(* The current handler must never propagate cancelation, but it would be
76+
possible to yield here to run some other fiber before resuming the current
77+
fiber. *)
7778
fiber
7879

7980
and yield fiber =
81+
(* In other handlers we need to account for cancelation. *)
8082
Fiber.check fiber;
8183
Systhreads.yield ()
8284

0 commit comments

Comments
 (0)