TEditLocks.mesa; Edited by Paxton on October 20, 1982 7:35 am
Last Edited by: Maxwell, January 6, 1983 10:32 am
DIRECTORY
Rope USING [ROPE],
TEditDocument USING [TEditDocumentData],
TextNode USING [Ref];
TEditLocks: CEDAR DEFINITIONS = BEGIN
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: TextNode.Ref, 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: TextNode.Ref, 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: TextNode.Ref] RETURNS [BOOL] = INLINE {
RETURN [LOOPHOLE[doc1, INT] <= LOOPHOLE[doc2, INT]] };
Returns true if ok to lock doc1 before doc2.
Unlock: PROC [doc: TextNode.Ref];
Reduces the lock count for the document.
LockDocAndTdd: PROC [tdd: TEditDocument.TEditDocumentData,
who: Rope.ROPE, access: Access ← write, interrupt, defer: BOOLFALSE] RETURNS [LockRef];
access is for locking the document; interrupt and defer are for locking the tdd
if defer and don't get the tdd lock, then returns nil.
UnlockDocAndTdd: PROC [tdd: TEditDocument.TEditDocumentData];
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.
END.