YggOpenDocImpl.mesa
Copyright Ó 1985, 1988 by Xerox Corporation. All rights reserved.
Last edited by
Kolling on November 2, 1983 4:09 pm
Bob Hagmann July 14, 1988 9:36:31 am PDT
Derived from Alpine's FileInstanceImpl.mesa.
This implementation manages OpenDoc objects. These are documents that are open for a particular transaction.
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;
errors:
InUse: --CALLING-- ERROR = CODE;
OldHandleNotFound: --CALLING-- ERROR = CODE;
UseCountAlreadyZero: --CALLING-- ERROR = CODE;
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.
GetOpenDoc:
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;
When this is called, it is a error if any handle in this transaction's YggOpenDoc list has useCount # 0 or delta version = 0.
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;
Access to immutable attributes.
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;
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;
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.
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] = {
errors defined in YggOpenDoc: none.
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;
};
main line code.
END.
Initial: Kolling: October 21, 1982 2:22 pm: an impl module for YggOpenDoc.
Hauser, March 7, 1985 2:53:07 pm PST
Nodified, added copyright.