Search in sources :

Example 1 with Lockable

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;
}
Also used : Hashtable(java.util.Hashtable) Lockable(org.apache.derby.iapi.services.locks.Lockable) StandardException(org.apache.derby.shared.common.error.StandardException)

Example 2 with Lockable

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;
}
Also used : Hashtable(java.util.Hashtable) Lockable(org.apache.derby.iapi.services.locks.Lockable)

Example 3 with Lockable

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;
}
Also used : Lockable(org.apache.derby.iapi.services.locks.Lockable)

Example 4 with Lockable

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);
}
Also used : Lockable(org.apache.derby.iapi.services.locks.Lockable)

Aggregations

Lockable (org.apache.derby.iapi.services.locks.Lockable)4 Hashtable (java.util.Hashtable)2 StandardException (org.apache.derby.shared.common.error.StandardException)1