-- File: AltoDirList.mesa
-- Last edited by Levin: 28-Jan-81 19:33:31
DIRECTORY
AltoFile USING [FP, sysDirFP],
AltoFilePrivate USING [
DirHandle, DirObject, FlushDirectoryBuffer, ResetDirectoryLength, sysDir],
VMDefs USING [CloseFile, FileHandle, PageNumber],
VMSpecial USING [OpenAltoFileFromFP],
VMStorage USING [shortTerm];
AltoDirList: MONITOR
IMPORTS AltoFilePrivate, VMDefs, VMSpecial, VMStorage
EXPORTS AltoFile, AltoFilePrivate =
BEGIN OPEN AltoFilePrivate;
-- Global Variables --
dirList: DirHandle;
-- Miscellaneous Declarations --
BadDirectoryList: ERROR = CODE;
-- Procedures and Signals Exported to AltoFile --
DirObject: PUBLIC TYPE = AltoFilePrivate.DirObject;
OpenDirectory: PUBLIC ENTRY PROCEDURE [fp: AltoFile.FP]
RETURNS [dir: DirHandle] =
BEGIN
FOR dir ← dirList, dir.link UNTIL dir = NIL DO
IF dir.fp = fp THEN BEGIN dir.useCount ← dir.useCount + 1; EXIT END;
REPEAT FINISHED => dir ← AddDirectory[fp ! UNWIND => NULL];
ENDLOOP;
END;
CloseDirectory: PUBLIC ENTRY PROCEDURE [dir: DirHandle] =
BEGIN
IF (dir.useCount ← dir.useCount - 1) = 0 THEN
BEGIN
IF dir = dirList THEN dirList ← dir.link
ELSE
FOR prev: DirHandle ← dirList, prev.link UNTIL prev.link = NIL DO
IF prev.link = dir THEN BEGIN prev.link ← dir.link; EXIT END;
REPEAT FINISHED => ERROR BadDirectoryList;
ENDLOOP;
FlushDirectoryBuffer[dir ! UNWIND => NULL];
VMDefs.CloseFile[dir.file];
VMStorage.shortTerm.FREE[@dir];
END;
END;
-- Procedures and Signals Exported to FilePrivateDefs --
InitializeDirectory: PUBLIC PROCEDURE =
BEGIN
dirList ← NIL;
sysDir ← AddDirectory[AltoFile.sysDirFP];
END;
FinalizeDirectory: PUBLIC PROCEDURE =
{CloseDirectory[sysDir]};
-- Internal Procedures --
AddDirectory: PROCEDURE [fp: AltoFile.FP] RETURNS [dir: DirHandle] =
-- creates a new directory entry, initializes it, and adds it to the directory list.
BEGIN
dir ← VMStorage.shortTerm.NEW[DirObject ← DirObject[
file:, length:, buffer: NIL, page: LAST[VMDefs.PageNumber], fp: fp,
spacePos:, spaceNeeded:, spaceFound: 0, link: dirList, useCount: 1]];
BEGIN
ENABLE UNWIND => VMStorage.shortTerm.FREE[@dir];
dir.file ← VMSpecial.OpenAltoFileFromFP[fp: fp, writable: TRUE, cacheFraction: 1];
ResetDirectoryLength[dir ! UNWIND => VMDefs.CloseFile[dir.file]];
END;
dirList ← dir;
END;
END.