synchronized int unlockReference(LockTable lset, Lockable ref, Object qualifier, Object group) { // look for locks matching our reference and qualifier. HashMap dl = (HashMap) groups.get(group); if (dl == null) return 0; Lock lockInGroup = lset.unlockReference(this, ref, qualifier, dl); if (lockInGroup == null) { return 0; } if (lockInGroup.getCount() == 1) { if (dl.isEmpty()) { groups.remove(group); saveGroup(dl); if ((callbackGroup != null) && group.equals(callbackGroup)) { nextLimitCall = limit; } } return 1; } // the lock item will be left in the group lockInGroup.count--; dl.put(lockInGroup, lockInGroup); return 1; }
/** * Return a count of the number of locks held by this space. The argument bail indicates at which * point the counting should bail out and return the current count. This routine will bail if the * count is greater than bail. Thus this routine is intended to for deadlock code to find the * space with the fewest number of locks. */ synchronized int deadlockCount(int bail) { int count = 0; for (Iterator it = groups.values().iterator(); it.hasNext(); ) { HashMap group = (HashMap) it.next(); for (Iterator locks = group.keySet().iterator(); locks.hasNext(); ) { Lock lock = (Lock) locks.next(); count += lock.getCount(); if (count > bail) return count; } } return count; }
/** Add a lock to a group. */ protected synchronized void addLock(Object group, Lock lock) throws StandardException { Lock lockInGroup = null; HashMap dl = (HashMap) groups.get(group); if (dl == null) { dl = getGroupMap(group); } else if (lock.getCount() != 1) { lockInGroup = (Lock) dl.get(lock); } if (lockInGroup == null) { lockInGroup = lock.copy(); dl.put(lockInGroup, lockInGroup); } lockInGroup.count++; if (inLimit) return; if (!group.equals(callbackGroup)) return; int groupSize = dl.size(); if (groupSize > nextLimitCall) { inLimit = true; callback.reached( this, group, limit, new LockList(java.util.Collections.enumeration(dl.keySet())), groupSize); inLimit = false; // see when the next callback should occur, if the callback // failed to release a sufficent amount of locks then // delay until another "limit" locks are obtained. int newGroupSize = dl.size(); if (newGroupSize < (limit / 2)) nextLimitCall = limit; else if (newGroupSize < (nextLimitCall / 2)) nextLimitCall -= limit; else nextLimitCall += limit; } }
private void mergeGroups(HashMap from, HashMap into) { for (Iterator e = from.keySet().iterator(); e.hasNext(); ) { Object lock = e.next(); Object lockI = into.get(lock); if (lockI == null) { // lock is only in from list into.put(lock, lock); } else { // merge the locks Lock fromL = (Lock) lock; Lock intoL = (Lock) lockI; intoL.count += fromL.getCount(); } } }