commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ozeigerm...@apache.org
Subject svn commit: r567193 - in /commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking: AbstractLockManager.java RWLockManager.java SimpleLockManager.java locks/ResourceRWLock.java
Date Sat, 18 Aug 2007 00:25:20 GMT
Author: ozeigermann
Date: Fri Aug 17 17:25:19 2007
New Revision: 567193

URL: http://svn.apache.org/viewvc?view=rev&rev=567193
Log:
Added removal of unused locks to avoid out of memory

Modified:
    commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/AbstractLockManager.java
    commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/RWLockManager.java
    commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/SimpleLockManager.java
    commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/locks/ResourceRWLock.java

Modified: commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/AbstractLockManager.java
URL: http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/AbstractLockManager.java?view=diff&rev=567193&r1=567192&r2=567193
==============================================================================
--- commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/AbstractLockManager.java
(original)
+++ commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/AbstractLockManager.java
Fri Aug 17 17:25:19 2007
@@ -45,6 +45,8 @@
         release();
     }
 
+    abstract protected void release();
+
     @Override
     public void startWork(long timeout, TimeUnit unit) {
         if (isWorking()) {
@@ -98,19 +100,6 @@
         long remainingTime = computeRemainingTime(thread);
         return (remainingTime < 0);
 
-    }
-
-    protected void release() {
-        Set<Lock> locks = locksForThreads.get(Thread.currentThread());
-        // graceful reaction...
-        if (locks == null) {
-            return;
-        }
-        for (Lock lock : locks) {
-            lock.unlock();
-        }
-
-        locksForThreads.remove(Thread.currentThread());
     }
 
     protected static class KeyEntry<K, M> {

Modified: commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/RWLockManager.java
URL: http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/RWLockManager.java?view=diff&rev=567193&r1=567192&r2=567193
==============================================================================
--- commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/RWLockManager.java
(original)
+++ commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/RWLockManager.java
Fri Aug 17 17:25:19 2007
@@ -18,21 +18,64 @@
 
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
+import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.Lock;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.transaction.locking.AbstractLockManager.KeyEntry;
 import org.apache.commons.transaction.locking.LockException.Code;
 import org.apache.commons.transaction.locking.locks.ResourceRWLock;
 
 public class RWLockManager<K, M> extends AbstractLockManager<K, M> implements
LockManager<K, M> {
 
-    protected ConcurrentHashMap<KeyEntry<K, M>, ResourceRWLock> locks = new ConcurrentHashMap<KeyEntry<K,
M>, ResourceRWLock>();
-    
+    private Log log = LogFactory.getLog(getClass());
+
+    protected ConcurrentHashMap<KeyEntry<K, M>, ResourceRWLock> allLocks = new
ConcurrentHashMap<KeyEntry<K, M>, ResourceRWLock>();
+
     private long absolutePrewaitTime = -1;
+
     private long prewaitTimeDivisor = 10;
 
+    protected void release() {
+        Set<Lock> locks = locksForThreads.get(Thread.currentThread());
+        // graceful reaction...
+        if (locks == null) {
+            return;
+        }
+
+        // first release all locks
+        for (Lock lock : locks) {
+            lock.unlock();
+        }
+
+        // then remove all locks that are no longer needed to avoid out of
+        // memory
+        removeUnsuedLocks();
+
+        locksForThreads.remove(Thread.currentThread());
+    }
+
+    protected void removeUnsuedLocks() {
+        Set<Entry<KeyEntry<K, M>, ResourceRWLock>> locksToCheck = allLocks.entrySet();
+        for (Entry<KeyEntry<K, M>, ResourceRWLock> entry : locksToCheck) {
+            KeyEntry<K, M> keyEntry = entry.getKey();
+            ResourceRWLock lock = entry.getValue();
+
+            // remove lock if no other thread holds a it
+            if (lock.isUnacquired()) {
+                // only remove if no one else has modified it in the meantime
+                if (allLocks.remove(keyEntry, lock)) {
+                    log.debug("Completely removing unused lock" + lock);
+                }
+            }
+        }
+    }
+
     protected ResourceRWLock create(String name) {
         return new ResourceRWLock(name);
     }
@@ -46,7 +89,7 @@
         String resourceName = entry.toString();
 
         ResourceRWLock rwlock = create(resourceName);
-        ResourceRWLock existingLock = locks.putIfAbsent(entry, rwlock);
+        ResourceRWLock existingLock = allLocks.putIfAbsent(entry, rwlock);
         if (existingLock != null)
             rwlock = existingLock;
         Set<Lock> locksForThisThread = locksForThreads.get(Thread.currentThread());
@@ -132,7 +175,8 @@
     }
 
     long getPrewaitTime(long timeMsecs) {
-        if (absolutePrewaitTime != -1) return absolutePrewaitTime;
+        if (absolutePrewaitTime != -1)
+            return absolutePrewaitTime;
         return timeMsecs / prewaitTimeDivisor;
     }
 

Modified: commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/SimpleLockManager.java
URL: http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/SimpleLockManager.java?view=diff&rev=567193&r1=567192&r2=567193
==============================================================================
--- commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/SimpleLockManager.java
(original)
+++ commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/SimpleLockManager.java
Fri Aug 17 17:25:19 2007
@@ -43,7 +43,7 @@
         LockManager<K, M> {
     private Log logger = LogFactory.getLog(getClass());
 
-    protected ConcurrentHashMap<KeyEntry<K, M>, ReentrantLock> locks = new ConcurrentHashMap<KeyEntry<K,
M>, ReentrantLock>();
+    protected ConcurrentHashMap<KeyEntry<K, M>, ReentrantLock> allLocks = new
ConcurrentHashMap<KeyEntry<K, M>, ReentrantLock>();
 
     protected ReentrantLock create() {
         return new ReentrantLock();
@@ -56,7 +56,7 @@
         KeyEntry<K, M> entry = new KeyEntry<K, M>(key, managedResource);
 
         ReentrantLock lock = create();
-        ReentrantLock existingLock = locks.putIfAbsent(entry, lock);
+        ReentrantLock existingLock = allLocks.putIfAbsent(entry, lock);
         if (existingLock != null)
             lock = existingLock;
         Set<Lock> locks = locksForThreads.get(Thread.currentThread());

Modified: commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/locks/ResourceRWLock.java
URL: http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/locks/ResourceRWLock.java?view=diff&rev=567193&r1=567192&r2=567193
==============================================================================
--- commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/locks/ResourceRWLock.java
(original)
+++ commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/locks/ResourceRWLock.java
Fri Aug 17 17:25:19 2007
@@ -88,6 +88,10 @@
         waiterThreads.remove(current);
     }
 
+    public boolean isUnacquired() {
+        return sync.isUnacquired();
+    }
+
     public class InnerLock {
         public ResourceRWLock getResourceRWLock() {
             return ResourceRWLock.this;
@@ -195,6 +199,20 @@
 
         private final int WRITE_LOCK = -1;
 
+        public boolean isUnacquired() {
+            return getState() == NO_LOCK;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof Sync) {
+                Sync otherSync = (Sync) obj;
+                return (getState() == otherSync.getState() && readerThreads
+                        .equals(otherSync.readerThreads));
+            }
+            return false;
+        }
+
         protected boolean tryRelease(int unsused) {
             Thread current = Thread.currentThread();
             // gracefully return in case we do not even have the lock
@@ -202,7 +220,8 @@
                 return true;
             setExclusiveOwnerThread(null);
             // if we release an exclusive lock, this can only mean we are the
-            // only who possibly could and the only possible outcome is that
+            // only one who possibly could do this and the only possible outcome
+            // is that
             // afterwards there are no more locks
             setState(NO_LOCK);
             return true;
@@ -325,5 +344,14 @@
         }
 
     };
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof ResourceRWLock) {
+            return sync.equals(((ResourceRWLock) obj).sync);
+        }
+        return false;
+
+    }
 
 }



Mime
View raw message