Author: ozeigermann
Date: Fri Jul 20 09:19:46 2007
New Revision: 558038
URL: http://svn.apache.org/viewvc?view=rev&rev=558038
Log:
Preparation for deadlock detection
Modified:
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/GenericLockManager.java
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/LockException.java
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/ReadWriteLockManager.java
Modified:
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/GenericLockManager.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/GenericLockManager.java?view=diff&rev=558038&r1=558037&r2=558038
==============================================================================
---
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/GenericLockManager.java
(original)
+++
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/GenericLockManager.java
Fri Jul 20 09:19:46 2007
@@ -1,44 +1,47 @@
package org.apache.commons.transaction.locking;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public abstract class GenericLockManager<K, L> implements LockManager<K, L> {
-
- protected final ConcurrentHashMap<K, L> globalLocks = new
ConcurrentHashMap<K, L>();
- protected final ConcurrentHashMap<K, L> globalOwners = new
ConcurrentHashMap<K, L>();
+
+ protected ConcurrentHashMap<K, L> locks = new ConcurrentHashMap<K, L>();
+
+ protected Map<Thread, Set<L>> threads = new ConcurrentHashMap<Thread,
Set<L>>();
@Override
public L get(K key) {
- return globalLocks.get(key);
+ return locks.get(key);
}
-
+
@Override
public L putIfAbsent(K key, L lock) {
L existingLock = get(key);
if (existingLock == null) {
- L concurrentlyInsertedLock = globalLocks.putIfAbsent(key, lock);
+ L concurrentlyInsertedLock = locks.putIfAbsent(key, lock);
if (concurrentlyInsertedLock != null)
lock = concurrentlyInsertedLock;
}
return lock;
-
+
}
-
+
@Override
public L remove(K key) {
- return globalLocks.remove(key);
+ return locks.remove(key);
}
+ @Override
public Iterable<L> getAll() {
- return globalLocks.values();
+ return locks.values();
}
- // FIXME
- public Set<L> getAllForCurrentThread() {
- // TODO Auto-generated method stub
- return null;
+ @Override
+ public Iterable<L> getAllForCurrentThread() {
+ return threads.get(Thread.currentThread());
}
+ public abstract L create();
}
Modified:
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/LockException.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/LockException.java?view=diff&rev=558038&r1=558037&r2=558038
==============================================================================
---
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/LockException.java
(original)
+++
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/LockException.java
Fri Jul 20 09:19:46 2007
@@ -87,6 +87,11 @@
super(cause);
}
+ public LockException(Throwable cause, Code code) {
+ super(cause);
+ this.code = code;
+ }
+
/**
* Returns the formal reason for the exception.
*
Modified:
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/ReadWriteLockManager.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/ReadWriteLockManager.java?view=diff&rev=558038&r1=558037&r2=558038
==============================================================================
---
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/ReadWriteLockManager.java
(original)
+++
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/ReadWriteLockManager.java
Fri Jul 20 09:19:46 2007
@@ -1,16 +1,136 @@
package org.apache.commons.transaction.locking;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
// TODO: Add wrappers to include failfast deadlock check
// possible actions after deadlock detected (done by user)
-// I rollback
-// II do not acquire the lock, but wait for a while
-public class ReadWriteLockManager extends GenericLockManager<Object,
ReadWriteLock> implements LockManager<Object, ReadWriteLock> {
+// (I) rollback
+// (II) do not acquire the lock, but wait for a while (would that do any good?
hmmm?)
+// TODO: Synchronize properly
+public class ReadWriteLockManager extends GenericLockManager<Object,
ReadWriteLock> implements
+ LockManager<Object, ReadWriteLock> {
+ protected Map<Thread, Long> effectiveGlobalTimeouts = new
ConcurrentHashMap<Thread, Long>();
+
+ // FIXME: This is Java 1.6 only!
+ protected Set<Thread> timedOutThreads = new
ConcurrentSkipListSet<Thread>();;
+
+ public void begin(long timeoutMSecs) {
+ startTimeoutTimer(timeoutMSecs);
+ }
+
+ public void end() {
+ releaseAll();
+ }
+
+ protected void releaseAll() {
+ Iterable<ReadWriteLock> locks = getAllForCurrentThread();
+ for (ReadWriteLock lock : locks) {
+ lock.readLock().unlock();
+ lock.writeLock().unlock();
+ }
+
+ }
+
+ protected void startTimeoutTimer(long timeoutMSecs) {
+ long now = System.currentTimeMillis();
+ long timeout = now + timeoutMSecs;
+ effectiveGlobalTimeouts.put(Thread.currentThread(), new Long(timeout));
+ }
+
+ @Override
public ReadWriteLock create() {
- return new ReentrantReadWriteLock();
+ return new TrackingReentrantReadWriteLock();
}
+ // returns a list of threads that could be rolledback to prevent the
deadlock
+ // that does not mean you actually have to, though.
+ protected Collection<Thread> wouldDeadlock(Lock lock) {
+ return null;
+ }
+
+ protected boolean checkForTimeout(Thread thread) throws LockException {
+ Long timeout = effectiveGlobalTimeouts.get(thread);
+ long now = System.currentTimeMillis();
+ return (timeout != null && now > timeout.longValue());
+ }
+
+ protected void clearAllTimedOutThreads() {
+
+ }
+
+ public class TrackingReentrantReadWriteLock extends ReentrantReadWriteLock
{
+
+ }
+
+ public class TrackingReadLock extends ReentrantReadWriteLock.ReadLock {
+
+ protected TrackingReadLock(ReentrantReadWriteLock lock) {
+ super(lock);
+ // TODO Auto-generated constructor stub
+ }
+
+ }
+
+ public class TrackingWriteLock extends ReentrantReadWriteLock.WriteLock {
+
+ protected TrackingWriteLock(ReentrantReadWriteLock lock) {
+ super(lock);
+ // TODO Auto-generated constructor stub
+ }
+ }
+
+ public class LockWrapper implements Lock {
+
+ private final Lock wrappedLock;
+
+ public LockWrapper(Lock wrappedLock) {
+ this.wrappedLock = wrappedLock;
+ }
+
+ public void lock() throws LockException {
+ // XXX
+ // we do not allow for uninterruptable operation, so delegate
+ // this to #lockInterruptibly() and rethrow the exception to a
+ // lockexception
+ try {
+ lockInterruptibly();
+ } catch (InterruptedException e) {
+ throw new LockException(e, LockException.Code.INTERRUPTED);
+ }
+ // TODO: alternative what be this:
+ // throw new UnsupportedOperationException("Uninterruptable
+ // operation are not supported!");
+ // Can't decide which is the better option...
+ }
+
+ public void lockInterruptibly() throws InterruptedException,
LockException {
+ wrappedLock.lockInterruptibly();
+ }
+
+ public Condition newCondition() {
+ return wrappedLock.newCondition();
+ }
+
+ public boolean tryLock() {
+ return wrappedLock.tryLock();
+ }
+
+ public boolean tryLock(long time, TimeUnit unit) throws
InterruptedException {
+ return wrappedLock.tryLock(time, unit);
+ }
+
+ public void unlock() {
+ wrappedLock.unlock();
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]