-- TiogaSelectionLocksImpl.mesa Edited by Paxton on December 28, 1982 2:25 pm
Last Edited by: Maxwell, January 6, 1983 11:57 am
DIRECTORY
Process USING [GetCurrent],
Rope USING [ROPE],
TiogaSelection,
TiogaDocument USING [SelectionId],
TiogaLocks USING [Unlock],
TiogaNode USING [RefBranchNode];
TiogaSelectionLocksImpl: CEDAR MONITOR
IMPORTS Process, TiogaLocks
EXPORTS TiogaSelection = BEGIN
OPEN TiogaSelection;
LockRec:
TYPE =
RECORD [
process: PROCESS ← NIL, -- the process holding the lock
whoLast, whoFirst: Rope.ROPE, -- the last lockers
count, maxCount: [0..255] ← 0 -- number of times inside the lock
];
LockRef: TYPE = REF LockRec;
pSelLock: LockRef ← NEW[LockRec];
sSelLock: LockRef ← NEW[LockRec];
fSelLock: LockRef ← NEW[LockRec];
unlocked: CONDITION;
UnlockDocAndPSel:
PUBLIC
PROC [root: TiogaNode.RefBranchNode] = {
TiogaLocks.Unlock[root]; UnlockSel[primary] };
LockBothSelections:
PUBLIC
PROC [who: Rope.
ROPE] = {
LockSel[primary, who]; LockSel[secondary, who] };
UnlockBothSelections:
PUBLIC
PROC = { UnlockSel[primary]; UnlockSel[secondary] };
LockSel:
PUBLIC
ENTRY
PROC [selection: TiogaDocument.SelectionId, who: Rope.
ROPE] = {
lock the selection so that no other process can change it
ENABLE UNWIND => NULL;
myProcess: PROCESS;
lock: LockRef =
SELECT selection
FROM
primary => pSelLock, secondary => sSelLock, feedback => fSelLock, ENDCASE => ERROR;
TRUSTED {myProcess ← LOOPHOLE[Process.GetCurrent[]]};
IF myProcess#lock.process
THEN
BEGIN
WHILE lock.count>0 DO WAIT unlocked; ENDLOOP;
lock.process ← myProcess;
END;
IF lock.count=0 THEN lock.whoFirst ← who ELSE lock.whoLast ← who;
lock.count ← lock.count+1;
lock.maxCount ← MAX[lock.maxCount, lock.count];
};
UnlockSel:
PUBLIC
ENTRY
PROC [selection: TiogaDocument.SelectionId ← primary] = {
give up lock on the selection
ENABLE UNWIND => NULL;
lock: LockRef =
SELECT selection
FROM
primary => pSelLock, secondary => sSelLock, feedback => fSelLock, ENDCASE => ERROR;
TRUSTED {IF lock.process # Process.GetCurrent[] THEN ERROR};
IF (lock.count ← lock.count-1) > 0 THEN RETURN;
lock.whoLast ← lock.whoFirst ← NIL;
lock.maxCount ← 0;
BROADCAST unlocked };
END...