use of org.apache.derby.iapi.services.locks.Lockable in project derby by apache.
the class Timeout method dumpLock.
/**
* dumpLock puts information about currentLock into currentRow for output later.
* @throws StandardException
*/
private void dumpLock() throws StandardException {
Hashtable<String, Object> attributes = new Hashtable<String, Object>(17);
Object lock_type = currentLock.getQualifier();
// want containerId, segmentId, pageNum, recId from locktable
Lockable lockable = currentLock.getLockable();
// See if the lockable object wants to participate
if (!lockable.lockAttributes(ALL, attributes)) {
currentRow = null;
return;
}
// fields
if (SanityManager.DEBUG) {
SanityManager.ASSERT(attributes.get(VirtualLockTable.LOCKNAME) != null, "lock table can only represent locks that have a LOCKNAME");
SanityManager.ASSERT(attributes.get(VirtualLockTable.LOCKTYPE) != null, "lock table can only represent locks that have a LOCKTYPE");
if (attributes.get(VirtualLockTable.CONTAINERID) == null && attributes.get(VirtualLockTable.CONGLOMID) == null)
SanityManager.THROWASSERT("lock table can only represent locks that are associated with a container or conglomerate");
}
Long conglomId = (Long) attributes.get(VirtualLockTable.CONGLOMID);
if (conglomId == null) {
if (attributes.get(VirtualLockTable.CONTAINERID) != null && tc != null) {
Long value = (Long) attributes.get(VirtualLockTable.CONTAINERID);
conglomId = tc.findConglomid(value.longValue());
attributes.put(VirtualLockTable.CONGLOMID, conglomId);
}
}
Long containerId = (Long) attributes.get(VirtualLockTable.CONTAINERID);
if (containerId == null) {
if (conglomId != null && tc != null) {
try {
containerId = tc.findContainerid(conglomId.longValue());
attributes.put(VirtualLockTable.CONTAINERID, containerId);
} catch (Exception e) {
// just don't do anything
}
}
}
attributes.put(VirtualLockTable.LOCKOBJ, currentLock);
attributes.put(VirtualLockTable.XACTID, String.valueOf(currentLock.getCompatabilitySpace().getOwner()));
attributes.put(VirtualLockTable.LOCKMODE, lock_type.toString());
attributes.put(VirtualLockTable.LOCKCOUNT, Integer.toString(currentLock.getCount()));
attributes.put(VirtualLockTable.STATE, (currentLock.getCount() != 0) ? "GRANT" : "WAIT");
if (tabInfo != null && conglomId != null) {
try {
String tableName = tabInfo.getTableName(conglomId);
attributes.put(VirtualLockTable.TABLENAME, tableName);
} catch (NullPointerException e) {
attributes.put(VirtualLockTable.TABLENAME, conglomId);
}
try {
String indexName = tabInfo.getIndexName(conglomId);
if (indexName != null)
attributes.put(VirtualLockTable.INDEXNAME, indexName);
else {
if (attributes.get(VirtualLockTable.LOCKTYPE).equals("LATCH")) {
// because MODE field is way to short to display this,
// just put it in the indexname field for LATCH only.
attributes.put(VirtualLockTable.INDEXNAME, attributes.get(VirtualLockTable.LOCKMODE));
} else
attributes.put(VirtualLockTable.INDEXNAME, "NULL");
}
} catch (Exception e) {
// we are here because tabInfo.indexCache is null
if (VirtualLockTable.CONTAINERID != null)
attributes.put(VirtualLockTable.INDEXNAME, VirtualLockTable.CONTAINERID);
else
attributes.put(VirtualLockTable.INDEXNAME, "NULL");
}
String tableType = tabInfo.getTableType(conglomId);
attributes.put(VirtualLockTable.TABLETYPE, tableType);
} else {
if (conglomId != null)
attributes.put(VirtualLockTable.TABLENAME, VirtualLockTable.CONGLOMID);
else
attributes.put(VirtualLockTable.TABLENAME, "NULL");
if (VirtualLockTable.CONTAINERID != null)
attributes.put(VirtualLockTable.INDEXNAME, VirtualLockTable.CONTAINERID);
else
attributes.put(VirtualLockTable.INDEXNAME, "NULL");
attributes.put(VirtualLockTable.TABLETYPE, currentLock.toString());
}
currentRow = attributes;
}
use of org.apache.derby.iapi.services.locks.Lockable in project derby by apache.
the class LockTable method dumpLock.
/*
** Private methods
*/
/**
* Convert the lock information into a hashtable.
*/
private Hashtable<String, Object> dumpLock(Latch lock) throws StandardException {
Hashtable<String, Object> attributes = new Hashtable<String, Object>(17);
Object lock_type = lock.getQualifier();
// 4 things we are interested in from the lockable:
// containerId, segmentId, pageNum, recId
Lockable lockable = lock.getLockable();
// see if this lockable object wants to participate
if (!lockable.lockAttributes(flag, attributes))
return null;
// fields
if (SanityManager.DEBUG) {
SanityManager.ASSERT(attributes.get(VirtualLockTable.LOCKNAME) != null, "lock table can only represent locks that have a LOCKNAME");
SanityManager.ASSERT(attributes.get(VirtualLockTable.LOCKTYPE) != null, "lock table can only represent locks that have a LOCKTYPE");
if (attributes.get(VirtualLockTable.CONTAINERID) == null && attributes.get(VirtualLockTable.CONGLOMID) == null)
SanityManager.THROWASSERT("lock table can only represent locks that are associated with a container or conglomerate");
}
if (attributes.get(VirtualLockTable.LOCKNAME) == null || attributes.get(VirtualLockTable.LOCKTYPE) == null)
// can't deal with this for now
return null;
// if the lock has zero count and is an instance of Lock then it
// is a lock that has just been released. Therefore do put it into
// the lock table. This occurs because the Lock object is the real
// live object in the LockTable. Thus when we copied the lock table
// it had a non-zero count, but since then it has been released
// (after we dropped the sync). Note if it is of type ActiveLock
// with zero count there is stil the chance it has been released.
// Less likely, but we still need to fix that at some time.
int lockCount = lock.getCount();
String state;
if (lockCount != 0)
state = "GRANT";
else if (!(lock instanceof org.apache.derby.impl.services.locks.ActiveLock))
return null;
else
state = "WAIT";
Long conglomId = (Long) attributes.get(VirtualLockTable.CONGLOMID);
if (conglomId == null) {
// we need to figure this out
if (attributes.get(VirtualLockTable.CONTAINERID) == null)
// can't deal with this for now
return null;
Long value = (Long) attributes.get(VirtualLockTable.CONTAINERID);
conglomId = tc.findConglomid(value.longValue());
attributes.put(VirtualLockTable.CONGLOMID, conglomId);
}
attributes.put(VirtualLockTable.LOCKOBJ, lock);
Object owner = lock.getCompatabilitySpace().getOwner();
attributes.put(VirtualLockTable.XACTID, (owner == null) ? "<null>" : owner.toString());
attributes.put(VirtualLockTable.LOCKMODE, lock_type.toString());
attributes.put(VirtualLockTable.LOCKCOUNT, Integer.toString(lockCount));
attributes.put(VirtualLockTable.STATE, state);
String tableName = tabInfo.getTableName(conglomId);
attributes.put(VirtualLockTable.TABLENAME, tableName);
String indexName = tabInfo.getIndexName(conglomId);
if (indexName != null)
attributes.put(VirtualLockTable.INDEXNAME, indexName);
String tableType = tabInfo.getTableType(conglomId);
attributes.put(VirtualLockTable.TABLETYPE, tableType);
return attributes;
}
use of org.apache.derby.iapi.services.locks.Lockable in project derby by apache.
the class LockControl method addLock.
/**
* Add a lock into this control, granted it if possible.
*
* This can be entered in several states.
*
* </OL>
* <LI>The Lockable is locked (granted queue not empty), and there are no waiters (waiting queue is empty)
* <LI>The Lockable is locked and there are waiters
* <LI>The Lockable is locked and there are waiters and the first is potentially granted
* <LI>The Lockable is unlocked and there are waiters and the first is potentially granted. Logically the item is
* still locked, it's just that the lock has just been released and the first waker has not woken up yet.
* </OL>
* This call is never entered when the object is unlocked and there are no waiters.
*
* 1) The Lockable has just been unlocked,
*/
public Lock addLock(LockTable ls, CompatibilitySpace compatibilitySpace, Object qualifier) {
if (SanityManager.DEBUG) {
if (!(!isUnlocked() || (firstWaiter() != null)))
SanityManager.THROWASSERT("entered in totally unlocked mode " + isUnlocked() + " " + (firstWaiter() != null));
}
// If there are other waiters for this lock then we
// will only grant this lock if we already hold a lock.
// This stops a lock being frozen out while compatible locks
// jump past it.
boolean grantLock = false;
boolean otherWaiters = (firstWaiter() != null);
Lock lockItem = null;
Lockable lref = ref;
// If we haven't been able to grant the lock yet then see if we hold a
// lock already that we are compatible with and there are no granted
// incompatible locks. If the object appears unlocked (due to a just
// released lock, but the first waiter hasn't woken yet)
// then we obviously don't hold a lock, so just join the wait queue.
boolean spaceHasALock = false;
boolean noGrantAtAll = false;
if (!isUnlocked()) {
boolean selfCompatible = lref.lockerAlwaysCompatible();
int index = 0;
int endIndex = firstGrant == null ? granted.size() : 0;
do {
Lock gl = firstGrant == null ? granted.get(index) : firstGrant;
boolean sameSpace = (gl.getCompatabilitySpace() == compatibilitySpace);
// our own locks then yes, we can be granted.
if (sameSpace && selfCompatible) {
spaceHasALock = true;
if (noGrantAtAll)
break;
if (qualifier == gl.getQualifier())
lockItem = gl;
grantLock = true;
continue;
}
// then we can't be granted, give up right away.
if (!lref.requestCompatible(qualifier, gl.getQualifier())) {
grantLock = false;
lockItem = null;
// because we need to ensure that canSkip is set correctly
if (spaceHasALock)
break;
noGrantAtAll = true;
}
if (!noGrantAtAll && (sameSpace || !otherWaiters)) {
grantLock = true;
}
} while (++index < endIndex);
}
if (lockItem != null) {
if (SanityManager.DEBUG) {
if (!grantLock) {
SanityManager.THROWASSERT("lock is not granted !" + lockItem);
}
}
// we already held a lock of this type, just bump the lock count
lockItem.count++;
return lockItem;
}
if (grantLock) {
lockItem = new Lock(compatibilitySpace, lref, qualifier);
grant(lockItem);
return lockItem;
}
ActiveLock waitingLock = new ActiveLock(compatibilitySpace, lref, qualifier);
// then this lock can be granted by skipping other waiters.
if (spaceHasALock) {
waitingLock.canSkip = true;
}
if (waiting == null)
waiting = new java.util.LinkedList<Lock>();
// Add lock to the waiting list
addWaiter(waitingLock, ls);
if (waitingLock.canSkip) {
lastPossibleSkip = waitingLock;
}
return waitingLock;
}
use of org.apache.derby.iapi.services.locks.Lockable in project derby by apache.
the class LockControl method isGrantable.
/**
* This routine can be called to see if a lock currently on the wait
* list could be granted. If this lock has waiters ahead of it
* then we do not jump over the waiter(s) even if we can be granted.
* This avoids the first waiter being starved out.
*/
public boolean isGrantable(boolean noWaitersBeforeMe, CompatibilitySpace compatibilitySpace, Object qualifier) {
if (isUnlocked())
return true;
boolean grantLock = false;
Lockable lref = ref;
List<Lock> lgranted = granted;
{
// Check to see if the only locks on the granted queue that
// we are incompatible with are locks we own.
boolean selfCompatible = lref.lockerAlwaysCompatible();
int index = 0;
int endIndex = firstGrant == null ? lgranted.size() : 0;
do {
Lock gl = firstGrant == null ? lgranted.get(index) : firstGrant;
boolean sameSpace = (gl.getCompatabilitySpace() == compatibilitySpace);
if (sameSpace && selfCompatible) {
// if it's one of our locks and we are always compatible
// with our own locks then yes, we can be granted.
grantLock = true;
continue;
} else if (!lref.requestCompatible(qualifier, gl.getQualifier())) {
// If we are not compatible with some already granted lock
// then we can't be granted, give up right away.
grantLock = false;
break;
} else {
if (sameSpace || noWaitersBeforeMe) {
grantLock = true;
}
}
} while (++index < endIndex);
}
return (grantLock);
}
Aggregations