Skip to content

Commit

Permalink
Fix #164:
Browse files Browse the repository at this point in the history
- store the storage lock in class LockEntry rather than in class
  SingleLock,
- as a consequence: obtain only one storage lock when mutliple shared
  locks are requested on the same dataset,
- release the storage lock when the lock count drops to zero,
  e.g. when the last lock on the dataset is closed.
  • Loading branch information
RKrahl committed Jul 10, 2024
1 parent 703be1d commit f11164b
Showing 1 changed file with 15 additions and 20 deletions.
35 changes: 15 additions & 20 deletions src/main/java/org/icatproject/ids/LockManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,13 @@ public class LockInfo {
private class LockEntry {
final Long id;
final LockType type;
final AutoCloseable storageLock;
int count;

LockEntry(Long id, LockType type) {
LockEntry(Long id, LockType type, AutoCloseable storageLock) {
this.id = id;
this.type = type;
this.storageLock = storageLock;
this.count = 0;
lockMap.put(id, this);
}
Expand All @@ -56,6 +58,13 @@ void dec() {
count -= 1;
if (count == 0) {
lockMap.remove(id);
if (storageLock != null) {
try {
storageLock.close();
} catch (Exception e) {
logger.error("Error while closing lock on {} in the storage plugin: {}.", id, e.getMessage());
}
}
}
}
}
Expand All @@ -74,26 +83,17 @@ public void close() {
private class SingleLock extends Lock {
private final Long id;
private boolean isValid;
private AutoCloseable storageLock;

SingleLock(Long id, AutoCloseable storageLock) {
SingleLock(Long id) {
this.id = id;
this.isValid = true;
this.storageLock = storageLock;
}

public void release() {
synchronized (lockMap) {
if (isValid) {
lockMap.get(id).dec();
isValid = false;
if (storageLock != null) {
try {
storageLock.close();
} catch (Exception e) {
logger.error("Error while closing lock on {} in the storage plugin: {}.", id, e.getMessage());
}
}
logger.debug("Released a lock on {}.", id);
}
}
Expand Down Expand Up @@ -136,22 +136,17 @@ public Lock lock(DsInfo ds, LockType type) throws AlreadyLockedException, IOExce
synchronized (lockMap) {
LockEntry le = lockMap.get(id);
if (le == null) {
le = new LockEntry(id, type);
AutoCloseable storageLock;
storageLock = mainStorage.lock(ds, type == LockType.SHARED);
le = new LockEntry(id, type, storageLock);
} else {
if (type == LockType.EXCLUSIVE || le.type == LockType.EXCLUSIVE) {
throw new AlreadyLockedException();
}
}
le.inc();
AutoCloseable storageLock;
try {
storageLock = mainStorage.lock(ds, type == LockType.SHARED);
} catch (AlreadyLockedException | IOException e) {
le.dec();
throw e;
}
logger.debug("Acquired a {} lock on {}.", type, id);
return new SingleLock(id, storageLock);
return new SingleLock(id);
}
}

Expand Down

0 comments on commit f11164b

Please sign in to comment.