Author: j16sdiz
Date: 2008-07-13 13:27:03 +0000 (Sun, 13 Jul 2008)
New Revision: 21131

Modified:
   
branches/saltedhashstore/freenet/src/freenet/store/saltedhash/LockManager.java
   
branches/saltedhashstore/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java
Log:
verify condition on unlock

Modified: 
branches/saltedhashstore/freenet/src/freenet/store/saltedhash/LockManager.java
===================================================================
--- 
branches/saltedhashstore/freenet/src/freenet/store/saltedhash/LockManager.java  
    2008-07-13 13:26:42 UTC (rev 21130)
+++ 
branches/saltedhashstore/freenet/src/freenet/store/saltedhash/LockManager.java  
    2008-07-13 13:27:03 UTC (rev 21131)
@@ -35,16 +35,17 @@
         * This lock is <strong>not</strong> re-entrance. No threads except 
Cleaner should hold more
         * then one lock at a time (or deadlock may occur).
         */
-       boolean lockEntry(long offset) {
+       Condition lockEntry(long offset) {
                if (logDEBUG)
                        Logger.debug(this, "try locking " + offset, new 
Exception());

+               Condition condition;
                try {
                        entryLock.lock();
                        try {
                                do {
                                        if (shutdown)
-                                               return false;
+                                               return null;

                                        Condition lockCond = 
lockMap.get(offset);
                                        if (lockCond != null)
@@ -52,31 +53,32 @@
                                        else
                                                break;
                                } while (true);
-                               lockMap.put(offset, entryLock.newCondition());
+                               condition = entryLock.newCondition();
+                               lockMap.put(offset, condition);
                        } finally {
                                entryLock.unlock();
                        }
                } catch (InterruptedException e) {
                        Logger.error(this, "lock interrupted", e);
-                       return false;
+                       return null;
                }

                if (logDEBUG)
                        Logger.debug(this, "locked " + offset, new Exception());
-               return true;
+               return condition;
        }

        /**
         * Unlock the entry
         */
-       void unlockEntry(long offset) {
+       void unlockEntry(long offset, Condition condition) {
                if (logDEBUG)
                        Logger.debug(this, "unlocking " + offset, new 
Exception("debug"));

                entryLock.lock();
                try {
                        Condition cond = lockMap.remove(offset);
-                       assert cond != null;
+                       assert cond != condition;
                        cond.signal();
                } finally {
                        entryLock.unlock();

Modified: 
branches/saltedhashstore/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java
===================================================================
--- 
branches/saltedhashstore/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java
   2008-07-13 13:26:42 UTC (rev 21130)
+++ 
branches/saltedhashstore/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java
   2008-07-13 13:27:03 UTC (rev 21131)
@@ -14,9 +14,10 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.Map;
 import java.util.Random;
-import java.util.Set;
 import java.util.SortedSet;
+import java.util.TreeMap;
 import java.util.TreeSet;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
@@ -151,8 +152,8 @@

                configLock.readLock().lock();
                try {
-                       boolean locked = lockPlainKey(routingKey, true);
-                       if (!locked) {
+                       Map<Long, Condition> lockMap = lockPlainKey(routingKey, 
true);
+                       if (lockMap == null) {
                                if (logDEBUG)
                                        Logger.debug(this, "cannot lock key: " 
+ HexUtil.bytesToHex(routingKey) + ", shutting down?");
                                return null;
@@ -179,7 +180,7 @@
                                        return null;
                                }
                        } finally {
-                               unlockPlainKey(routingKey, true);
+                               unlockPlainKey(routingKey, true, lockMap);
                        }
                } finally {
                        configLock.readLock().unlock();
@@ -238,8 +239,8 @@

                configLock.readLock().lock();
                try {
-                       boolean locked = lockPlainKey(routingKey, false);
-                       if (!locked) {
+                       Map<Long, Condition> lockMap = lockPlainKey(routingKey, 
false);
+                       if (lockMap == null) {
                                if (logDEBUG)
                                        Logger.debug(this, "cannot lock key: " 
+ HexUtil.bytesToHex(routingKey) + ", shutting down?");
                                return;
@@ -305,7 +306,7 @@
                                if (oldEntry.generation != generation)
                                        keyCount.incrementAndGet();
                        } finally {
-                               unlockPlainKey(routingKey, false);
+                               unlockPlainKey(routingKey, false, lockMap);
                        }
                } finally {
                        configLock.readLock().unlock();
@@ -1133,13 +1134,12 @@
                 *         otherwise (e.g. can't acquire locks, node shutting 
down)
                 */
                private boolean batchProcessEntries(long offset, int length, 
BatchProcessor processor) {
-                       boolean[] locked = new boolean[length];
+                       Condition[] locked = new Condition[length];
                        try {
                                // acquire all locks in the region, will unlock 
in the finally block
                                for (int i = 0; i < length; i++) {
-                                       if (lockManager.lockEntry(offset + i))
-                                               locked[i] = true;
-                                       else
+                                       locked[i] = 
lockManager.lockEntry(offset + i);
+                                       if (locked[i] == null)
                                                return false;
                                }

@@ -1215,8 +1215,8 @@
                        } finally {
                                // unlock
                                for (int i = 0; i < length; i++)
-                                       if (locked[i])
-                                               lockManager.unlockEntry(offset 
+ i);
+                                       if (locked[i] != null)
+                                               lockManager.unlockEntry(offset 
+ i, locked[i]);
                        }
                }

@@ -1227,7 +1227,8 @@
                 * @return <code>true</code> if the entry have put back 
successfully.
                 */
                private boolean resolveOldEntry(Entry entry) {
-                       if (!lockDigestedKey(entry.getDigestedRoutingKey(), 
false))
+                       Map<Long, Condition> lockMap = 
lockDigestedKey(entry.getDigestedRoutingKey(), false);
+                       if (lockMap == null)
                                return false;
                        try {
                                entry.storeSize = storeSize;
@@ -1261,7 +1262,7 @@
                                }
                                return false;
                        } finally {
-                               
unlockDigestedKey(entry.getDigestedRoutingKey(), false);
+                               
unlockDigestedKey(entry.getDigestedRoutingKey(), false, lockMap);
                        }
                }
        }
@@ -1304,12 +1305,12 @@
         * @param plainKey
         * @return <code>true</code> if all the offsets are locked.
         */
-       private boolean lockPlainKey(byte[] plainKey, boolean usePrevStoreSize) 
{
+       private Map<Long, Condition> lockPlainKey(byte[] plainKey, boolean 
usePrevStoreSize) {
                return lockDigestedKey(cipherManager.getDigestedKey(plainKey), 
usePrevStoreSize);
        }

-       private void unlockPlainKey(byte[] plainKey, boolean usePrevStoreSize) {
-               unlockDigestedKey(cipherManager.getDigestedKey(plainKey), 
usePrevStoreSize);
+       private void unlockPlainKey(byte[] plainKey, boolean usePrevStoreSize, 
Map<Long, Condition> lockMap) {
+               unlockDigestedKey(cipherManager.getDigestedKey(plainKey), 
usePrevStoreSize, lockMap);
        }

        /**
@@ -1319,7 +1320,7 @@
         * @param digestedKey
         * @return <code>true</code> if all the offsets are locked.
         */
-       private boolean lockDigestedKey(byte[] digestedKey, boolean 
usePrevStoreSize) {
+       private Map<Long, Condition> lockDigestedKey(byte[] digestedKey, 
boolean usePrevStoreSize) {
                // use a set to prevent duplicated offsets,
                // a sorted set to prevent deadlocks
                SortedSet<Long> offsets = new TreeSet<Long>();
@@ -1332,25 +1333,25 @@
                                offsets.add(offset);
                }

-               Set<Long> locked = new TreeSet<Long>();
+               Map<Long, Condition> locked = new TreeMap<Long, Condition>();
                for (long offset : offsets) {
-                       boolean status = lockManager.lockEntry(offset);
-                       if (!status)
+                       Condition condition = lockManager.lockEntry(offset);
+                       if (condition == null)
                                break;
-                       locked.add(offset);
+                       locked.put(offset, condition);
                }

                if (locked.size() == offsets.size()) {
-                       return true;
+                       return locked;
                } else {
                        // failed, remove the locks
-                       for (long offset : locked)
-                               lockManager.unlockEntry(offset);
-                       return false;
+                       for (Map.Entry<Long, Condition> e : locked.entrySet())
+                               lockManager.unlockEntry(e.getKey(), 
e.getValue());
+                       return null;
                }
        }

-       private void unlockDigestedKey(byte[] digestedKey, boolean 
usePrevStoreSize) {
+       private void unlockDigestedKey(byte[] digestedKey, boolean 
usePrevStoreSize, Map<Long, Condition> lockMap) {
                // use a set to prevent duplicated offsets
                SortedSet<Long> offsets = new TreeSet<Long>();
                long[] offsetArray = getOffsetFromDigestedKey(digestedKey, 
storeSize);
@@ -1363,7 +1364,8 @@
                }

                for (long offset : offsets) {
-                       lockManager.unlockEntry(offset);
+                       lockManager.unlockEntry(offset, lockMap.get(offset));
+                       lockMap.remove(offset);
                }
        }



Reply via email to