DIRECTORY YggEnvironment USING[DID, LockMode, PageCount], YggInternal USING[Document, TransHandle], YggOpenDoc, YggOpenDocPrivate, YggDID USING[DID, EqualDIDs], YggDIDMap USING[GetDID, Register], YggTransactionMap USING[GetOpenDocList, SetOpenDocList]; YggOpenDocImpl: CEDAR MONITOR IMPORTS YggDID, YggDIDMap, YggTransactionMap EXPORTS YggInternal = BEGIN OpenDoc: TYPE = REF OpenDocRep; OpenDocRep: PUBLIC TYPE = YggOpenDocPrivate.OpenDocRep; InUse: --CALLING-- ERROR = CODE; OldHandleNotFound: --CALLING-- ERROR = CODE; UseCountAlreadyZero: --CALLING-- ERROR = CODE; Register: PUBLIC ENTRY PROCEDURE [trans: YggInternal.TransHandle, did: YggDID.DID] RETURNS [openDoc: OpenDoc] = BEGIN -- errors defined in YggOpenDoc: none. ENABLE UNWIND => NULL; firstOpenDoc: OpenDoc; TRUSTED BEGIN firstOpenDoc _ YggTransactionMap.GetOpenDocList[trans]; END; FOR openDoc _ firstOpenDoc, openDoc.nextForTrans UNTIL openDoc = NIL DO IF YggDID.EqualDIDs[did, GetDID[openDoc]] THEN GOTO found; REPEAT found => openDoc.useCount _ openDoc.useCount + 1; FINISHED => BEGIN openDoc _ NEW[OpenDocRep _ [trans: trans, docHandle: YggDIDMap.Register[did], useCount: 1, deltaVersion: 0, highWaterMark: LAST[YggEnvironment.PageCount], lockMode: none, nextForTrans: firstOpenDoc]]; YggTransactionMap.SetOpenDocList[trans, openDoc]; END; ENDLOOP; END; Unregister: PUBLIC ENTRY PROCEDURE [openDoc: OpenDoc] = BEGIN -- errors defined in YggOpenDoc: none. ENABLE UNWIND => NULL; IF openDoc.useCount = 0 THEN RETURN WITH ERROR UseCountAlreadyZero; IF (((openDoc.useCount _ openDoc.useCount - 1) = 0) AND (openDoc.deltaVersion = 0)) THEN TRUSTED BEGIN prevOpenDoc: OpenDoc _ FindOpenDoc[openDoc.docHandle, YggTransactionMap.GetOpenDocList[openDoc.trans]]; IF prevOpenDoc = NIL THEN YggTransactionMap.SetOpenDocList[openDoc.trans, openDoc.nextForTrans] ELSE prevOpenDoc.nextForTrans _ openDoc.nextForTrans; END; END; FlushTransState: PUBLIC ENTRY PROCEDURE [trans: YggInternal.TransHandle] = TRUSTED BEGIN -- errors defined in YggOpenDoc: none. ENABLE UNWIND => NULL; FOR openDoc: OpenDoc _ YggTransactionMap.GetOpenDocList[trans], openDoc.nextForTrans UNTIL openDoc = NIL DO IF ((openDoc.useCount # 0) OR (openDoc.deltaVersion = 0)) THEN RETURN WITH ERROR InUse; ENDLOOP; YggTransactionMap.SetOpenDocList[trans, NIL]; END; GetDocHandle: PUBLIC PROCEDURE [openDoc: OpenDoc] RETURNS [doc: YggInternal.Document] = BEGIN -- errors defined in YggOpenDoc: none. RETURN[openDoc.docHandle]; END; GetTransHandle: PUBLIC PROCEDURE [openDoc: OpenDoc] RETURNS [trans: YggInternal.TransHandle] = BEGIN -- errors defined in YggOpenDoc: none. RETURN[openDoc.trans]; END; GetDID: PUBLIC PROCEDURE [openDoc: OpenDoc] RETURNS [did: YggEnvironment.DID] = BEGIN -- errors defined in YggOpenDoc: none. RETURN[YggDIDMap.GetDID[openDoc.docHandle]]; END; GetDeltaVersion: PUBLIC ENTRY PROCEDURE [openDoc: OpenDoc] RETURNS [delta: LONG INTEGER] = BEGIN -- errors defined in YggOpenDoc: none. ENABLE UNWIND => NULL; RETURN[openDoc.deltaVersion]; END; SetMaxDeltaVersion: PUBLIC ENTRY PROCEDURE [openDoc: OpenDoc, increment: LONG INTEGER] = BEGIN -- errors defined in YggOpenDoc: none. ENABLE UNWIND => NULL; openDoc.deltaVersion _ MAX[openDoc.deltaVersion, increment]; END; GetHighWaterMark: PUBLIC ENTRY PROCEDURE [openDoc: OpenDoc] RETURNS [highWaterMark: YggEnvironment.PageCount] = BEGIN -- errors defined in YggOpenDoc: none. ENABLE UNWIND => NULL; RETURN[openDoc.highWaterMark]; END; GetLockMode: PUBLIC ENTRY PROCEDURE [openDoc: OpenDoc] RETURNS [lock: YggEnvironment.LockMode] = BEGIN -- errors defined in YggOpenDoc: none. ENABLE UNWIND => NULL; RETURN[openDoc.lockMode]; END; SetLockMode: PUBLIC ENTRY PROCEDURE [openDoc: OpenDoc, lock: YggEnvironment.LockMode] = BEGIN -- errors defined in YggOpenDoc: none. ENABLE UNWIND => NULL; openDoc.lockMode _ lock; END; GetNextHandleForTrans: PUBLIC ENTRY PROCEDURE [trans: YggInternal.TransHandle, lastOpenDoc: OpenDoc _ NIL] RETURNS [nextOpenDoc: OpenDoc] = BEGIN -- errors defined in YggOpenDoc: none. ENABLE UNWIND => NULL; firstOpenDoc: OpenDoc; TRUSTED BEGIN firstOpenDoc _ YggTransactionMap.GetOpenDocList[trans]; END; IF lastOpenDoc = NIL THEN RETURN[firstOpenDoc]; [] _ FindOpenDoc[lastOpenDoc.docHandle, firstOpenDoc]; RETURN[lastOpenDoc.nextForTrans]; END; FindOpenDoc: INTERNAL PROCEDURE [doc: YggInternal.Document, firstDoc: OpenDoc] RETURNS [foundDoc: OpenDoc] = { did: YggDID.DID; did _ YggDIDMap.GetDID[doc]; FOR foundDoc _ firstDoc, foundDoc.nextForTrans UNTIL foundDoc = NIL DO IF YggDID.EqualDIDs[did, GetDID[foundDoc]] THEN RETURN; REPEAT FINISHED => ERROR OldHandleNotFound; ENDLOOP; }; END. Edit Log Initial: Kolling: October 21, 1982 2:22 pm: an impl module for YggOpenDoc. YggOpenDocImpl.mesa Copyright Σ 1985, 1988 by Xerox Corporation. All rights reserved. Last edited by Kolling on November 2, 1983 4:09 pm Bob Hagmann May 4, 1988 9:28:32 pm PDT Derived from Alpine's FileInstanceImpl.mesa. This implementation manages OpenDoc objects. These are documents that are open for a particular transaction. errors: Finds or creates a Handle for the supplied transand did, and increments use count on the returned handle. If the handle is created, it is also entered in the YggOpenDoc list for its transaction and YggDIDMap.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 YggOpenDoc 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 YggOpenDoc 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 YggOpenDoc list is assumed to not be being modified during this enumeration. When handle is non-NIL, not finding it is a fatal error. errors defined in YggOpenDoc: none. main line code. Hauser, March 7, 1985 2:53:07 pm PST Nodified, added copyright. Κ˜šœ™IcodešœB™B—šœ™Jšœ#™#Kšœ&™&K™—Kšœ,™,K™šœm™mJ˜J˜—JšΟk ˜ ˜Jšœœ˜/Jšœ œ˜)Jšœ ˜ Jšœ˜Jšœœ˜Jšœ œ˜"šœœ!˜8J˜J˜——šΟnœœ˜Jšœ%˜,Jšœ˜J˜J˜—Jšœ˜J˜J˜Jšœ œœ ˜J˜šœ œœ ˜7J˜J˜—Jšœ™J˜JšžœΟc œœœ˜ JšžœŸ œœœ˜,JšžœŸ œœœ˜.J˜J˜J˜Jšœδ™δJ˜š žœœœ œ3œ˜ošœŸ&˜-Jšœœœ˜Jšœ˜Jšœœ9œ˜Jšœ-œ ˜GJšœ(œœ˜:š˜Jšœ1˜1šœœ œ˜4Jšœ7˜7Jšœ œ+˜OJšœ˜Jšœ1˜1Jšœ˜——Jšœ˜—Jšœ˜J˜J˜——Jšœο™οJ˜šž œœœ œ˜7JšœŸ&˜-Jšœœœ˜Jš œœœœœ˜Cšœ2œ˜Sšœœ˜šœ5˜5Jšœ1˜1—šœ˜JšœF˜JJšœ1˜5—Jšœ˜——Jšœ˜J˜J˜J˜—Jšœ}™}J˜šžœœœ œ#˜JJšœœŸ&˜5Jšœœœ˜šœQœ ˜kšœœ˜9Jšœœœœ˜—Jšœ˜—Jšœ(œ˜/Jšœ˜J˜J˜J˜—Jšœ™J˜J˜šž œœ œœ˜WšœŸ&˜-Jšœ˜Jšœ˜J˜J˜——šžœœ œœ#˜^JšœŸ&˜-Jšœ˜Jšœ˜J˜J˜—šžœœ œœ˜OJšœŸ(˜/Jšœ&˜,Jšœ˜J˜J˜—Jšœ ™ J˜J˜š žœœœ œœ ˜Ošœ˜ JšœŸ&˜-Jšœœœ˜Jšœ˜Jšœ˜J˜J˜——Jšœœ%™FJ˜š žœœœ œ˜Mšœ˜ JšœŸ&˜-Jšœœœ˜Jšœœ"˜