DIRECTORY AlpineEnvironment USING[FileID, LockMode, PageCount, VolumeID], AlpineInternal USING[FileHandle, TransHandle], FileInstance, FileMap USING[GetFileID, GetVolumeID, GetVolumeIDAndFileID, Register], TransactionMap USING[GetFileInstanceList, SetFileInstanceList]; FileInstanceImpl: CEDAR MONITOR IMPORTS FileMap, TM: TransactionMap EXPORTS AlpineInternal, FileInstance = BEGIN OPEN AE: AlpineEnvironment, AI: AlpineInternal; Handle: TYPE = REF FileInstanceObject; FileInstanceObject: PUBLIC TYPE = RECORD[ trans: AI.TransHandle, fileHandle: AI.FileHandle, useCount: CARDINAL, deltaVersion: LONG INTEGER, highWaterMark: AE.PageCount, lockMode: AE.LockMode, nextForTrans: Handle]; InUse: --CALLING-- ERROR = CODE; OldHandleNotFound: --CALLING-- ERROR = CODE; UseCountAlreadyZero: --CALLING-- ERROR = CODE; Register: PUBLIC ENTRY PROCEDURE [trans: AI.TransHandle, volumeID: AE.VolumeID, fileID: AE.FileID] RETURNS [handle: Handle] = BEGIN -- errors defined in FileInstance: none. ENABLE UNWIND => NULL; firstInsHandle: Handle; TRUSTED BEGIN firstInsHandle _ TM.GetFileInstanceList[trans]; END; FOR handle _ firstInsHandle, handle.nextForTrans UNTIL handle = NIL DO IF FileMap.GetVolumeIDAndFileID[handle.fileHandle] = [volumeID, fileID] THEN GOTO found; REPEAT found => handle.useCount _ handle.useCount + 1; FINISHED => BEGIN handle _ NEW[FileInstanceObject _ [trans: trans, fileHandle: FileMap.Register[volumeID, fileID], useCount: 1, deltaVersion: 0, highWaterMark: LAST[AE.PageCount], lockMode: none, nextForTrans: firstInsHandle]]; TRUSTED BEGIN TM.SetFileInstanceList[trans, handle]; END; END; ENDLOOP; END; Unregister: PUBLIC ENTRY PROCEDURE [handle: Handle] = BEGIN -- errors defined in FileInstance: none. ENABLE UNWIND => NULL; IF handle.useCount = 0 THEN RETURN WITH ERROR UseCountAlreadyZero; IF (((handle.useCount _ handle.useCount - 1) = 0) AND (handle.deltaVersion = 0)) THEN TRUSTED BEGIN prevInsHandle: Handle _ FindHandle[handle.fileHandle, TM.GetFileInstanceList[handle.trans]]; IF prevInsHandle = NIL THEN TM.SetFileInstanceList[handle.trans, handle.nextForTrans] ELSE prevInsHandle.nextForTrans _ handle.nextForTrans; END; END; FlushTransState: PUBLIC ENTRY PROCEDURE [trans: AI.TransHandle] = TRUSTED BEGIN -- errors defined in FileInstance: none. ENABLE UNWIND => NULL; FOR insHandle: Handle _ TM.GetFileInstanceList[trans], insHandle.nextForTrans UNTIL insHandle = NIL DO IF ((insHandle.useCount # 0) OR (insHandle.deltaVersion = 0)) THEN RETURN WITH ERROR InUse; ENDLOOP; TM.SetFileInstanceList[trans, NIL]; END; GetFileHandle: PUBLIC PROCEDURE [handle: Handle] RETURNS [fileHandle: AI.FileHandle] = BEGIN -- errors defined in FileInstance: none. RETURN[handle.fileHandle]; END; GetTransHandle: PUBLIC PROCEDURE [handle: Handle] RETURNS [trans: AI.TransHandle] = BEGIN -- errors defined in FileInstance: none. RETURN[handle.trans]; END; GetVolumeID: PUBLIC PROCEDURE [handle: Handle] RETURNS [volumeID: AE.VolumeID] = BEGIN -- errors defined in FileInstance: none. RETURN[FileMap.GetVolumeID[handle.fileHandle]]; END; GetFileID: PUBLIC PROCEDURE [handle: Handle] RETURNS [fileID: AE.FileID] = BEGIN -- errors defined in FileInstance: none. RETURN[FileMap.GetFileID[handle.fileHandle]]; END; GetVolumeIDAndFileID: PUBLIC PROCEDURE [handle: Handle] RETURNS [volumeID: AE.VolumeID, fileID: AE.FileID] = BEGIN -- errors defined in FileInstance: none. [volumeID, fileID] _ FileMap.GetVolumeIDAndFileID[handle.fileHandle]; END; GetDeltaVersion: PUBLIC ENTRY PROCEDURE [handle: Handle] RETURNS [delta: LONG INTEGER] = BEGIN -- errors defined in FileInstance: none. ENABLE UNWIND => NULL; RETURN[handle.deltaVersion]; END; SetMaxDeltaVersion: PUBLIC ENTRY PROCEDURE [handle: Handle, increment: LONG INTEGER] = BEGIN -- errors defined in FileInstance: none. ENABLE UNWIND => NULL; handle.deltaVersion _ MAX[handle.deltaVersion, increment]; END; GetHighWaterMark: PUBLIC ENTRY PROCEDURE [handle: Handle] RETURNS [highWaterMark: AE.PageCount] = BEGIN -- errors defined in FileInstance: none. ENABLE UNWIND => NULL; RETURN[handle.highWaterMark]; END; SetHighWaterMark: PUBLIC ENTRY PROCEDURE [handle: Handle, highWaterMark: AE.PageCount] RETURNS [oldHighWaterMark: AE.PageCount] = BEGIN -- errors defined in FileInstance: none. ENABLE UNWIND => NULL; oldHighWaterMark _ handle.highWaterMark; handle.highWaterMark _ highWaterMark; END; GetLockMode: PUBLIC ENTRY PROCEDURE [handle: Handle] RETURNS [lock: AE.LockMode] = BEGIN -- errors defined in FileInstance: none. ENABLE UNWIND => NULL; RETURN[handle.lockMode]; END; SetLockMode: PUBLIC ENTRY PROCEDURE [handle: Handle, lock: AE.LockMode] = BEGIN -- errors defined in FileInstance: none. ENABLE UNWIND => NULL; handle.lockMode _ lock; END; GetNextHandleForTrans: PUBLIC ENTRY PROCEDURE [trans: AI.TransHandle, handle: Handle] RETURNS [nextHandle: Handle] = BEGIN -- errors defined in FileInstance: none. ENABLE UNWIND => NULL; firstInsHandle: Handle; TRUSTED BEGIN firstInsHandle _ TM.GetFileInstanceList[trans]; END; IF handle = NIL THEN RETURN[firstInsHandle]; [] _ FindHandle[handle.fileHandle, firstInsHandle]; RETURN[handle.nextForTrans]; END; FindHandle: INTERNAL PROCEDURE [fileHandle: AI.FileHandle, firstInsHandle: Handle] RETURNS [prevHandle: Handle] = BEGIN -- errors defined in FileInstance: none. volumeID: AE.VolumeID; fileID: AE.FileID; [volumeID, fileID] _ FileMap.GetVolumeIDAndFileID[fileHandle]; prevHandle _ NIL; FOR foundHandle: Handle _ firstInsHandle, foundHandle.nextForTrans UNTIL foundHandle = NIL DO IF FileMap.GetVolumeIDAndFileID[foundHandle.fileHandle] = [volumeID, fileID] THEN EXIT; prevHandle _ foundHandle; REPEAT FINISHED => ERROR OldHandleNotFound; ENDLOOP; END; END. Edit Log Initial: Kolling: October 21, 1982 2:22 pm: an impl module for FileInstance. 8FileInstanceImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Last edited by Kolling on November 2, 1983 4:09 pm errors: Finds or creates a Handle for the supplied trans, volume, and file, and increments use count on the returned handle. If the handle is created, it is also entered in the FileInstance list for its transaction and FileMap.Register is called. Decrements use count on handle. If the use count becomes zero and delta version is 0 (i.e., if the file has not been updated), deletes it from the FileInstance list for its transaction. (Updated files are taken care of by FlushTransState.) When this is called, it is a error if any handle in this transaction's FileInstance list has useCount # 0 or delta version = 0. Access to immutable attributes. Access to read/write attributes. Sets the delta version to the MAX of increment and its existing value. Returns the uncommitted highWaterMark, for this transaction. Initialize value is LAST[PageCount]. Enumeration. handle = NIL starts a new enumeration, and nextHandle = NIL is returned when the enumeration is exhausted. The FileInstance list is assumed to not be being modified during this enumeration. When handle is non-NIL, not finding it is a fatal error. main line code. Hauser, March 7, 1985 2:53:07 pm PST Nodified, added copyright. Κ ˜J˜J˜šœ™Icodešœ Οmœ1™<—šœ™Jšœ#™#J˜J˜—JšΟk ˜ ˜˜Jšžœ(˜-—˜Jšžœ˜—J˜ ˜Jšžœ9˜>—˜Jšžœ+˜0J˜J˜——šœžœž˜Jšžœ žœ˜#Jšžœ˜&J˜J˜—Jšžœžœžœžœ˜5J˜J˜Jšœžœžœ˜&J˜šœžœžœžœ˜)Jšœžœ ˜Jšœ žœ ˜Jšœ žœ˜Jšœžœžœ˜Jšœžœ ˜Jšœ žœ ˜J˜J˜J˜—Jšœ™J˜JšœΟc œžœžœ˜ JšœŸ œžœžœ˜,JšœŸ œžœžœ˜.J˜J˜J˜Jšœο™οJ˜š Οnœžœžœž œ žœžœ˜Wšžœ žœ˜%JšžœŸ(˜/Jšžœžœžœ˜J˜Jšžœžœžœžœ˜BJšžœ-˜0šžœ ž˜Jšž˜šžœE˜GJšžœžœ˜—šž˜J˜/šžœžœ žœ˜;J˜CJšœ žœžœ˜CJ˜Jšžœžœžœ%žœ˜9Jšžœ˜——Jšžœ˜—Jšžœ˜J˜J˜——Jšœρ™ρJ˜š  œžœžœž œ˜5JšžœŸ(˜/Jšžœžœžœ˜Jš žœžœžœžœžœ˜Bšžœ0žœ˜Pšžœžœž˜˜5Jšžœ$˜&—šžœž˜Jšžœžœ7˜>Jšžœ2˜6—Jšžœ˜——Jšžœ˜J˜J˜J˜—Jšœ™J˜š  œžœžœž œ žœ˜AJšžœžœŸ(˜7Jšžœžœžœ˜Jšžœžœ3˜Mšžœ ž˜šžœžœžœ˜@Jšžœžœžœžœ˜—Jšžœ˜—Jšžœžœ˜%Jšžœ˜J˜J˜J˜—Jšœ™J˜J˜š  œžœž œžœ ˜Ešžœ˜JšžœŸ(˜/Jšžœ˜Jšžœ˜J˜J˜——š  œžœž œžœ žœ˜SJšžœŸ(˜/Jšžœ˜Jšžœ˜J˜J˜—š  œžœž œžœ ˜Ašžœ ˜JšžœŸ)˜0Jšžœ)˜/Jšžœ˜J˜J˜——š   œžœž œžœ žœ ˜JJšžœŸ*˜1Jšžœ'˜-Jšžœ˜J˜J˜—š œžœž œžœ ˜Jšžœžœ ˜!JšžœŸ(˜/J˜EJšžœ˜J˜J˜J˜——Jšœ ™ J˜J˜š  œžœžœž œžœ ž˜Mšžœ˜ JšžœŸ(˜/Jšžœžœžœ˜Jšžœ˜Jšžœ˜J˜J˜——JšœF™FJ˜š  œžœžœž œž˜Kšžœ˜ JšžœŸ(˜/Jšžœžœžœ˜Jšœžœ!˜:Jšžœ˜J˜J˜——Jšœb™bJ˜š  œžœžœž œž˜Ašœžœ ˜JšžœŸ(˜/Jšžœžœžœ˜Jšžœ˜Jšžœ˜J˜J˜——š œžœžœž œ ˜Hšžœ žœžœ ˜8JšžœŸ(˜/Jšžœžœžœ˜J˜(J˜%Jšžœ˜J˜J˜——š   œžœžœž œžœžœ ˜RJšžœŸ(˜/Jšžœžœžœ˜Jšžœ˜Jšžœ˜J˜J˜—š   œžœžœž œžœ ˜IJšžœŸ(˜/Jšžœžœžœ˜J˜Jšžœ˜J˜J˜J˜—Jšœ ™ J˜JšœP™PJšœ[™[JšœK™KJ˜š  œžœžœž œ žœ˜Mšœžœ˜&JšžœŸ(˜/Jšžœžœžœ˜J˜Jšžœžœžœžœ˜BJšžœ žœžœžœ˜,J˜3Jšžœ˜Jšžœ˜J˜J˜——š  œžœž œžœ$˜Ršžœ˜JšžœŸ(˜/Jšœ žœ ˜Jšœžœ˜J˜>Jšœ žœ˜šžœ?˜Bšžœž˜Jšž˜šžœJ˜LJšžœžœ˜ —J˜Jšžœžœžœ˜+Jšžœ˜——Jšžœ˜J˜J˜J˜J˜——Jšœ™J˜J˜J˜Jšžœ˜˜J˜J˜—J˜L™$K™—K™—…—ά%'