001: /*
002:
003: Derby - Class org.apache.derby.iapi.services.locks.Lockable
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.iapi.services.locks;
023:
024: import java.util.Hashtable;
025:
026: /**
027: Any object that needs to be locked must implement Lockable.
028: This allows a generic lock manager that can have locking policies
029: defined on a per-object basis.
030:
031: A request to lock the object takes a qualifier, this qualifier may be
032: used the object to implement a complex locking policy, e.g. traditional
033: database shared, update and exclusive locks.
034: <P>
035: The lock manager uses this ordered protocol to determine if a lock request on a
036: Lockable <TT> L </TT> with qualifier <TT> Q1 </TT> in compatiblity space
037: <TT> CS1 </TT> can be granted:
038: <OL>
039: <LI>If no locks are held on <TT> L </TT> in any compatability space then the
040: request is granted.
041: <LI>If <TT>L.requestCompatible(Q1)</TT> returns true then the lock is granted.
042: <LI>Otherwise the request is granted if the following expression evaluates
043: to true for every other lock <TT>{ CSn, Qn}</TT> held on <TT> L </TT>
044: <UL>
045: <LI> <PRE> ( ( CSn == CS1 ) && L.lockerAlwaysCompatible() ) </PRE>
046: <LI> <PRE> || (L.reqestCompatible(Q1, Qn)) </PRE>
047: </UL>
048: </OL>
049: <BR>
050: If the request is granted then a call is made to <TT> L.lockEvent(CS1, Q1) </TT>.
051: <BR>
052: When the lock is released a call is made to <TT> L.unlockEvent(CS1, Q1) </TT>.
053: <P>
054: The lock manager uses equals() and hashCode() to identify unique Lockables.
055: <BR>
056: If the class implementing Lockable requires that each instance of class
057: correspond to a different locked object then the equals() method must test
058: equality via the reference equality test (==), this is the default behaviour
059: for equality.
060: <BR>
061: If the class implementing Lockable require that each instance of the class
062: that has the same value (as defined by the class) corresponds to a locked
063: object then its equals() method must reflect that, e.g. by testing equality
064: of its fields. In this case the first Lockable to be locked will be kept
065: by lock manager as the key for the lock. Thus even after the first caller
066: unlocks the obejct, its reference will still be kept by the lock manager.
067: Thus Lockable's that per value equality must be designed so that they
068: are never re-used for different lockable concepts.
069: <BR>
070: In either case the equals() method must accept a reference to an object of
071: a different type.
072: <BR>
073: As per standard hashtable rules the value returned by hashCode() must be in sync
074: with the equals() method.
075:
076: <BR>
077: MT - Mutable - : single thread required, synchronization is provided by the lock manager.
078: If the class implementing Lockable uses value equality then it must have an immutable identity.
079: */
080:
081: public interface Lockable {
082:
083: /**
084: Note the fact the object is locked. Performs required actions
085: to ensure that unlockEvent() work correctly.
086: This method does not actually perform any locking of the
087: object, the locking mechanism is provided by the lock manager.
088: <P>
089: If the class supports multiple lockers of the object then this method
090: will be called once per locker, each with their own qualifier.
091: <P>
092: Must only be called by the lock manager. Synchronization will be handled
093: by the lock manager.
094: */
095: public void lockEvent(Latch lockInfo);
096:
097: /**
098: Return true if the requested qualifier is compatible with the already granted
099: qualifier.
100: */
101: public boolean requestCompatible(Object requestedQualifier,
102: Object grantedQualifier);
103:
104: /**
105: Returns true if any lock request on a Lockable L in a compatibility space CS1 is compatible
106: with any other lock held on L in CS1.
107:
108: */
109: public boolean lockerAlwaysCompatible();
110:
111: /**
112: Note that the object has been unlocked
113: <P>
114: Must only be called by the lock manager. Synchronization will be handled
115: by the lock manager.
116: */
117: public void unlockEvent(Latch lockInfo);
118:
119: /**
120: If this lockable object wants to participate in a diagnostic virtual
121: lock table, then put any relavent attributes of this lock into the
122: attributes list (the attribute must be an immutable object). The list
123: of attributes of interest to the virtual lock table can be found in
124: VirtualLockTable. The toString method will be called by the VirtualTable
125: on the attribute value for display.
126: <P>
127: @param flag use the bits in this int to decide if the user is
128: interested in this kind of lockable object. The bits are defined in
129: VirtualLockTable. For instance, the user may only ask
130: for TABLE_AND_ROWLOCK and if this is not a table or row lock, then
131: don't paritipate.
132: @param attributes if this decides to participate, put all relavent
133: attributes into the Hashtable. The complete list of interesting
134: attributes is listed in VirtualLockTable.
135: The following attributes must be present for all participating
136: lockables:
137: VirtualLockTable.LOCKNAME,
138: VirtualLockTable.LOCKTYPE,
139: either VirtualLockTable.CONTAINERID or VirtualLockTable.CONGLOMID,
140: <P>
141: MT - this routine must be MP safe, caller will not be single threading
142: the lock manager.
143: <P>
144: @return true if this object has diagnostic information to add to the
145: virtual lock table. If this object either does not want to participate
146: in the diagnostic virtual lock table or none of the attributes
147: requested are attributes of this lock, returns false.
148:
149: @see VirtualLockTable
150: */
151: public boolean lockAttributes(int flag, Hashtable attributes);
152: }
|