[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