- Move lock management facilities into their own package, make them
parameterized by key type, fix some bugs uncovered during testing, and
add support for non-transactional locking, which is used by the
caching data store server
- Merges revision 6418 of branch tjb-misc to the trunk
- Reviewed by Seth
M sgs-server/src/main/java/com/sun/sgs/impl/kernel/LockingAccessCoordinator.java
- Move lock management facilities to separate classes in the new
com.sun.sgs.impl.util.lock package.
- Remove comment about special priority for upgrade requests, which has
been removed.
- Remove DEFAULT_LOCK_TIMEOUT -- it's easier to compute the lock timeout
using the actual transaction timeout, and means the constructor can
print out the actual transaction timeout in its new CONFIG logging.
- Move the addCheckOverflow method to the new Numbers utility class.
- Define the new LockerImpl class, extending TxnLocker.
- Add code to LockerImpl to check the thread safety of accesses to the
requests field when assertions are enabled. An earlier coding error
had been producing a thread hazard on this field. Note that the
synchronization used in these checks should not synchronize on the
locker object itself, since that might introduce lock ordering
problems.
- Define the LockerImpl.setConflictIfNeeded method for storing locally
discovered conflicts in the locker's conflict field, and use it in the
AccessReporterImpl.reportObjectAccess method.
A sgs-server/src/main/java/com/sun/sgs/impl/util/Numbers.java
- Define utility methods for working with numbers, and move the
addCheckOverflow method to here.
A sgs-server/src/main/java/com/sun/sgs/impl/util/lock/BasicLocker.java
- Define a new subclass of Locker that records the currently active lock
request in a field.
A sgs-server/src/main/java/com/sun/sgs/impl/util/lock/Lock.java
- Make this a top-level class and add the key type parameter.
- Add a logger field and move the currentSync field to the LockManager
class.
- Modify the lock method
- Remove some redundant code.
- Check waiters for conflicts. This change makes sure that upgrade
requests do not jump the queue of earlier waiters, and also makes
sure that reads wait for writes.
- Check to see if the requester is already waiting even if the waiting
parameter is false. This change allows this method to be safely
retried while a previous call is still active, which might be needed
if a blocked call suffers a network failure and is retried while the
original call is still waiting.
- Simplify the logic for removing the read owner on an upgrade: in
that case, there is only one owner.
- Don't create a new lock request in the case where a conflict is
found and the locker is already waiting. Creating a new lock
request in that case was causing a thread safety hazard for the
locker's requests field.
- Modify the release method to add the downgrade parameter.
- Modify copyOwners to return a list rather than an array, to avoid
ugliness with parameterized array types. Use the canonical empty list
or a singleton list to save space, if possible.
- Add copyWaiters, for use by the caching data store server.
- Modify flushWaiter to throw an assertion error if the locker is not
waiting.
A sgs-server/src/main/java/com/sun/sgs/impl/util/lock/LockAttemptResult.java
- Make this a top-level class and add the key type parameter.
A sgs-server/src/main/java/com/sun/sgs/impl/util/lock/LockConflict.java
- Make this a top-level class and add the key type parameter.
- Replace the conflictingTxn field with conflictingLocker.
A sgs-server/src/main/java/com/sun/sgs/impl/util/lock/LockConflictType.java
- Move to the top-level.
A sgs-server/src/main/java/com/sun/sgs/impl/util/lock/LockManager.java
- Define a new class that contains the parts of the old
LockingAccessCoordinator class that were related to locking, so that
it can be used to implement locking on the caching data store server
as well. This class contains just the basic locking facilities, and
does not include support for transactions, deadlock detection, or
tracking of lock requests. The transaction parameter has been
replaced by the more general Locker, the key has been make a type
parameter, and the description is not included.
- Clarify that the lock and lockNoWait methods can be called again if
they return a non-deadlock conflict.
- Clarify that the locker provided to the lock, lockNoWait, and
waitForLock methods must be associated with this lock manager.
- Simplify the coding of the lock method by calling lockNoWait rather
than lockNoWaitInternal.
- Modify lockNoWait to not call checkLockerNotAborted --
lockNoWaitInternal already makes the same check.
- Modify waitForLock to not fail if a previous lock attempt produced a
deadlock. Due to timing, it is possible that in the gap between
calling lockNoWait and waitForLock, a deadlock would be detected, so
requiring there to be no deadlock is not practical.
- Add the releaseLock, getOwners, and getWaiters methods.
- Document lockNoWaitInternal, waitForLockInternal, and
releaseLockInternal.
- Modify lockNoWaitInternal and waitForLockInternal to use the new
Locker.clearConflict method.
- Modify lockNoWaitInternal method to remove some logging that is
redundant when there is no deadlock detection.
- Modify the waitForLockInternal method to call the new
Locker.getLockTimeoutTime method.
- Modify the waitForLockInternal method to check whether the locker has
obtained ownership before deciding that the lock attempt has failed.
Also flush waiters within the same synchronized block. These changes
avoid a thread hazard where the lock is released by another locker at
the same time that this method decides that the request has timed out
or is interrupted.
- Move the addCheckOverflow method from LockManager to Numbers, so that
it can be used by other callers.
- Add the releaseLockInternal method, with support for lock downgrades.
Call notifyAll now that there may be multiple waiters.
A sgs-server/src/main/java/com/sun/sgs/impl/util/lock/LockRequest.java
- Make a top-level class and add the key type parameter.
- Add accessor methods and make fields private.
A sgs-server/src/main/java/com/sun/sgs/impl/util/lock/Locker.java
- Make a top-level class and add the key type parameter.
- Move the currentSync field to the lock manager, and remove fields
related to transactions.
- Remove the waitingFor field and let subclasses implement the
getWaitingFor method.
- Remove the conflict field, replace the setConflict method with the
clearConflict method, and provide default implementations that do not
record conflicts.
- Add a field and accessor method for the associated lock manager.
- Add the getLockTimeoutTime and newLockRequest methods.
A sgs-server/src/main/java/com/sun/sgs/impl/util/lock/MultiLockManager.java
- Add a new class for managing lock conflicts where locks are not held
by transactions and the locker can make simultaneous request from
multiple threads. This class supports lock downgrades.
A sgs-server/src/main/java/com/sun/sgs/impl/util/lock/MultiLocker.java
- Add a new class to record information about an entity that requests
locks from a MultiLockManager.
A sgs-server/src/main/java/com/sun/sgs/impl/util/lock/TxnLockManager.java
- Add a new class for managing lock conflicts as part of a transaction.
This class supports deadlock checking.
- Modify DeadlockChecker to store TxnLockers.
- Modify DeadlockChecker.checkInternal to set conflict to the original
request at the lowest recursion level. I can't figure out a case
where doing this would be needed, but Keith sent me a stack trace
which showed a NullPointerException in the check method in the case
where the victim is not the root locker resulting from the conflict
field not being set, so this is a defensive change.
- Modify DeadlockChecker.getWaiterInfo to use lists for the collection
of lock owners, to fit better with parameterized types.
A sgs-server/src/main/java/com/sun/sgs/impl/util/lock/TxnLocker.java
- Add a new class to record information about an entity that requests
locks from a TxnLockManager.
A sgs-server/src/main/java/com/sun/sgs/impl/util/lock/package-info.java
- Add package documentation.
M sgs-server/src/main/etc/findbugs-exclude.xml
- Move NN_NAKED_NOTIFY exclusion from LockingAccessCoordinator to the
new LockManager class.
- Remove LockingAccessCoordinator NO_NOTIFY_NOT_NOTIFYALL exclusions --
we're now calling notifyAll.
- Rename LockingAccessCoordinator.Locker to LockerImpl.
- Do some alphabetizing.
M sgs-server/src/test/java/com/sun/sgs/test/impl/kernel/TestLockingAccessCoordinator.java
- Modify testAccessedObjectsDetailDeadlock to use access coordinator
APIs.
- Move test methods that used internal locking APIs to the new lock
manager tests.
A sgs-server/src/test/java/com/sun/sgs/test/impl/util/TestNumbers.java
- Add tests for the Numbers class.
A sgs-server/src/test/java/com/sun/sgs/test/impl/util/lock/TestLockManager.java
- Add a new test for the LockManager class containing standard tests for
the APIs plus the concurrent tests from TestLockingAccessCoordinator
that don't depend on transactions. Also add a couple upgrade tests.
- Modify the AcquireLock method to track exceptions that occur during
the call to lockNoWait and make sure they get reported, rather than
just making it seem like the operation failed to block.
A sgs-server/src/test/java/com/sun/sgs/test/impl/util/lock/TestMultiLockManager.java
- Add a new test for the MultiLockManager class.
A sgs-server/src/test/java/com/sun/sgs/test/impl/util/lock/TestTxnLockManager.java
- Add a new test for TxnLockManager class, including
transaction-specific tests from TestLockingAccessCoordinator.
- Add some deadlock tests where the lock requester wins.