FSReportImpl.mesa
Last Edited by: Schroeder, November 15, 1983 5:01 pm
Last Edited by: Birrell, July 8, 1983 2:22 pm
DIRECTORY
BasicTime USING [GMT, nullGMT],
File USING [Reason],
FS USING [ErrorGroup, ErrorDesc],
FSBackdoor USING [ErrorCode, EventOp, MakeFName, noVersion, Version],
FSExtras USING [CreateOp, CreateEvent, RemoteOp, RemoteEvent],
FSName USING [BangVersionFile],
FSReport USING [],
IO USING [PutFR, rope, time],
Rope USING [Cat, ROPE];
FSReportImpl: CEDAR MONITOR
IMPORTS BasicTime, FSBackdoor, FSName, IO, Rope
EXPORTS FS, FSBackdoor, FSExtras, FSReport
= BEGIN
Exported to FS
Error: PUBLIC ERROR [error: FS.ErrorDesc] = CODE;
Exported to FSExtras
remoteEventListTail: REF FSExtras.RemoteEvent ← NIL;
anotherRemoteEvent: CONDITION;
watchingRemote: BOOLEANFALSE;
NextRemoteEvent: PUBLIC ENTRY PROC [last: REF READONLY FSExtras.RemoteEvent] RETURNS [REF FSExtras.RemoteEvent] =
BEGIN
IF last = NIL
THEN BEGIN -- first call for this client
IF remoteEventListTail = NIL
THEN BEGIN -- no events in list yet
watchingRemote ← TRUE;
UNTIL remoteEventListTail # NIL DO WAIT anotherRemoteEvent ENDLOOP;
RETURN [remoteEventListTail];
END
ELSE last ← remoteEventListTail;
END;
UNTIL last.chain # NIL DO WAIT anotherRemoteEvent ENDLOOP; -- wait for next event
RETURN [last.chain];
END;
creationEventListTail: REF FSExtras.CreateEvent ← NIL;
anotherCreationEvent: CONDITION;
watchingCreation: BOOLEANFALSE;
NextCreateEvent: PUBLIC ENTRY PROC [last: REF READONLY FSExtras.CreateEvent] RETURNS [REF FSExtras.CreateEvent] =
BEGIN
IF last = NIL
THEN BEGIN -- first call for this client
IF creationEventListTail = NIL
THEN BEGIN -- no events in list yet
watchingCreation ← TRUE;
UNTIL creationEventListTail # NIL DO WAIT anotherCreationEvent ENDLOOP;
RETURN [creationEventListTail];
END
ELSE last ← creationEventListTail;
END;
UNTIL last.chain # NIL DO WAIT anotherCreationEvent ENDLOOP; -- wait for next event
RETURN [last.chain];
END;
Exported to FSBackdoor
EventObject: PUBLIC TYPE = FSExtras.RemoteEvent;
NextEvent: PUBLIC PROC [last: REF EventObject] RETURNS [fName: Rope.ROPE, event: FSBackdoor.EventOp, this: REF EventObject] =
BEGIN
DO
nextEvent: REF FSExtras.RemoteEvent = NextRemoteEvent[last];
SELECT nextEvent.op FROM
startRetrieving => event ← startRetrieving;
endRetrieving => event ← endRetrieving;
startStoring => event ← startStoring;
endStoring => event ← endStoring;
startFlushing => event ← startFlushing;
endFlushing => event ← endFlushing;
ENDCASE => {last ← nextEvent; LOOP};
fName ← nextEvent.fName;
this ← nextEvent;
EXIT;
ENDLOOP;
END;
group: PACKED ARRAY FSBackdoor.ErrorCode OF FS.ErrorGroup = [
-- 4-- bug, bug, bug, bug,
--13-- environment, environment, environment, environment, environment, environment, environment, environment, environment, environment, environment, environment, environment,
-- 2-- lock, lock,
-- 8-- client, client, client, client, client, client, client, client,
--12-- user, user, user, user, user, user, user, user, user, user, user, user
];
codeAtom: ARRAY FSBackdoor.ErrorCode OF ATOM = [
$ok, $inconsistent, $software, $badFP,
$wentOffline, $hardware, $volumeFull, $fragmented, $noMoreVersions, $serverInaccessible, $connectionRejected, $connectionTimedOut, $badCredentials, $accessDenied, $quotaExceeded, $invalidPropertyPage, $badBTree,
$lockConflict, $fileBusy,
$noCache, $wrongLock, $globalWriteLock, $zeroKeep, $badByteCount, $unknownPage, $invalidOpenFile, $notImplemented,
$nonCedarVolume, $unknownServer, $unknownVolume, $unknownFile, $unknownCreatedTime, $illegalName, $patternNotAllowed, $versionSpecified, $globalCreation, $badWorkingDir, $noKeeps, $cantUpdateTiogaFile
];
ProduceError: PUBLIC PROC [code: FSBackdoor.ErrorCode, explanation: Rope.ROPE] =
{ ERROR Error [ [group[code], codeAtom[code], explanation] ] };
Exported to FSReport
ReportRemote: PUBLIC ENTRY PROC [op: FSExtras.RemoteOp, fName: Rope.ROPE] =
BEGIN
IF watchingRemote
THEN BEGIN
eventREF: REF FSExtras.RemoteEvent = NEW [ FSExtras.RemoteEvent ← [op, fName, NIL] ];
IF remoteEventListTail # NIL THEN remoteEventListTail.chain ← eventREF;
remoteEventListTail ← eventREF;
BROADCAST anotherRemoteEvent;
END;
END;
ReportCreation: PUBLIC ENTRY PROC [op: FSExtras.CreateOp, fName: Rope.ROPE] =
BEGIN
IF watchingCreation
THEN BEGIN
eventREF: REF FSExtras.CreateEvent = NEW [ FSExtras.CreateEvent ← [op, fName, NIL] ];
IF creationEventListTail # NIL THEN creationEventListTail.chain ← eventREF;
creationEventListTail ← eventREF;
BROADCAST anotherCreationEvent;
END;
END;
FileError: PUBLIC PROC [reason: File.Reason] =
BEGIN
code: FSBackdoor.ErrorCode;
e: Rope.ROPE;
SELECT reason FROM
wentOffline => { code ← wentOffline;
e ← "Local volume is no longer accessible." };
nonCedarVolume => { code ← nonCedarVolume;
e ← "Not a cedar volume." };
inconsistent => { code ← inconsistent;
e ← "Local volume's permanent data structures are inconsistent." };
software => { code ← software;
e ← "Label check encountered while reading or writing local volume pages." };
hardware => { code ← hardware;
e ← "Hard error encountered while reading or writing local volume pages." };
unknownFile => { code ← badFP;
e ← "File.FP from directory/cache doesn't correspond to a local volume file." };
unknownPage => { code ← unknownPage;
e ← "Tried to read or write a page that is beyond end of the file." };
volumeFull => { code ← volumeFull;
e ← "No more free pages on a local volume." };
fragmented => { code ← fragmented;
e ← "File required too many non-contiguous areas on a local volume." };
ENDCASE => ERROR;
ProduceError[code, e];
END;
LockConflict: PUBLIC PROC [prefix, nameBody: Rope.ROPE, version: FSBackdoor.Version] =
BEGIN
ProduceError[lockConflict,
Rope.Cat["FS lock conflict on \"", FSBackdoor.MakeFName[nameBody, version, prefix], "\"."]];
END;
UnknownFile: PUBLIC PROC [name: Rope.ROPE, createdTime: BasicTime.GMT] =
BEGIN
IF createdTime = BasicTime.nullGMT
THEN ProduceError[unknownFile, Rope.Cat["Couldn't find a file named \"", name, "\"."]]
ELSE BEGIN
name ← FSName.BangVersionFile[name, FSBackdoor.noVersion];
ProduceError[unknownCreatedTime, IO.PutFR["Couldn't find a version of \"%g\" created at %t.", IO.rope[name], IO.time[createdTime]]];
END;
END;
UnknownVolumeLName: PUBLIC PROC [name: Rope.ROPE] =
BEGIN
ProduceError[unknownVolume, Rope.Cat["There's no system volume, so can't access the LName \"", name, "\"."]];
END;
UnknownVolume: PUBLIC PROC [vName: Rope.ROPE] =
BEGIN
IF vName = NIL
THEN ProduceError[unknownVolume, "There is no system volume for this Cedar instance."]
ELSE ProduceError[unknownVolume, Rope.Cat["Couldn't find a local volume named \"", vName, "\"."]];
END;
NoCache: PUBLIC PROC [name: Rope.ROPE] =
BEGIN
ProduceError[noCache, Rope.Cat["There's no system volume, so can't cache the GName \"", name, "\"."]];
END;
VersionSpecified: PUBLIC PROC [name: Rope.ROPE] =
BEGIN
ProduceError[versionSpecified, Rope.Cat[ "\"", name, "\" includes a version part, but none is allowed when generating a new FName."]];
END;
END.