summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian S. O'Neill <bronee@gmail.com>2008-12-12 23:42:13 +0000
committerBrian S. O'Neill <bronee@gmail.com>2008-12-12 23:42:13 +0000
commit3f184dc28d1744bab131af067fe5c709659fb416 (patch)
treef3776609a942ad50144440bb2a025c6be6d1ae4e /src
parente7c3eed36a5f1484fb994075af1cde9891b89143 (diff)
Fix deadlock in timed write lock acquisition.
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/amazon/carbonado/repo/map/UpgradableLock.java22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/main/java/com/amazon/carbonado/repo/map/UpgradableLock.java b/src/main/java/com/amazon/carbonado/repo/map/UpgradableLock.java
index 55074e1..60c9bfa 100644
--- a/src/main/java/com/amazon/carbonado/repo/map/UpgradableLock.java
+++ b/src/main/java/com/amazon/carbonado/repo/map/UpgradableLock.java
@@ -469,8 +469,26 @@ class UpgradableLock<L> {
throw new InterruptedException();
}
if (!tryLockForWrite(locker)) {
- return lockForWriteQueuedInterruptibly(locker, addWriteWaiter(),
- unit.toNanos(timeout));
+ long start = System.nanoTime();
+ Result upgradeResult = tryLockForUpgrade_(locker, timeout, unit);
+ if (upgradeResult == Result.FAILED) {
+ return false;
+ }
+ if (!tryLockForWrite(locker)) {
+ if ((timeout = unit.toNanos(timeout) - (System.nanoTime() - start)) <= 0) {
+ return false;
+ }
+ if (!lockForWriteQueuedInterruptibly(locker, addWriteWaiter(), timeout)) {
+ return false;
+ }
+ }
+ if (upgradeResult == Result.ACQUIRED) {
+ // clear upgrade state bit to indicate automatic upgrade
+ while (!clearUpgradeLock(mState)) {}
+ } else {
+ // undo automatic upgrade count increment
+ mUpgradeCount--;
+ }
}
return true;
}