Skip to content

Commit 68eb5f9

Browse files
committed
Clarify the internal intr_pending counter increment
1 parent 4e905e0 commit 68eb5f9

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

lib/picos_select/picos_select.ml

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -326,23 +326,26 @@ module Intr = struct
326326

327327
let intr_key =
328328
Picos_tls.new_key @@ fun () : [ `Req ] tdt ->
329-
Req { state = get (); unused = true; computation = cleared }
329+
Req { state = get (); unused = false; computation = cleared }
330330

331331
let[@inline] use = function R Nothing -> () | R (Req r) -> r.unused <- false
332332

333333
let handle _ =
334334
let (Req r) = Picos_tls.get intr_key in
335335
Computation.return r.computation Signaled
336336

337-
let rec finish (Req r as req : [ `Req ] tdt) backoff =
337+
(** This is used to ensure that the [intr_pending] counter is incremented
338+
exactly once before the counter is decremented. *)
339+
let rec incr_once (Req r as req : [ `Req ] tdt) backoff =
338340
let before = Atomic.get intr_pending in
341+
(* [intr_pending] must be read before [r.unused]! *)
339342
r.unused && before.req != R req
340343
&& begin
341344
use before.req;
342345
let after = { value = before.value + 1; req = R req } in
343346
if Atomic.compare_and_set intr_pending before after then
344347
after.value = 1
345-
else finish req (Backoff.once backoff)
348+
else incr_once req (Backoff.once backoff)
346349
end
347350

348351
let intr_action trigger (Req r as req : [ `Req ] tdt) id =
@@ -353,14 +356,14 @@ module Intr = struct
353356
| Signaled ->
354357
(* Signal was delivered before timeout. *)
355358
remove_action trigger r.state id;
356-
if finish req Backoff.default then
359+
if incr_once req Backoff.default then
357360
(* We need to make sure at least one select thread will keep on
358361
triggering interrupts. *)
359362
wakeup r.state `Alive
360363
| exception Exit ->
361364
(* The timeout was triggered. This must have been called from the
362365
select thread, which will soon trigger an interrupt. *)
363-
let _ : bool = finish req Backoff.default in
366+
let _ : bool = incr_once req Backoff.default in
364367
()
365368

366369
let () =
@@ -411,7 +414,9 @@ module Intr = struct
411414
let _was_blocked : int list = Thread.sigmask SIG_BLOCK intr_sigs in
412415
(* assert (not (List.exists is_intr_sig was_blocked)); *)
413416
if not (Computation.try_return r.computation Cleared) then begin
414-
let _ : bool = finish req Backoff.default in
417+
let _ : bool = incr_once req Backoff.default in
418+
(* We ensure that the associated increment has been done before we
419+
decrement so that the [intr_pending] counter is never too low. *)
415420
decr Backoff.default
416421
end
417422
end

0 commit comments

Comments
 (0)