[jboss-cvs] JBossAS SVN: r86551 - in trunk: testsuite/src/main/org/jboss/test/cluster/defaultcfg/test and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Mar 31 18:07:19 EDT 2009


Author: bstansberry at jboss.com
Date: 2009-03-31 18:07:19 -0400 (Tue, 31 Mar 2009)
New Revision: 86551

Modified:
   trunk/cluster/src/main/org/jboss/ha/framework/server/lock/AbstractClusterLockSupport.java
   trunk/cluster/src/main/org/jboss/ha/framework/server/lock/LocalAndClusterLockManager.java
   trunk/cluster/src/main/org/jboss/ha/framework/server/lock/NonGloballyExclusiveClusterLockSupport.java
   trunk/cluster/src/main/org/jboss/ha/framework/server/lock/RemoteLockResponse.java
   trunk/cluster/src/main/org/jboss/ha/framework/server/lock/TimeoutException.java
   trunk/cluster/src/main/org/jboss/ha/framework/server/lock/YieldingGloballyExclusiveClusterLockSupport.java
   trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/ReadWriteClusteredLockManagerUnitTestCase.java
Log:
[JBAS-5552] Fix locking bugs observed during ClusteredDeploymentRepository testing

Modified: trunk/cluster/src/main/org/jboss/ha/framework/server/lock/AbstractClusterLockSupport.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/framework/server/lock/AbstractClusterLockSupport.java	2009-03-31 21:37:52 UTC (rev 86550)
+++ trunk/cluster/src/main/org/jboss/ha/framework/server/lock/AbstractClusterLockSupport.java	2009-03-31 22:07:19 UTC (rev 86551)
@@ -170,15 +170,18 @@
                      }
                      else if (((RemoteLockResponse) rsp).flag != RemoteLockResponse.Flag.OK)
                      {
+                        RemoteLockResponse curRsp = (RemoteLockResponse) rsp;
                         remoteLocked = false;
                         if (superiorCompetitor == null)
                         {
-                           superiorCompetitor = getSuperiorCompetitor(((RemoteLockResponse) rsp).holder);
+                           superiorCompetitor = getSuperiorCompetitor(curRsp.holder);
+                           log.debug("Received " + curRsp.flag + " response from " + 
+                                 curRsp.responder + " -- reports lock is held by " + curRsp.holder);
                         }
                      }
                   }
                }
-               else if (members.size() ==0 || (members.size() == 1 && members.contains(me)))
+               else if ((members.size() == 1 && members.contains(me)) || members.size() == 0)
                {
                   // no peers
                   remoteLocked = true;
@@ -285,8 +288,11 @@
       this.partition.registerRPCHandler(this.serviceHAName, this.rpcTarget);
       this.partition.registerMembershipListener(this); 
       
-      @SuppressWarnings("unchecked")
-      Vector allMembers = this.partition.getCurrentView();
+      Vector<ClusterNode> allMembers = new Vector<ClusterNode>();
+      for (ClusterNode node : this.partition.getClusterNodes())
+      {
+         allMembers.add(node);
+      }
       membershipChanged(new Vector<ClusterNode>(), allMembers, allMembers);
    }
    
@@ -342,14 +348,14 @@
    
    protected abstract RemoteLockResponse yieldLock(ClusterLockState lockState, ClusterNode caller, long timeout);
 
-   protected void recordLockHolder(ClusterLockState category, ClusterNode caller)
+   protected void recordLockHolder(ClusterLockState lockState, ClusterNode caller)
    {
-      if (category.holder != null)
+      if (lockState.holder != null)
       {
-         Set<ClusterLockState> memberLocks = getLocksHeldByMember(category.holder);
+         Set<ClusterLockState> memberLocks = getLocksHeldByMember(lockState.holder);
          synchronized (memberLocks)
          {
-            memberLocks.remove(category);
+            memberLocks.remove(lockState);
          }
       }
       
@@ -358,20 +364,20 @@
          Set<ClusterLockState> memberLocks = getLocksHeldByMember(caller);
          synchronized (memberLocks)
          {
-            memberLocks.add(category);
+            memberLocks.add(lockState);
          }
       }
       
-      category.lock(caller);
+      lockState.lock(caller);
    }
    
-   protected ClusterLockState getClusterLockState(Serializable categoryName, boolean create)
+   protected ClusterLockState getClusterLockState(Serializable lockName, boolean create)
    {
-      ClusterLockState category = lockStates.get(categoryName);
+      ClusterLockState category = lockStates.get(lockName);
       if (category == null && create)
       {
-         category = new ClusterLockState(categoryName);
-         ClusterLockState existing = lockStates.putIfAbsent(categoryName, category);
+         category = new ClusterLockState(lockName);
+         ClusterLockState existing = lockStates.putIfAbsent(lockName, category);
          if (existing != null)
          {
             category = existing;
@@ -390,55 +396,56 @@
    /**
     * Called by a remote node via RpcTarget.
     */
-   private RemoteLockResponse remoteLock(Serializable categoryName, ClusterNode caller, long timeout)
+   private RemoteLockResponse remoteLock(Serializable lockName, ClusterNode caller, long timeout)
    {
       RemoteLockResponse response = null;
-      ClusterLockState category = getClusterLockState(categoryName);
-      if (category == null)
+      ClusterLockState lockState = getClusterLockState(lockName);
+      if (lockState == null)
       {
          // unknown == OK
-         return new RemoteLockResponse(RemoteLockResponse.Flag.OK);
+         return new RemoteLockResponse(me, RemoteLockResponse.Flag.OK);
       }
       
-      switch (category.state.get())
+      switch (lockState.state.get())
       {
          case UNLOCKED:
             // Remote callers can race for the local lock
-            response = getLock(categoryName, category, caller, timeout);
+            response = getLock(lockName, lockState, caller, timeout);
             break;
          case REMOTE_LOCKING:
             if (me.equals(caller))
             {
                log.warn("Received remoteLock call from self");
-               response = new RemoteLockResponse(RemoteLockResponse.Flag.OK);
+               response = new RemoteLockResponse(me, RemoteLockResponse.Flag.OK);
             }
             else if (getSuperiorCompetitor(caller) == null)
             {
                // I want the lock and I take precedence
-               response = new RemoteLockResponse(RemoteLockResponse.Flag.REJECT, me);
+               response = new RemoteLockResponse(me, RemoteLockResponse.Flag.REJECT, me);
             }
             else
             {
                // I want the lock but caller takes precedence; let
                // them acquire local lock and I'll fail
-               response = getLock(categoryName, category, caller, timeout);
+               response = getLock(lockName, lockState, caller, timeout);
             }
             break;
          case LOCAL_LOCKING:
             // I've gotten OK responses from everyone and am about
             // to acquire local lock, so reject caller
-            response = new RemoteLockResponse(RemoteLockResponse.Flag.REJECT, me);
+            response = new RemoteLockResponse(me, RemoteLockResponse.Flag.REJECT, me);
             break;
          case LOCKED:
             // See if I have the lock and will give it up
-            response = yieldLock(category, caller, timeout);
+            response = yieldLock(lockState, caller, timeout);
             break;
          case INVALID:
             // We've given up the lock since we got the category and the
             // thread that caused that is trying to discard the unneeded 
             // category.
             // Call in again and see what our current state is
-            response = remoteLock(categoryName, caller, timeout);
+            Thread.yield();
+            response = remoteLock(lockName, caller, timeout);
             break;
       }
       
@@ -450,20 +457,20 @@
     */
    private void releaseRemoteLock(Serializable categoryName, ClusterNode caller)
    {
-      ClusterLockState category = getClusterLockState(categoryName, false);
-      if (category != null && category.state.get() == State.LOCKED)
+      ClusterLockState lockState = getClusterLockState(categoryName, false);
+      if (lockState != null && lockState.state.get() == State.LOCKED)
       {
          if (caller.equals(localHandler.getLockHolder(categoryName)))
          {
             // Throw away the category as a cleanup exercise
-            category.invalidate();
+            lockState.invalidate();
             localHandler.unlockFromCluster(categoryName, caller);
             Set<ClusterLockState> memberLocks = getLocksHeldByMember(caller);
             synchronized (memberLocks)
             {
-               memberLocks.remove(category);
+               memberLocks.remove(lockState);
             }
-            removeLockState(category);
+            removeLockState(lockState);
          }
       }
       
@@ -505,11 +512,11 @@
       {
          Thread.currentThread().interrupt();
          log.error("Caught InterruptedException; Failing request by " + caller + " to lock " + categoryName);
-         return new RemoteLockResponse(RemoteLockResponse.Flag.FAIL, localHandler.getLockHolder(categoryName));
+         return new RemoteLockResponse(me, RemoteLockResponse.Flag.FAIL, localHandler.getLockHolder(categoryName));
       }
       catch (TimeoutException t)
       {
-         return new RemoteLockResponse(RemoteLockResponse.Flag.FAIL, t.getOwner());
+         return new RemoteLockResponse(me, RemoteLockResponse.Flag.FAIL, t.getOwner());
       }
       
       response = handleLockSuccess(category, caller);

Modified: trunk/cluster/src/main/org/jboss/ha/framework/server/lock/LocalAndClusterLockManager.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/framework/server/lock/LocalAndClusterLockManager.java	2009-03-31 21:37:52 UTC (rev 86550)
+++ trunk/cluster/src/main/org/jboss/ha/framework/server/lock/LocalAndClusterLockManager.java	2009-03-31 22:07:19 UTC (rev 86551)
@@ -54,20 +54,27 @@
          boolean wasInterrupted = false;
          Thread current = Thread.currentThread();
          waiters.add(current);
-
-         // Block while not first in queue or cannot acquire lock
-         while (waiters.peek() != current || 
-                !locked.compareAndSet(false, true)) 
-         { 
-            LockSupport.parkUntil(deadline);
-            if (Thread.interrupted()) // ignore interrupts while waiting
-               wasInterrupted = true;
-            if (System.currentTimeMillis() >= deadline)
-               break;
-         }
          
          try
          {
+            // Block while not first in queue or cannot acquire lock
+            while (waiters.peek() != current || 
+                   !locked.compareAndSet(false, true)) 
+            { 
+               LockSupport.parkUntil(deadline);
+               if (Thread.interrupted()) // ignore interrupts while waiting
+                  wasInterrupted = true;
+               if (System.currentTimeMillis() >= deadline)
+               {
+                  if (waiters.peek() != current || 
+                        !locked.compareAndSet(false, true))
+                  {
+                     throw new TimeoutException(this.holder);
+                  }
+                  break;
+               }
+            }
+            
             if (locked.get())
             {
                holder = caller;
@@ -90,6 +97,7 @@
          if (caller.equals(holder))              
          {
             locked.set(false);
+            holder = null;
             LockSupport.unpark(waiters.peek());
          }
        } 

Modified: trunk/cluster/src/main/org/jboss/ha/framework/server/lock/NonGloballyExclusiveClusterLockSupport.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/framework/server/lock/NonGloballyExclusiveClusterLockSupport.java	2009-03-31 21:37:52 UTC (rev 86550)
+++ trunk/cluster/src/main/org/jboss/ha/framework/server/lock/NonGloballyExclusiveClusterLockSupport.java	2009-03-31 22:07:19 UTC (rev 86551)
@@ -63,12 +63,12 @@
          throw new IllegalStateException("Must call start() before first call to unlock()");
       }
       
-      ClusterLockState category = getClusterLockState(lockId, false);
+      ClusterLockState lockState = getClusterLockState(lockId, false);
       
-      if (category != null && myself.equals(category.getHolder()))
+      if (lockState != null && myself.equals(lockState.getHolder()))
       {
          getLocalHandler().unlockFromCluster(lockId, myself);
-         category.release();
+         lockState.release();
          
          try
          {
@@ -98,14 +98,14 @@
    @Override
    protected RemoteLockResponse yieldLock(ClusterLockState lockState, ClusterNode caller, long timeout)
    {
-      return new RemoteLockResponse(RemoteLockResponse.Flag.REJECT, lockState.getHolder());
+      return new RemoteLockResponse(getLocalClusterNode(), RemoteLockResponse.Flag.REJECT, lockState.getHolder());
    }
 
    @Override
    protected RemoteLockResponse handleLockSuccess(ClusterLockState lockState, ClusterNode caller)
    {
       recordLockHolder(lockState, caller);
-      return new RemoteLockResponse(RemoteLockResponse.Flag.OK);
+      return new RemoteLockResponse(getLocalClusterNode(), RemoteLockResponse.Flag.OK);
    }
    
    // ----------------------------------------------------------------- Private

Modified: trunk/cluster/src/main/org/jboss/ha/framework/server/lock/RemoteLockResponse.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/framework/server/lock/RemoteLockResponse.java	2009-03-31 21:37:52 UTC (rev 86550)
+++ trunk/cluster/src/main/org/jboss/ha/framework/server/lock/RemoteLockResponse.java	2009-03-31 22:07:19 UTC (rev 86551)
@@ -28,15 +28,17 @@
    
    public final RemoteLockResponse.Flag flag;
    public final ClusterNode holder;
+   public final ClusterNode responder;
    
-   public RemoteLockResponse(RemoteLockResponse.Flag flag)
+   public RemoteLockResponse(ClusterNode responder, RemoteLockResponse.Flag flag)
    {
-      this(flag, null);
+      this(responder, flag, null);
    }
    
-   public RemoteLockResponse(RemoteLockResponse.Flag flag, ClusterNode holder)
+   public RemoteLockResponse(ClusterNode responder, RemoteLockResponse.Flag flag, ClusterNode holder)
    {
       this.flag = flag;
       this.holder = holder;
+      this.responder = responder;
    }
 }
\ No newline at end of file

Modified: trunk/cluster/src/main/org/jboss/ha/framework/server/lock/TimeoutException.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/framework/server/lock/TimeoutException.java	2009-03-31 21:37:52 UTC (rev 86550)
+++ trunk/cluster/src/main/org/jboss/ha/framework/server/lock/TimeoutException.java	2009-03-31 22:07:19 UTC (rev 86551)
@@ -38,7 +38,7 @@
    
    public TimeoutException(ClusterNode owner)
    {
-      super("Unabled to acquire lock as it is held by " + (owner == null ? "unknown" : owner));
+      super("Unable to acquire lock as it is held by " + (owner == null ? "unknown" : owner));
       this.owner = owner;
    }
    

Modified: trunk/cluster/src/main/org/jboss/ha/framework/server/lock/YieldingGloballyExclusiveClusterLockSupport.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/framework/server/lock/YieldingGloballyExclusiveClusterLockSupport.java	2009-03-31 21:37:52 UTC (rev 86550)
+++ trunk/cluster/src/main/org/jboss/ha/framework/server/lock/YieldingGloballyExclusiveClusterLockSupport.java	2009-03-31 22:07:19 UTC (rev 86551)
@@ -88,7 +88,7 @@
       }
       else
       {
-         return new RemoteLockResponse(RemoteLockResponse.Flag.REJECT, lockState.getHolder());
+         return new RemoteLockResponse(getLocalClusterNode(), RemoteLockResponse.Flag.REJECT, lockState.getHolder());
       }
    }
 
@@ -106,7 +106,7 @@
          lockState.invalidate();
          removeLockState(lockState);
       }
-      return new RemoteLockResponse(RemoteLockResponse.Flag.OK);
+      return new RemoteLockResponse(getLocalClusterNode(), RemoteLockResponse.Flag.OK);
    }
    
    

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/ReadWriteClusteredLockManagerUnitTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/ReadWriteClusteredLockManagerUnitTestCase.java	2009-03-31 21:37:52 UTC (rev 86550)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/ReadWriteClusteredLockManagerUnitTestCase.java	2009-03-31 22:07:19 UTC (rev 86551)
@@ -284,7 +284,7 @@
       ArrayList<RemoteLockResponse> rspList = new ArrayList<RemoteLockResponse>();
       for (int i = 0; i < viewSize - 1; i++)
       {
-         rspList.add(new RemoteLockResponse(RemoteLockResponse.Flag.OK));
+         rspList.add(new RemoteLockResponse(null, RemoteLockResponse.Flag.OK));
       }
       
       expect(partition.callMethodOnCluster(eq("test"), 




More information about the jboss-cvs-commits mailing list