@@ -54,7 +54,7 @@ public class ItemHolder<K, V, Ctx, UserData> {
5454 private final AtomicReference <V > item = new AtomicReference <>();
5555 private final AtomicReference <UserData > userData = new AtomicReference <>();
5656 private final BusyRefCounter busyRefCounter = new BusyRefCounter ();
57- private final AtomicReference <Pair <CancellationSignaller , ItemStatus <K , V , Ctx >>> runningUpgradeAction = new AtomicReference <>();
57+ private final AtomicReference <Pair <Cancellable , ItemStatus <K , V , Ctx >>> runningAction = new AtomicReference <>();
5858 private final TicketSet <K , V , Ctx > tickets ;
5959 private volatile ItemStatus <K , V , Ctx > status = null ;
6060// private final List<Pair<ItemStatus<K, V, Ctx>, Long>> statusHistory = ReferenceLists.synchronize(new ReferenceArrayList<>());
@@ -127,9 +127,9 @@ public synchronized boolean isBusy() {
127127 return busyRefCounter .isBusy ();
128128 }
129129
130- public ItemStatus <K , V , Ctx > upgradingStatusTo () {
130+ public ItemStatus <K , V , Ctx > changingStatusTo () {
131131 assertOpen ();
132- final Pair <CancellationSignaller , ItemStatus <K , V , Ctx >> pair = this .runningUpgradeAction .get ();
132+ final Pair <Cancellable , ItemStatus <K , V , Ctx >> pair = this .runningAction .get ();
133133 return pair != null ? pair .right () : null ;
134134 }
135135
@@ -144,7 +144,9 @@ public void addTicket(ItemStatus<K, V, Ctx> targetStatus, ItemTicket ticket) {
144144 }
145145 this .tickets .addUnchecked (targetStatus );
146146 createFutures ();
147- needConsumption = targetStatus .ordinal () <= this .getStatus ().ordinal ();
147+ final var current = this .getStatus ();
148+ final var projected = this .changingStatusTo ();
149+ needConsumption = targetStatus .ordinal () <= (projected == null ? current .ordinal () : Math .min (current .ordinal (), projected .ordinal ()));
148150 }
149151
150152 if (needConsumption ) {
@@ -208,16 +210,21 @@ BusyRefCounter busyRefCounter() {
208210 return this .busyRefCounter ;
209211 }
210212
211- public void submitUpgradeAction (CancellationSignaller signaller , ItemStatus <K , V , Ctx > status ) {
213+ public void finishAction () {
214+ assertOpen ();
215+ Pair <Cancellable , ItemStatus <K , V , Ctx >> current = this .runningAction .getAndSet (null );
216+ Assertions .assertTrue (current != null , "No action is present when trying to finish an action" );
217+ }
218+
219+ public void submitAction (Cancellable cancellation , ItemStatus <K , V , Ctx > status ) {
212220 assertOpen ();
213- final boolean success = this .runningUpgradeAction .compareAndSet (null , Pair .of (signaller , status ));
221+ final var success = this .runningAction .compareAndSet (null , Pair .of (cancellation , status ));
214222 Assertions .assertTrue (success , "Only one action can happen at a time" );
215- signaller .addListener (unused -> this .runningUpgradeAction .set (null ));
216223 }
217224
218- public void tryCancelUpgradeAction () {
225+ public void tryCancelAction () {
219226 assertOpen ();
220- final Pair <CancellationSignaller , ItemStatus <K , V , Ctx >> signaller = this .runningUpgradeAction .get ();
227+ final Pair <Cancellable , ItemStatus <K , V , Ctx >> signaller = this .runningAction .get ();
221228 if (signaller != null ) {
222229 signaller .left ().cancel ();
223230 }
0 commit comments