ozeigermann    2004/12/17 08:36:22

  Modified:    transaction/src/java/org/apache/commons/transaction/locking
                        GenericLockManager.java GenericLock.java
  Log:
  Fix for possbile lock out with incompatible preferred locks.
  
  Revision  Changes    Path
  1.5       +7 -5      
jakarta-commons/transaction/src/java/org/apache/commons/transaction/locking/GenericLockManager.java
  
  Index: GenericLockManager.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/transaction/src/java/org/apache/commons/transaction/locking/GenericLockManager.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- GenericLockManager.java   16 Dec 2004 23:26:31 -0000      1.4
  +++ GenericLockManager.java   17 Dec 2004 16:36:21 -0000      1.5
  @@ -88,7 +88,9 @@
       public boolean tryLock(Object ownerId, Object resourceId, int 
targetLockLevel, boolean reentrant) {
           GenericLock lock = (GenericLock) atomicGetOrCreateLock(resourceId);
           boolean acquired = lock.tryLock(ownerId, targetLockLevel,
  -                reentrant ? GenericLock.COMPATIBILITY_REENTRANT : 
GenericLock.COMPATIBILITY_NONE);
  +                reentrant ? GenericLock.COMPATIBILITY_REENTRANT : 
GenericLock.COMPATIBILITY_NONE,
  +                false);
  +        
           if (acquired) {
               addOwner(ownerId, lock);
           }
  
  
  
  1.6       +44 -25    
jakarta-commons/transaction/src/java/org/apache/commons/transaction/locking/GenericLock.java
  
  Index: GenericLock.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/transaction/src/java/org/apache/commons/transaction/locking/GenericLock.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- GenericLock.java  17 Dec 2004 00:20:36 -0000      1.5
  +++ GenericLock.java  17 Dec 2004 16:36:21 -0000      1.6
  @@ -176,7 +176,7 @@
       public boolean test(Object ownerId, int targetLockLevel, int 
compatibility) {
           boolean success = false;
           try {
  -            success = tryLock(ownerId, targetLockLevel, compatibility);
  +            success = tryLock(ownerId, targetLockLevel, compatibility, 
false);
           } finally {
               release(ownerId);
           }
  @@ -248,7 +248,7 @@
                        + System.currentTimeMillis());
           }
   
  -        if (tryLock(ownerId, targetLockLevel, compatibility)) {
  +        if (tryLock(ownerId, targetLockLevel, compatibility, preferred)) {
               
               if (logger.isFinerEnabled()) {
                    logger.logFiner(
  @@ -288,7 +288,7 @@
                               oldLock = (LockOwner) owners.get(ownerId);
                               // this creates a new owner, so we do not need to
                               // copy the old one
  -                            setLockLevel(ownerId, null, targetLockLevel);
  +                            setLockLevel(ownerId, null, targetLockLevel, 
preferred);
   
                               // finally wait
                               wait(remaining);
  @@ -299,14 +299,18 @@
                               // following check
                               // and not to have it in case of success either
                               // as there will be an ordinary lock then
  -                            owners.put(ownerId, oldLock);
  +                            if (oldLock != null) {
  +                                owners.put(ownerId, oldLock);
  +                            } else {
  +                                owners.remove(ownerId);
  +                            }
                           }
   
                       } else {
                           wait(remaining);
                       }
   
  -                    if (tryLock(ownerId, targetLockLevel, compatibility)) {
  +                    if (tryLock(ownerId, targetLockLevel, compatibility, 
preferred)) {
   
                           if (logger.isFinerEnabled()) {
                                logger.logFiner(
  @@ -394,37 +398,43 @@
   
           for (Iterator it = owners.values().iterator(); it.hasNext();) {
               LockOwner owner = (LockOwner) it.next();
  -            buf.append("- ").append(owner.ownerId.toString()).append(": 
").append(owner.lockLevel).append("\n");
  +            buf.append("- ").append(owner.ownerId.toString()).append(": 
").append(owner.lockLevel)
  +                    .append(owner.intention ? " intention" : " 
acquired").append("\n");
           }
           return buf.toString();
   
       }
   
       protected synchronized LockOwner getMaxLevelOwner() {
  -        return getMaxLevelOwner(null, -1);
  +        return getMaxLevelOwner(null, -1, false);
       }
   
  -    protected synchronized LockOwner getMaxLevelOwner(LockOwner 
reentrantOwner) {
  -        return getMaxLevelOwner(reentrantOwner, -1);
  +    protected synchronized LockOwner getMaxLevelOwner(LockOwner 
reentrantOwner, boolean preferred) {
  +        return getMaxLevelOwner(reentrantOwner, -1, preferred);
       }
   
  -    protected synchronized LockOwner getMaxLevelOwner(int supportLockLevel) {
  -        return getMaxLevelOwner(null, supportLockLevel);
  +    protected synchronized LockOwner getMaxLevelOwner(int supportLockLevel, 
boolean preferred) {
  +        return getMaxLevelOwner(null, supportLockLevel, preferred);
       }
   
  -    protected synchronized LockOwner getMaxLevelOwner(LockOwner 
reentrantOwner, int supportLockLevel) {
  +    protected synchronized LockOwner getMaxLevelOwner(LockOwner 
reentrantOwner,
  +            int supportLockLevel, boolean preferred) {
           LockOwner maxOwner = null;
           for (Iterator it = owners.values().iterator(); it.hasNext();) {
               LockOwner owner = (LockOwner) it.next();
               if (owner.lockLevel != supportLockLevel && 
!owner.equals(reentrantOwner)
  -                    && (maxOwner == null || maxOwner.lockLevel < 
owner.lockLevel)) {
  +                    && (maxOwner == null || maxOwner.lockLevel < 
owner.lockLevel)
  +                    // if we are a preferred lock we must not interfere with 
other intention
  +                    // locks as we otherwise might mututally lock without 
resolvation
  +                    && !(preferred && owner.intention)) {
                   maxOwner = owner;
               }
           }
           return maxOwner;
       }
       
  -    protected synchronized void setLockLevel(Object ownerId, LockOwner lock, 
int targetLockLevel) {
  +    protected synchronized void setLockLevel(Object ownerId, LockOwner lock, 
int targetLockLevel,
  +            boolean intention) {
           // be sure there exists at most one lock per owner
           if (lock != null) {
   
  @@ -440,6 +450,7 @@
               }
   
               lock.lockLevel = targetLockLevel;
  +            lock.intention = intention;
           } else {
   
               if (logger.isFinestEnabled()) {
  @@ -453,11 +464,12 @@
                            + System.currentTimeMillis());
               }
   
  -            owners.put(ownerId, new LockOwner(ownerId, targetLockLevel));
  +            owners.put(ownerId, new LockOwner(ownerId, targetLockLevel, 
intention));
           }
       }
   
  -    protected synchronized boolean tryLock(Object ownerId, int 
targetLockLevel, int compatibility) {
  +    protected synchronized boolean tryLock(Object ownerId, int 
targetLockLevel, int compatibility,
  +            boolean preferred) {
   
           LockOwner myLock = (LockOwner) owners.get(ownerId);
   
  @@ -469,12 +481,12 @@
                   return true;
               } else {
                   // our own lock will not be compromised by ourself
  -                highestOwner = getMaxLevelOwner(myLock);
  +                highestOwner = getMaxLevelOwner(myLock, preferred);
               }
           } else if (compatibility == COMPATIBILITY_SUPPORT) {
               // we are compatible with any other lock owner holding
               // the same lock level
  -            highestOwner = getMaxLevelOwner(targetLockLevel);
  +            highestOwner = getMaxLevelOwner(targetLockLevel, preferred);
   
           } else if (compatibility == COMPATIBILITY_REENTRANT_AND_SUPPORT) {
               if (myLock != null && targetLockLevel <= myLock.lockLevel) {
  @@ -482,7 +494,7 @@
                   return true;
               } else {
                   // our own lock will not be compromised by ourself and same 
lock level 
  -                highestOwner = getMaxLevelOwner(myLock, targetLockLevel);
  +                highestOwner = getMaxLevelOwner(myLock, targetLockLevel, 
preferred);
               }
           } else {
               highestOwner = getMaxLevelOwner();
  @@ -498,7 +510,8 @@
   
           // we are only allowed to acquire our locks if we do not compromise 
locks of any other lock owner
           if (isCompatible(targetLockLevel, currentLockLevel)) {
  -            setLockLevel(ownerId, myLock, targetLockLevel);
  +            // if we really have the lock, it no longer is an intention
  +            setLockLevel(ownerId, myLock, targetLockLevel, false);
               return true;
           } else {
               return false;
  @@ -547,10 +560,16 @@
       protected static class LockOwner {
           public Object ownerId;
           public int lockLevel;
  +        public boolean intention;
   
  -        public LockOwner(Object ownerId, int lockLevel) {
  +        public LockOwner(Object ownerId, int lockLevel, boolean intention) {
               this.ownerId = ownerId;
               this.lockLevel = lockLevel;
  +            this.intention = intention;
  +        }
  +
  +        public LockOwner(Object ownerId, int lockLevel) {
  +            this(ownerId, lockLevel, false);
           }
       }
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to