DIRECTORY FS USING [Lock], FSBackdoor USING [Version], FSLock USING [ActiveFile, LookupLock, RemoveLock], Rope USING [ROPE]; FSLockImpl: CEDAR MONITOR LOCKS a USING a: FSLock.ActiveFile IMPORTS FSLock EXPORTS FSLock = BEGIN LockRecord: PUBLIC PROC [volumePrefix, nameBody: Rope.ROPE, version: FSBackdoor.Version] RETURNS [a: FSLock.ActiveFile, ok: BOOLEAN] = BEGIN InnerLockRecord: ENTRY PROC [a: FSLock.ActiveFile] RETURNS [{gotIt, wait, dead}] = BEGIN IF a.nameBody = NIL THEN RETURN [dead]; IF a.recordLock THEN RETURN [wait]; a.recordLock _ TRUE; RETURN [gotIt]; END; DO a _ FSLock.LookupLock[volumePrefix, nameBody, version]; SELECT InnerLockRecord[a] FROM gotIt => ok _ TRUE; wait => ok _ FALSE; dead => LOOP; ENDCASE => ERROR; EXIT; ENDLOOP; END; checkAgain: CONDITION; LockAttachedToRecord: PUBLIC PROC [a: FSLock.ActiveFile] = BEGIN InnerLockAttachedToRecord: PUBLIC ENTRY PROC [a: FSLock.ActiveFile] = BEGIN WHILE a.recordLock DO WAIT checkAgain ENDLOOP; IF a.nameBody = NIL THEN ERROR; a.recordLock _ TRUE; END; IF NOT a.recordLock THEN ERROR; InnerLockAttachedToRecord[a.attachedTo]; END; WaitForRecord: PUBLIC ENTRY PROC [a: FSLock.ActiveFile] = { WHILE a.nameBody # NIL AND a.recordLock DO WAIT checkAgain ENDLOOP }; ReleaseRecord: PUBLIC PROC [a: FSLock.ActiveFile] = BEGIN InnerReleaseRecord: ENTRY PROC [a: FSLock.ActiveFile] = BEGIN IF a.recordLock -- may be no record lock to release THEN BEGIN a.recordLock _ FALSE; IF a.fileLockCount = 0 THEN FSLock.RemoveLock[a]; BROADCAST checkAgain; END; END; IF a = NIL THEN RETURN; -- release of NIL is a nop! InnerReleaseRecord[a]; END; LockFile: PUBLIC ENTRY PROC [a: FSLock.ActiveFile, lock: FS.Lock] RETURNS [ok: BOOLEAN] = BEGIN IF NOT a.recordLock THEN ERROR; IF a.fileLockCount = 0 THEN a.fileLock _ (IF lock = write THEN write ELSE read) ELSE { IF lock = write OR (lock = read AND a.fileLock = write) THEN RETURN [FALSE] }; a.fileLockCount _ a.fileLockCount + 1; RETURN [TRUE]; END; GetAttachment: PUBLIC ENTRY PROC [a: FSLock.ActiveFile] RETURNS [FSLock.ActiveFile] = BEGIN WHILE a.recordLock DO WAIT checkAgain ENDLOOP; IF a.fileLockCount = 0 THEN ERROR; RETURN [a.attachedTo]; END; ReportClose: PUBLIC PROC [a: FSLock.ActiveFile] = BEGIN ReleaseFile: ENTRY PROC [a: FSLock.ActiveFile] RETURNS [attachedTo: FSLock.ActiveFile] = BEGIN WHILE a.recordLock DO WAIT checkAgain ENDLOOP; IF a.fileLockCount = 0 THEN ERROR; attachedTo _ a.attachedTo; a.fileLockCount _ a.fileLockCount - 1; IF a.fileLockCount = 0 THEN BEGIN a.fileLock _ none; IF NOT a.recordLock THEN FSLock.RemoveLock[a]; END; END; att: FSLock.ActiveFile _ ReleaseFile[a]; IF att # NIL THEN att _ ReleaseFile[att]; IF att # NIL THEN ERROR; END; END. jFSLockImpl.mesa Last Edited by: Schroeder, November 15, 1983 1:29 pm Procedures exported to FSLock Κχ– "cedar" style˜Icode2šœ™K™4code1šΟk ˜ Lšœœ˜Lšœ œ ˜Lšœœ&˜2Lšœœœ˜—šœ œ˜Lšœœ˜"Lšœ˜Lšœ˜Lšœ˜—šΟi™š Οn œœœœœœ˜†Kš˜šŸœœœœ˜RKš˜Kšœœœœ˜'Kšœœœ˜#Kšœœ˜Kšœ ˜Kšœ˜—š˜Kšœ7˜7šœ˜Kšœœ˜Kšœ œ˜Kšœœ˜ Kšœœ˜—Kšœ˜Kšœ˜—Kšœ˜—Kšœ  œ˜šŸœœœ˜:Kš˜šŸœœœœ˜EKš˜Kšœœœ œ˜.Kšœœœœ˜Kšœœ˜Kšœ˜—Kšœœœœ˜Kšœ)˜)Kšœ˜—šŸ œœœœ˜9Kš œœœœœœ œ˜G—šŸ œœœ˜3Kš˜šŸœœœ˜7Kš˜KšœΟc#˜3šœ˜ Kšœœ˜Kšœœ˜1Kš œ ˜Kšœ˜—Kšœ˜—Kš œœœœ ˜3Kšœ˜Kšœ˜—šŸœœœœœœœ˜YKš˜Kšœœœœ˜Kšœ˜Kšœœœœ˜8Kšœœœœœœœ˜UK˜&Kšœœ˜Kšœ˜—š Ÿ œœœœœ˜UKš˜Kšœœœ ˜.Kšœœœ˜"Kšœ˜Kšœ˜—šŸ œœœ˜1Kš˜šŸ œœœœ"˜XKš˜Kšœœœ œ˜.Kšœœœ˜"Kšœ˜K˜&Kšœ˜šœ˜ Kšœ˜Kšœœ ˜Kšœ˜Kšœ˜—Kšœ˜—Kšœ(˜(Kšœœœ˜)Kšœœœœ˜Kšœ˜——Kšœ˜—…— zΫ