DIRECTORY TiogaLocks, TiogaLocksPrivate, Process USING [GetCurrent], Rope USING [ROPE], TiogaNode USING [RefBranchNode]; TiogaLocksImpl: CEDAR MONITOR LOCKS lock USING lock: LockRef IMPORTS TiogaLocks, TiogaLocksPrivate, Process EXPORTS TiogaLocks = BEGIN OPEN TiogaLocks; LockBoth: PUBLIC PROC [doc1, doc2: TiogaNode.RefBranchNode, who: Rope.ROPE, access1, access2: Access _ write] RETURNS [lock1, lock2: LockRef] = { IF (doc1=doc2 AND access1=write) OR (doc1 # doc2 AND LockOrder[doc1, doc2]) THEN { lock1 _ Lock[doc1, who, access1]; lock2 _ Lock[doc2, who, access2] } ELSE { lock2 _ Lock[doc2, who, access2]; lock1 _ Lock[doc1, who, access1] }}; Lock: PUBLIC PROC [ doc: TiogaNode.RefBranchNode, who: Rope.ROPE, access: Access _ write] RETURNS [lock: LockRef] = { IF doc=NIL THEN ERROR; IF (lock _ TiogaLocksPrivate.GetLock[doc])=NIL THEN RETURN; LockIt[lock, who, access, doc]; }; LockIt: ENTRY PROC [ lock: LockRef, who: Rope.ROPE, access: Access, doc: TiogaNode.RefBranchNode] = { ENABLE UNWIND => NULL; myProcess: PROCESS; TRUSTED {myProcess _ LOOPHOLE[Process.GetCurrent[]]}; IF access=read THEN { IF lock.process # myProcess THEN WHILE lock.process # NIL DO -- wait for write lock to clear WAIT lock.unlocked; ENDLOOP } ELSE { -- want write access IF lock.process # myProcess THEN { -- I don't have a write lock on it already IF lock.count > 0 THEN { -- doc is locked lock.waitingForWrite _ lock.waitingForWrite+1; WHILE lock.count > 0 DO -- wait for all locks to clear WAIT lock.unlocked; ENDLOOP; lock.waitingForWrite _ lock.waitingForWrite-1 }; lock.process _ myProcess }}; IF lock.count=0 THEN lock.whoFirst _ who ELSE lock.whoLast _ who; lock.count _ lock.count+1; lock.maxCount _ MAX[lock.maxCount, lock.count] }; Unlock: PUBLIC PROC [doc: TiogaNode.RefBranchNode] = { lock: LockRef; IF doc=NIL THEN ERROR; IF (lock _ TiogaLocksPrivate.GetLock[doc])=NIL THEN RETURN; UnlockIt[lock, doc]; }; UnlockIt: ENTRY PROC [lock: LockRef, doc: TiogaNode.RefBranchNode] = { ENABLE UNWIND => NULL; IF lock=NIL THEN RETURN; IF lock.count <= 0 THEN ERROR; TRUSTED {IF lock.process # NIL AND lock.process # Process.GetCurrent[] THEN ERROR}; IF (lock.count _ lock.count-1) > 0 THEN RETURN; -- still locked IF lock.process # NIL THEN { -- had write lock IF dirtyDocProc # NIL THEN dirtyDocProc[doc]; lock.process _ NIL }; lock.whoFirst _ lock.whoLast _ NIL; lock.maxCount _ 0; BROADCAST lock.unlocked; }; dirtyDocProc: PROC [doc: RefBranchNode]; RegisterForCallAfterReleaseWriteLock: PUBLIC PROC [proc: PROC [doc: RefBranchNode]] = { dirtyDocProc _ proc; -- someday change this so have multiple proc's registered }; UnregisterForCallAfterReleaseWriteLock: PUBLIC PROC [ proc: PROC [doc: RefBranchNode]] = { dirtyDocProc _ NIL }; END... The following belong in TiogaLayout (?) LockDocAndTdd: PUBLIC PROC [tdd: TiogaDocument.TiogaDocumentData, who: Rope.ROPE, access: Access _ write, interrupt, defer: BOOL _ FALSE] RETURNS [lock: LockRef] = { IF ~TiogaDocument.SpinAndLock[tdd, "LockDocAndTdd1", interrupt, defer] THEN RETURN [NIL]; DO doc: TiogaNode.RefBranchNode _ tdd.text; TiogaDocument.Unlock[tdd]; -- must unlock tdd before try to lock the document. IF doc=NIL THEN RETURN [NIL]; lock _ Lock[doc, who, access]; IF ~TiogaDocument.SpinAndLock[tdd, "LockDocAndTdd2", interrupt, defer] THEN { UnlockIt[lock, doc]; RETURN [NIL] }; IF tdd.text = doc THEN RETURN; -- all went well UnlockIt[lock, doc]; -- document changed during the time we had tdd unlocked ENDLOOP }; UnlockDocAndTdd: PUBLIC PROC [tdd: TiogaDocument.TiogaDocumentData] = { IF tdd.text#NIL THEN Unlock[tdd.text]; TiogaDocument.Unlock[tdd] }; άTiogaLocksImpl.mesa Edited by Paxton on July 11, 1983 1:49 pm Last Edited by: Maxwell, January 6, 1983 11:43 am Like two calls on Lock, but orders the calls according to LockOrder. must lock before read tdd.text ΚΊ˜Jšœ=™=JšΟk1™1J˜š ˜ Jšœ ˜ Jšœ˜Jšœœ˜Jšœœœ˜Jšœ œ˜ J˜—šœ ˜Jšœœ˜Jšœ'˜.Jšœœœ ˜+—J˜šΟnœœœ1œ˜KJšœ"œ˜EJšœD™Dš œ œœœœ˜RJšœD˜D—JšœI˜MJ™—šžœ œ˜Jšœ(œ˜EJšœ˜Jšœœœœ˜Jšœ)œœœ˜;J˜˜J˜——unitšžœœœ˜Jšœœ3˜PJšœœœ˜Jšœ œ˜Jšœœ˜5codešœ œ˜šœ˜ šœœœΟc˜;Lšœœ˜———šœŸ˜šœœŸ*˜MšœœŸ˜)L˜.šœœŸ˜6Lšœœ˜—L˜0—Lšœ˜——Lšœœœ˜AL˜Lšœœ˜1—J˜šžœœœ#˜6Jšœ˜Jšœœœœ˜Jšœ)œœœ˜;J˜J˜—J˜šžœœœ2˜FJšœœœ˜Jšœœœœ˜Jšœœœ˜Jš œœœœ%œœ˜SJšœ!œœŸ˜?šœœœŸ˜.Jšœœœ˜-Jšœœ˜—Jšœœ˜#J˜Jš œ˜J˜—J˜Jšœœ˜(J˜šž$œ œœ˜WJšœŸ9˜NJ˜J˜—šž&œ œ˜5Jšœœ˜$Jšœœ˜—J˜Jšœ˜J˜J˜'J˜šž œœœ'˜AJšœ œ,œœ˜GJšœ˜šœEœœœ˜YJšœ™—š˜Jšœ(˜(JšœŸ3˜NJš œœœœœ˜Jšœ˜šœEŸœ˜MJšœœœ˜$—JšœœœŸ˜/JšœŸ7˜LJšœ˜ ——J˜šžœ œ+˜GJšœ œœ˜&Jšœ˜—J˜—…—$Ί