From 3f184dc28d1744bab131af067fe5c709659fb416 Mon Sep 17 00:00:00 2001
From: "Brian S. O'Neill" <bronee@gmail.com>
Date: Fri, 12 Dec 2008 23:42:13 +0000
Subject: Fix deadlock in timed write lock acquisition.

---
 .../amazon/carbonado/repo/map/UpgradableLock.java  | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

(limited to 'src/main/java/com/amazon/carbonado/repo/map')

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;
     }
-- 
cgit v1.2.3