-- Copyright (C) 1983 by Xerox Corporation. All rights reserved. -- BootServersB.mesa, HGM, 23-Sep-83 3:27:13 DIRECTORY File USING [nullFile], Space USING [nullInterval], String USING [Equivalent], BootServerFriends USING [ ActivateFile, BootFile, BootFileNumber, BootFileObject, BootFileType, DeactivateFile, KillSpace, MachineType, timeNotKnown], ServerHeap USING [CopyString, Free, FreeString, Node]; BootServersB: MONITOR IMPORTS String, BootServerFriends, ServerHeap EXPORTS BootServerFriends = BEGIN BootFile: TYPE = BootServerFriends.BootFile; BootFileNumber: TYPE = BootServerFriends.BootFileNumber; UseCountConfusion: ERROR = CODE; DanglingFile: ERROR = CODE; first: BootFile ← NIL; waitingForLock: CONDITION; FindBootFile: PUBLIC ENTRY PROCEDURE [code: BootFileNumber] RETURNS [bf: BootFile] = BEGIN previous: BootFile ← NIL; FOR bf ← first, bf.next UNTIL bf = NIL DO IF bf.code = code AND ~bf.unknown THEN EXIT; previous ← bf; REPEAT FINISHED => RETURN; ENDLOOP; IF previous # NIL THEN BEGIN previous.next ← bf.next; bf.next ← first; first ← bf; END; END; FindBootFileByName: PUBLIC ENTRY PROCEDURE [name: LONG STRING] RETURNS [bf: BootFile] = BEGIN previous: BootFile ← NIL; FOR bf ← first, bf.next UNTIL bf = NIL DO IF ~bf.unknown AND String.Equivalent[name, bf.fileName] THEN EXIT; previous ← bf; REPEAT FINISHED => RETURN; ENDLOOP; IF previous # NIL THEN BEGIN previous.next ← bf.next; bf.next ← first; first ← bf; END; END; EnumerateBootTable: PUBLIC ENTRY PROCEDURE [proc: PROCEDURE [BootFile]] = BEGIN FOR bf: BootFile ← first, bf.next UNTIL bf = NIL DO proc[bf]; ENDLOOP; END; GetPointerToBootTable: PUBLIC PROCEDURE RETURNS [LONG POINTER TO BootFile] = BEGIN RETURN[@first]; END; LockFileRead: PUBLIC ENTRY PROCEDURE [bf: BootFile] RETURNS [BOOLEAN] = BEGIN IF bf.useCount > 50 THEN ERROR UseCountConfusion; IF bf.handle = NIL THEN RETURN[FALSE]; bf.useCount ← bf.useCount + 1; RETURN[TRUE]; END; UnlockFile: PUBLIC ENTRY PROCEDURE [bf: BootFile] = BEGIN IF bf.useCount = 0 THEN ERROR UseCountConfusion; bf.useCount ← bf.useCount - 1; BROADCAST waitingForLock; END; AddBootFile: PUBLIC ENTRY PROCEDURE [ code: BootFileNumber, fileName: LONG STRING, fileType: BootServerFriends.BootFileType, machineType: BootServerFriends.MachineType, pup: BOOLEAN] = BEGIN bf: BootFile ← ServerHeap.Node[SIZE[BootServerFriends.BootFileObject]]; last: BootFile; bf↑ ← [ next: NIL, code: code, create: BootServerFriends.timeNotKnown, file: File.nullFile, handle: NIL, space: Space.nullInterval, fileName: ServerHeap.CopyString[fileName], ms: 0, count: 0, pages: 0, bytes: 0, useCount: 0, tries: 0, pup: pup, fileType: fileType, machineType: machineType, unknown: TRUE, inTransit: FALSE]; IF first = NIL THEN first ← bf ELSE BEGIN FOR last ← first, last.next UNTIL last.next = NIL DO ENDLOOP; last.next ← bf; END; END; ActivateFiles: PUBLIC ENTRY PROCEDURE = BEGIN FOR bf: BootFile ← first, bf.next UNTIL bf = NIL DO BootServerFriends.ActivateFile[bf]; ENDLOOP; END; DeactivateFiles: PUBLIC ENTRY PROCEDURE = BEGIN FOR bf: BootFile ← first, bf.next UNTIL bf = NIL DO IF bf.space # Space.nullInterval THEN BootServerFriends.KillSpace[bf]; BootServerFriends.DeactivateFile[bf]; ENDLOOP; END; DeleteBootFileTable: PUBLIC ENTRY PROCEDURE = BEGIN UNTIL first = NIL DO bf: BootServerFriends.BootFile ← first; IF bf.handle # NIL OR bf.useCount # 0 THEN ERROR DanglingFile; first ← bf.next; ServerHeap.FreeString[bf.fileName]; ServerHeap.Free[bf]; ENDLOOP; END; ReleaseFile: PUBLIC ENTRY PROCEDURE [bf: BootFile] = BEGIN UNTIL bf.useCount = 0 DO WAIT waitingForLock; ENDLOOP; IF bf.space # Space.nullInterval THEN BootServerFriends.KillSpace[bf]; bf.handle ← NIL; bf.unknown ← bf.inTransit ← TRUE; END; END.