Skip to content

Commit

Permalink
pool: fix double decrement of hsm requests
Browse files Browse the repository at this point in the history
Motivation:
If hsm requests completed twice due to a bug or a race condition, then
`AbstractRequest#removeFromQueue` can be called twice. As
removeFromQueue uses `state#get` then two competing requests might get
the same value and introduce double decrement.

Modification:
Add new state 'REMOVED' that with get-and-set semantic avoids double decrement situation.

Result:
Fix double decrement on active hsm requests

Fixes: #7511
Acked-by: Dmitry Litvintsev
Target: master, 10.1, 10.0, 9.2
Require-book: no
Require-notes: yes
(cherry picked from commit daad2ab)
Signed-off-by: Tigran Mkrtchyan <[email protected]>
  • Loading branch information
kofemann authored and lemora committed Oct 7, 2024
1 parent 1215548 commit 8e376b7
Showing 1 changed file with 6 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* dCache - http://www.dcache.org/
*
* Copyright (C) 2014 - 2023 Deutsches Elektronen-Synchrotron
* Copyright (C) 2014 - 2024 Deutsches Elektronen-Synchrotron
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
Expand Down Expand Up @@ -519,7 +519,7 @@ private void addFromNearlineStorage(StorageInfoMessage message, NearlineStorage
*/
private abstract static class AbstractRequest<K> implements Comparable<AbstractRequest<K>> {

protected enum State {QUEUED, ACTIVE, CANCELED}
protected enum State {QUEUED, ACTIVE, CANCELED, REMOVED}

private final List<CompletionHandler<Void, K>> callbacks = new ArrayList<>();
protected final long createdAt = System.currentTimeMillis();
Expand Down Expand Up @@ -644,7 +644,7 @@ public int compareTo(AbstractRequest<K> o) {
}

public void removeFromQueue() {
State currentState = state.get();
State currentState = state.getAndSet(State.REMOVED);
switch (currentState) {
case QUEUED:
decQueued();
Expand All @@ -655,6 +655,9 @@ public void removeFromQueue() {
case CANCELED:
decCanceled();
break;
case REMOVED:
LOGGER.warn("Request {} was already removed from the queue.", this);
break;
default:
throw new RuntimeException();
}
Expand Down

0 comments on commit 8e376b7

Please sign in to comment.