Skip to content

Commit edbfc68

Browse files
committed
Fix to allow retry from withing Xt.update and Xt.modify
1 parent c1cf4ee commit edbfc68

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

src/kcas/kcas.ml

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -535,13 +535,17 @@ module Xt = struct
535535
let update0 loc f xt lt gt =
536536
let state = fenceless_get (as_atomic loc) in
537537
let before = eval state in
538-
let after = f before in
539-
let state =
540-
if before == after && is_obstruction_free xt.casn loc then state
541-
else { before; after; casn = xt.casn; awaiters = [] }
542-
in
543-
xt.cass <- CASN { loc; state; lt; gt; awaiters = [] };
544-
before
538+
match f before with
539+
| after ->
540+
let state =
541+
if before == after && is_obstruction_free xt.casn loc then state
542+
else { before; after; casn = xt.casn; awaiters = [] }
543+
in
544+
xt.cass <- CASN { loc; state; lt; gt; awaiters = [] };
545+
before
546+
| exception exn ->
547+
xt.cass <- CASN { loc; state; lt; gt; awaiters = [] };
548+
raise exn
545549
[@@inline]
546550

547551
let update loc f xt state' lt gt =

test/kcas/test.ml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,13 @@ let test_backoff () =
328328
let test_blocking () =
329329
let state = Loc.make `Spawned in
330330
let await state' =
331-
Loc.get_as (fun state -> Retry.unless (state == state')) state
331+
(* Intentionally test that [Xt.modify] allows retry. *)
332+
let tx ~xt =
333+
Xt.modify ~xt state @@ fun state ->
334+
Retry.unless (state == state');
335+
state
336+
in
337+
Xt.commit { tx }
332338
in
333339

334340
let a = Loc.make 0 and bs = Array.init 10 @@ fun _ -> Loc.make 0 in

0 commit comments

Comments
 (0)