TiogaLocks.mesa; Edited by Paxton on July 11, 1983 1:49 pm
Last Edited by: Maxwell, January 6, 1983 10:32 am
DIRECTORY
Rope USING [ROPE],
TiogaNode USING [RefBranchNode];
TiogaLocks: CEDAR DEFINITIONS = BEGIN
RefBranchNode: TYPE = TiogaNode.RefBranchNode;
Declarations
LockRef: TYPE = REF LockRecord;
LockRecord: TYPE = MONITORED RECORD [
waitingForWrite: INTEGER ← 0, -- number of processes waiting for write access to this document
count, maxCount: [0..255] ← 0, -- number of times have entered this lock
process: PROCESSNIL, -- the unique process which has write access to this document
whoLast, whoFirst: Rope.ROPE, -- provided by the lockers
unlocked: CONDITION -- raised when the lock is freed
];
Access: TYPE = { read, write };
Procedures
Lock: PROC [doc: RefBranchNode, who: Rope.ROPE, access: Access ← write]
RETURNS [LockRef];
Can only lock a document if
(1) it is unlocked, or
(2) current process has a write lock on it already
If neither holds, then waits until it can lock it.
Note that cannot convert a read lock into a write lock. (Implementation limitation.)
Many processes can have read locks; only one can have a write lock.
When a write lock is released, all viewers for the document have their tdd.dirty bit set true.
LockBoth: PROC [
doc1, doc2: RefBranchNode, who: Rope.ROPE, access1, access2: Access ← write]
RETURNS [lock1, lock2: LockRef];
Like two calls on Lock, but orders the calls according to LockOrder.
LockOrder: PROC [doc1, doc2: RefBranchNode] RETURNS [BOOL] = INLINE {
RETURN [LOOPHOLE[doc1, INT] <= LOOPHOLE[doc2, INT]] };
Returns true if ok to lock doc1 before doc2.
Unlock: PROC [doc: RefBranchNode];
Reduces the lock count for the document.
WaitingForWrite: PROC [lock: LockRef] RETURNS [BOOL] = INLINE
{ RETURN [lock.waitingForWrite > 0] };
Returns true iff some process is waiting to get a write lock for the document.
RegisterForCallAfterReleaseWriteLock: PROC [proc: PROC [doc: RefBranchNode]];
Registered procedure will be called as soon as the write lock is released.
The display update routines use this.
UnregisterForCallAfterReleaseWriteLock: PROC [proc: PROC [doc: RefBranchNode]];
END.