InsertFile:
PUBLIC
PROC [fs: FSInstance, name:
ROPE, openProc:
PROC [FileHandle]
RETURNS [IFSFile.AccessFailure]]
RETURNS [file: FileHandle] = {
NewlyOpened:
ENTRY
PROC [fs: FSInstance]
RETURNS [
BOOL] = {
checks to see if the file identified by 'name' has already been entered in the file list. If not, it enters it and indicates that the open operation is underway. If so, it waits for any previous open attempt to be resolved, then reports the outcome.
file ← fs.fileList;
UNTIL file =
NIL
DO
IF Rope.Equal[file.name, name,
FALSE]
THEN {
SELECT file.seal
FROM
openSeal => {file.openCount ← file.openCount + 1; RETURN[FALSE]};
underwaySeal => {WAIT fs.changeInOpenState; file ← fs.fileList};
ENDCASE => GO TO bogusList
}
ELSE
-- ensure pointer validity
SELECT file.seal
FROM
openSeal, underwaySeal => file ← file.link;
ENDCASE => GO TO bogusList;
REPEAT
bogusList => ERROR FileListSmashed;
ENDLOOP;
file ← NEW[FileObject ← FileObject[link: fs.fileList, name: name, fs: fs]];
fs.fileList ← file;
RETURN[TRUE]
};
AnnounceOutcome:
ENTRY
PROC [fs: FSInstance, outcome: IFSFile.AccessFailure] = {
IF outcome = ok THEN file.seal ← openSeal ELSE RemoveFile[fs, file];
BROADCAST fs.changeInOpenState;
SELECT outcome
FROM
ok => RETURN;
io => RETURN WITH ERROR IFSFile.Error[io];
ENDCASE => RETURN WITH ERROR IFSFile.CantOpen[outcome];
};
IF NewlyOpened[fs] THEN AnnounceOutcome[fs, openProc[file]];
};
ReleaseFile:
PUBLIC
PROC [file: FileHandle, closeProc:
PROC [FileHandle]] = {
IF LastReference[file.fs, file] THEN {closeProc[file]; FlushFile[file]};
};
PurgeFile:
PUBLIC
PROC [file: FileHandle, destroyProc:
PROC [FileHandle]] = {
IF LastReference[file.fs, file]
THEN {destroyProc[file]; FlushFile[file]}
ELSE ERROR IllegalDestroy;
};