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]