001: /*
002:
003: Derby - Class org.apache.derby.impl.services.locks.ActiveLock
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.services.locks;
023:
024: import org.apache.derby.iapi.services.locks.Lockable;
025: import org.apache.derby.iapi.services.locks.C_LockFactory;
026:
027: import org.apache.derby.iapi.error.StandardException;
028: import org.apache.derby.iapi.services.context.ContextService;
029: import org.apache.derby.iapi.services.context.ContextManager;
030: import org.apache.derby.iapi.services.sanity.SanityManager;
031:
032: /**
033: A Lock represents a granted or waiting lock request.
034:
035: <BR>
036: MT - Mutable - Immutable identity : Thread Aware
037: */
038:
039: public final class ActiveLock extends Lock {
040:
041: /**
042: Set to true if the object waiting on this thread should wake up,
043: MT - mutable - java synchronized(this)
044: */
045: byte wakeUpNow;
046:
047: /**
048: Set to true if the Lock potentially could be granted.
049:
050: MT - mutable - single thread required
051: */
052: boolean potentiallyGranted;
053:
054: /**
055: If true then this lock can be granted even if
056: it is not the first lock request on the wait queue.
057: This can occur if the compatability space already holds
058: a lock on the object.
059: */
060: protected boolean canSkip;
061:
062: /**
063: Initialize the lock, should be seen as part of the constructor. A future
064: version of this class may become mutable - mutable identity.
065:
066: MT - single thread required
067: */
068: protected ActiveLock(Object space, Lockable ref, Object qualifier) {
069: super (space, ref, qualifier);
070: }
071:
072: /**
073: Set the potentially granted flag, returns true if the
074: flag changed its state.
075:
076: MT - single thread required
077: */
078: protected boolean setPotentiallyGranted() {
079: if (!potentiallyGranted) {
080: potentiallyGranted = true;
081: return true;
082: }
083: return false;
084: }
085:
086: /**
087: Clear the potentially granted flag.
088:
089: MT - single thread required
090: */
091: protected void clearPotentiallyGranted() {
092: potentiallyGranted = false;
093: }
094:
095: /**
096: Wait for a lock to be granted, returns when the lock is granted.
097: <P>
098: The sleep wakeup scheme depends on the two booleans wakeUpNow & potentiallyGranted.
099:
100: MT - Single thread required - and assumed to be the thread requesting the lock.
101:
102: @return true if the wait ended early (ie. someone else woke us up).
103:
104: @exception StandardException timeout, deadlock or thread interrupted
105: */
106: protected synchronized byte waitForGrant(int timeout)
107: throws StandardException {
108:
109: if (wakeUpNow == Constants.WAITING_LOCK_IN_WAIT) {
110:
111: try {
112:
113: if (timeout == C_LockFactory.WAIT_FOREVER) {
114: wait();
115: } else if (timeout > 0) {
116: wait(timeout);
117: }
118:
119: } catch (InterruptedException ie) {
120: throw StandardException.interrupt(ie);
121: }
122: }
123:
124: byte why = wakeUpNow;
125: wakeUpNow = Constants.WAITING_LOCK_IN_WAIT;
126: return why;
127: }
128:
129: /**
130: Wake up anyone sleeping on this lock.
131:
132: MT - Thread Safe
133: */
134: protected synchronized void wakeUp(byte why) {
135: // If we were picked as a deadlock victim then don't
136: // override the wakeup reason with another one.
137: if (wakeUpNow != Constants.WAITING_LOCK_DEADLOCK)
138: wakeUpNow = why;
139: notify();
140: }
141: }
|