-- TiogaPGMonitorImpl.Mesa -- last written by Paxton. February 8, 1981 5:47 PM DIRECTORY TiogaFiles: FROM "TiogaFiles" USING [controlBlock, textBlock], TiogaPGStreams; TiogaPGMonitorImpl: MONITOR LOCKS pgm USING pgm: PGM EXPORTS TiogaPGStreams = BEGIN OPEN filesI: TiogaFiles, TiogaPGStreams; PGM: TYPE = REF PGMBody; PGMBody: PUBLIC TYPE = MONITORED RECORD [ text, control, writes, deferred: MList ]; MList: TYPE = REF MListBody; MListBody: TYPE = RECORD [ first, last: BlockList, done: BOOLEAN _ FALSE, available: CONDITION ]; BlockList: TYPE = REF BlockListBody; BlockListBody: TYPE = RECORD [ next: BlockList, block: Block ]; CreatePGM: PUBLIC PROC [mode: PGStreamMode] RETURNS [pgm: PGM] = BEGIN pgm _ NEW[PGMBody]; SELECT mode FROM read => { pgm.text _ NEW[MListBody]; pgm.control _ NEW[MListBody] }; write => { pgm.writes _ NEW[MListBody]; pgm.deferred _ NEW[MListBody] }; ENDCASE => ERROR; END; AddToMList: INTERNAL PROC [mlst: MList, block: Block] = BEGIN itm: BlockList _ NEW[BlockListBody _ [NIL, block]]; IF mlst.first # NIL THEN mlst.last.next _ itm ELSE mlst.first _ itm; mlst.last _ itm; NOTIFY mlst.available; END; GetFromMList: INTERNAL PROC [mlst: MList, pgm: PGM] RETURNS [block: Block] = BEGIN itm: BlockList; WHILE (itm _ mlst.first) = NIL AND ~mlst.done DO WAIT mlst.available; ENDLOOP; IF itm=NIL THEN RETURN [NIL]; -- done block _ itm.block; IF itm = mlst.last THEN mlst.first _ mlst.last _ NIL ELSE mlst.first _ mlst.first.next; END; AddToControlList: PUBLIC ENTRY PROC [pgm: PGM, block: Block] = { ENABLE UNWIND => NULL; AddToMList[pgm.control, block] }; GetFromControlList: PUBLIC ENTRY PROC [pgm: PGM] RETURNS [Block] = { ENABLE UNWIND => NULL; RETURN [GetFromMList[pgm.control, pgm]] }; SetDone: INTERNAL PROC [mlst: MList] = INLINE { mlst.done _ TRUE; NOTIFY mlst.available }; ControlReadsDone: PUBLIC ENTRY PROC [pgm: PGM] = { ENABLE UNWIND => NULL; SetDone[pgm.control] }; TextReadsDone: PUBLIC ENTRY PROC [pgm: PGM] = { ENABLE UNWIND => NULL; SetDone[pgm.text] }; WriteTextBlock: PUBLIC ENTRY PROC [pgm: PGM, block: Block] = { ENABLE UNWIND => NULL; AddToMList[pgm.writes, block] }; WriteControlBlock: PUBLIC ENTRY PROC [pgm: PGM, block: Block] = { ENABLE UNWIND => NULL; AddToMList[pgm.deferred, block] }; GetFromWriteList: PUBLIC ENTRY PROC [pgm: PGM] RETURNS [Block] = { ENABLE UNWIND => NULL; RETURN[GetFromMList[pgm.writes, pgm]] }; WritesDone: PUBLIC ENTRY PROC [pgm: PGM] = { ENABLE UNWIND => NULL; writes, deferred: MList; deferred _ pgm.deferred; IF deferred.first # NIL THEN -- move to writes IF (writes _ pgm.writes).first # NIL THEN BEGIN writes.last.next _ deferred.first; writes.last _ deferred.last; deferred.first _ deferred.last _ NIL; END ELSE BEGIN writes.first _ deferred.first; writes.last _ deferred.last; deferred.first _ deferred.last _ NIL; END; SetDone[pgm.writes] }; END.