DIRECTORY PDInterpBasic, PDInterpControl, PDTransferRpcControl, PDFileFormat, PDInterpPage, PDInterpReader, Process, MesaRPC, PDInterpControlRpcControl, Heap, PDTransfer; PDInterpControlImpl: MONITOR IMPORTS MesaRPC, PDInterpPage, PDInterpReader, Process, PDTransferRpcControl, PDInterpControlRpcControl, Heap, PDTransfer EXPORTS PDInterpControl SHARES PDTransferRpcControl -- for creation of PDTransferRpcControl.InterfaceRecordObject = BEGIN OPEN PDInterpControl; queueMaxSize: NAT = 10; QueueEntry: TYPE = RECORD [ inputHandle: PDTransferRpcControl.InterfaceRecord, pageSpec: PageSpec ]; queueSize: NAT _ 0; queue: ARRAY [0..queueMaxSize) OF QueueEntry; queueChange: CONDITION; JobDone: ENTRY PROC = { IF queue[0].inputHandle # NIL THEN { Heap.systemZone.FREE[@(queue[0].inputHandle)]; }; FOR i: NAT IN [1..queueSize) DO queue[i-1] _ queue[i]; ENDLOOP; queueSize _ queueSize - 1; BROADCAST queueChange; }; ReQueue: ENTRY PROC = { queueEntry: QueueEntry _ queue[0]; FOR i: NAT IN [1..queueSize) DO queue[i-1] _ queue[i]; ENDLOOP; queue[queueSize-1] _ queueEntry; BROADCAST queueChange; }; UnQueue: ENTRY PROC [handle: PDTransferRpcControl.InterfaceRecord] = { found: BOOLEAN _ FALSE; FOR i: NAT IN [1..queueSize) DO IF found THEN queue[i-1] _ queue[i] ELSE found _ queue[i].inputHandle = handle; ENDLOOP; IF found THEN {queueSize _ queueSize - 1; BROADCAST queueChange}; }; ImportNewInterface: PROC [interfaceName: MesaRPC.InterfaceName] RETURNS [interface: PDTransferRpcControl.InterfaceRecord] = { PDTransferRpcControl.ImportInterface[interfaceName]; interface _ Heap.systemZone.NEW[PDTransferRpcControl.InterfaceRecordObject _ [ GetBlock: PDTransfer.GetBlock, ReportStatus: PDTransfer.ReportStatus ]]; }; RequestService: PUBLIC ENTRY PROC [requestorName: LONG STRING, pageSpec: PageSpec] = { interfaceName: MesaRPC.InterfaceName = [instance: requestorName]; handle: PDTransferRpcControl.InterfaceRecord = ImportNewInterface[interfaceName]; UNTIL queueSize < queueMaxSize DO WAIT queueChange ENDLOOP; queue[queueSize] _ [handle, pageSpec]; queueSize _ queueSize + 1; BROADCAST queueChange; }; PrintOne: PROC [reader: PDInterpReader.Handle] = { finished: BOOLEAN _ FALSE; FOR i: NAT IN [0..maxRanges) UNTIL finished DO pageRange: PageRange _ queue[0].pageSpec[i]; skip: NAT _ pageRange.skipCount; UNTIL finished OR skip = 0 DO WITH PDInterpReader.Get[reader] SELECT FROM stateChange: PDInterpReader.CommandBuffer.stateChange => { SELECT stateChange.whatChanged FROM imageStart => finished _ reader.input^.ReportStatus[startImage, queueSize, 0, reader.page, reader.pass, reader.index].abort; documentEnd => finished _ TRUE; imageEnd => skip _ skip - 1; ENDCASE => NULL; }; ENDCASE => NULL; ENDLOOP; UNTIL finished OR pageRange.printCount = 0 DO IF PDInterpPage.InterpretPage[reader].ok THEN { finished _ reader.input.ReportStatus[startImage, queueSize, 0, reader.page, reader.pass, reader.index].abort; pageRange.printCount _ pageRange.printCount - 1; pageRange.skipCount _ pageRange.skipCount + 1; } ELSE finished _ TRUE; ENDLOOP; queue[0].pageSpec[i] _ pageRange; ENDLOOP; [] _ reader.input.ReportStatus[transmissionComplete, queueSize, 0, reader.page, reader.pass, reader.index]; }; WaitForOne: ENTRY PROC = { UNTIL queueSize > 0 DO WAIT queueChange ENDLOOP; }; PrintProcess: PROC = { reader: PDInterpReader.Handle _ NIL; ReportStatus: PROC [status: PDInterpBasic.Status] RETURNS [abort: BOOLEAN] = { IF reader = NIL THEN { abort _ queue[0].inputHandle.ReportStatus[ status: status, queueSize: queueSize, queuePosition: 0, page: 0, pass: 0, sourceIndex: 0 ] } ELSE { abort _ queue[0].inputHandle.ReportStatus[ status: status, queueSize: queueSize, queuePosition: 0, page: reader.page, pass: reader.pass, sourceIndex: reader.index ] }; }; DO ENABLE PDInterpReader.Warning => {IF ReportStatus[code].abort THEN CONTINUE ELSE RESUME}; WaitForOne[]; reader _ PDInterpReader.Open[queue[0].inputHandle ! PDInterpReader.Error => {[]_ReportStatus[code]; CONTINUE} ]; IF reader # NIL THEN { PrintOne[reader ! PDInterpReader.Error => {[] _ ReportStatus[code]; CONTINUE}]; reader _ PDInterpReader.Close[reader]; }; JobDone[]; ENDLOOP; }; QueueWatch: PROC = { snapshot: ARRAY [0..queueMaxSize) OF PDTransferRpcControl.InterfaceRecord; count: NAT; SnapshotQueue: ENTRY PROC = { WAIT queueChange; count _ queueSize; FOR i: NAT IN [0..count) DO snapshot[i] _ queue[i].inputHandle; ENDLOOP; }; DO SnapshotQueue[]; FOR i: NAT IN [1..count) DO IF snapshot[i].ReportStatus[queued, queueSize, i, 0, 0, 0].abort THEN UnQueue[snapshot[i]]; ENDLOOP; ENDLOOP; }; Process.Detach[FORK QueueWatch[]]; Process.Detach[FORK PrintProcess[]]; PDInterpControlRpcControl.ExportInterface[ interfaceName: [instance: "Plass.pa"L], user: "Plass.pa"L, password: MesaRPC.MakeKey["IOTW3799"L] ]; END. hPDInterpControlImpl.mesa Michael Plass, November 17, 1983 4:58 pm !!!!!!! This is a hack !!!!!!! Êd˜Jšœ™J™(šÏk œ¡˜ªJ˜—šœ˜Jšœr˜yJšœ˜JšœÏc=˜Y—šœ œ˜J˜—Jšœœ˜šœ œœ˜Jšœ2˜2Jšœ˜Jšœ˜—Jšœ œ˜Jšœœœ ˜-J˜Jšœ œ˜šÏnœœœ˜šœœœ˜$Jšœœ˜.Jšœ˜—šœœœ˜Jšœ˜Jšœ˜—Jšœ˜Jš œ ˜Jšœ˜J˜—šŸœœœ˜Jšœ"˜"šœœœ˜Jšœ˜Jšœ˜—Jšœ ˜ Jš œ ˜Jšœ˜J˜—šŸœœœ3˜FJšœœœ˜šœœœ˜Jšœœ˜#Jšœ'˜+Jšœ˜—Jšœœ œ˜AJšœ˜J˜—šŸœœ(œ6˜}J™Jšœ4˜4šœœ/˜NJšœ˜Jšœ%˜%Jšœ˜—Jšœ˜J˜—š Ÿœœ œœœ˜VJšœA˜AJšœQ˜QJšœœœ œ˜;Jšœ&˜&Jšœ˜Jš œ ˜Jšœ˜J˜—šŸœœ$˜2Jšœ œœ˜š œœœœ ˜.Jšœ,˜,Jšœœ˜ šœ œ ˜šœœ˜+šœ:˜:šœ˜#Jšœ|˜|Jšœœ˜Jšœ˜Jšœœ˜—Jšœ˜—Jšœœ˜—Jšœ˜—šœ œ˜-šœ'œ˜/Jšœm˜mJšœ0˜0Jšœ.˜.Jšœ˜—Jšœ œ˜Jšœ˜—Jšœ!˜!Jšœ˜—Jšœk˜kJšœ˜J˜—šŸ œœœ˜Jšœœœ œ˜0Jšœ˜J˜—šŸ œœ˜Jšœ œ˜$šŸ œœ œ œ˜Nšœ œœ˜šœ*˜*Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜—J˜—šœ˜šœ*˜*Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜—Jšœ˜—Jšœ˜—šœœœœœœœ˜\Jšœ ˜ šœ1˜1Jšœ2œ˜;Jšœ˜—šœ œœ˜JšœDœ˜OJšœ&˜&Jšœ˜—Jšœ ˜ Jšœ˜—Jšœ˜J˜—šŸ œœ˜Jšœ œœ&˜JJšœœ˜ šŸ œœœ˜Jšœ ˜Jšœ˜šœœœ ˜Jšœ#˜#Jšœ˜—Jšœ˜—š˜Jšœ˜šœœœ ˜Jšœ?œ˜[Jšœ˜—Jšœ˜—Jšœ˜J˜—Jšœœ˜"Jšœœ˜$šœ*˜*Jšœ'˜'Jšœ˜JšœÏhœ˜&Jšœ˜—J˜Jšœ˜—…—ªv