-- TempFileManager.mesa
-- created by Schroeder, November 18, 1980 9:19 PM
-- edited by Brotz, March 11, 1983 10:21 AM

DIRECTORY
Core USING [Close, Open],
exD: FROM "ExceptionDefs" USING [SysBug],
Storage USING [Node],
String USING [AppendDecimal, AppendString],
tfD: FROM "TempFileDefs",
VMDefs USING [CantOpen
, FileHandle, GetFileLength, SetFileLength];

TempFileManager: MONITOR
IMPORTS Core, exD, Storage, String, VMDefs
EXPORTS tfD =

BEGIN

TempFile: TYPE = RECORD
[c: CARDINAL,
h: VMDefs.FileHandle,
n: POINTER TO TempFile];

alloc: POINTER TO TempFile ← NIL; --checked out temp files
free: POINTER TO TempFile ← NIL; --freed temp files
tmpFileCntr: CARDINAL ← 100;


AllocateTempFile: PUBLIC ENTRY PROCEDURE RETURNS [VMDefs.FileHandle] =
BEGIN
t: POINTER TO TempFile;
fnm: STRING ← [10];
IF free = NIL THEN
BEGIN -- generate a new temp file node
t ← Storage.Node[SIZE[TempFile]];
IF (tmpFileCntr ← tmpFileCntr - 1) = 0 THEN exD.SysBug[];
t.c ← tmpFileCntr;
END
ELSE -- take one from free list -- {t ← free; free ← t.n};
t.n ← alloc;
alloc ← t;
DO
String.AppendString[fnm, "DMS-"L];
String.AppendDecimal[fnm, t.c];
String.AppendString[fnm, ".TMP"L];
t.h ← Core.Open[fnm, update ! VMDefs.CantOpen =>
BEGIN
fnm.length ← 0;
IF (tmpFileCntr ← tmpFileCntr - 1) = 0 THEN GO TO OutOfFiles;
t.c ← tmpFileCntr;
LOOP;
END];
EXIT;
REPEAT
OutOfFiles => exD.SysBug[];
ENDLOOP;
RETURN[t.h];
END; -- of AllocateTempFile --


FreeTempFile: PUBLIC ENTRY PROCEDURE [h: VMDefs.FileHandle] =
BEGIN
current: POINTER TO TempFile;
previous: POINTER TO TempFile ← NIL;
FOR current ← alloc, current.n UNTIL current = NIL DO
IF current.h = h THEN EXIT;
previous ← current;
REPEAT FINISHED => exD.SysBug[];
ENDLOOP;
IF previous = NIL
THEN alloc ← current.n
ELSE previous.n ← current.n;
current.n ← free;
free ← current;
IF VMDefs.GetFileLength[current.h].page > 3 THEN VMDefs.SetFileLength[current.h, [4, 0]];
Core.Close[current.h];
current.h ← NIL;
END; -- of FreeTempFile --


END. -- of TempFileManager --