DIRECTORY
ControlMessages USING [Key],
ForwardingControl USING [CancelProc, TraceLevel, WaitChoice],
MiscUtilities USING [KeyForCommunicationStatus],
NSFile USING [Attribute, Close, Error, Handle, Open, nullHandle, nullTime, Session, Time],
NSString USING [String, StringFromMesaString],
PaperTypes USING [Paper],
PrintingTypes USING [Option],
PrintQueue USING [Empty, nilQueueObjectHandle, Priority, ObjectStatus, QueueObjectHandle, QueueStage, QueueWatcher, Requeue],
Process USING [Detach, Pause, Priority, SecondsToTicks, SetPriority, SetTimeout],
PSAssignedTypes USING [tSpooled],
PSAsyncMsg USING [ExpandArrayAndPutString, Insert, Proc, PutMesaString],
PSKMessages USING [GetHandle],
PSVolume USING [GetDefaultSession, GetDirectory],
String USING [AppendDecimal, AppendLongDecimal, Overflow, StringBoundsFault],
System USING [gmtEpoch, GetGreenwichMeanTime, NetworkAddress, nullNetworkAddress, nullID, Overflow, SecondsSinceEpoch, UniversalID],
TargetPS USING [Error, ForwardDocument],
TargetPSStatus USING [Communication],
XMessage USING [Handle, MsgKey];
ForwardingControlImpl:
CEDAR
MONITOR
IMPORTS MiscUtilities, NSFile, NSString, PrintQueue, Process, PSAsyncMsg, PSKMessages, PSVolume, String, System, TargetPS
EXPORTS ForwardingControl =
BEGIN
Control:
TYPE =
RECORD [
stop: BOOLEAN ← TRUE,
start: BOOLEAN ← FALSE,
jobQueueEntry: BOOLEAN ← FALSE,
tpQueueEntry: BOOLEAN ← FALSE
];
State:
TYPE =
RECORD [
stopped: BOOLEAN ← TRUE,
forwarding: BOOLEAN ← FALSE,
lastForwardingStatus: TargetPSStatus.Communication ← okay,
targetPS: XNS.Address ← XNS.nullAddress,
tpJob: BOOLEAN ← FALSE,
file: FS.OpenFile ← FS.nullOpenFile,
trace: ForwardingControl.TraceLevel ← none,
qOH: PrintQueue.QueueObjectHandle ← PrintQueue.nilQueueObjectHandle,
stopStatus: PrintQueue.ObjectStatus ← canceledInForwarder, --specified in Stop call
canceledWhileForwarding: ForwardingControl.CancelProc ← NIL,
putAsyncMsgFromKey: PSAsyncMsg.Proc ← NIL,
startForwardingTime: BasicTime.GMT ← BasicTime.nullGMT
];
event: CONDITION;
stopped: CONDITION;
control: Control ← [];
state: State ← [];
Message domain handle:
controlMsgs: XMessage.Handle ← PSKMessages.GetHandle[control];
session: NSFile.Session = PSVolume.GetDefaultSession[];
Init:
PUBLIC
ENTRY
PROCEDURE [currentOption: PrintingTypes.Option, priority: Process.Priority,
putAsyncMsgFromKey: PSAsyncMsg.Proc] =
TRUSTED
BEGIN
ENABLE UNWIND => NULL;
IF currentOption # feps9700 THEN ERROR;
state ← [putAsyncMsgFromKey: putAsyncMsgFromKey];
PrintQueue.QueueWatcher[proc: JobQueueEntry, queueStage: merged];
PrintQueue.QueueWatcher[proc: TPQueueEntry, queueStage: tpMerged];
Process.SetTimeout[@event, Process.SecondsToTicks[seconds: 30]]; --check queue every 30 secs
Process.Detach[FORK ForwardingControlLoop[priority]];
END; --Init
Queue:
ENTRY
PROCEDURE [status: PrintQueue.ObjectStatus] =
BEGIN
ENABLE UNWIND => NULL;
IF state.qOH = PrintQueue.nilQueueObjectHandle
THEN
BEGIN
IF state.trace # none THEN PSAsyncMsg.PutMesaString["##Can't Queue nilQOH! "];
RETURN;
END;
IF state.trace # none
THEN
BEGIN
forwardTime: LONG CARDINAL ← 0;
sDoneForwarding: LONG STRING ← "//Done Forwarding ""<1>""; status= <2>; seconds= <3>"L;
sSeconds: LONG STRING ← [10];
nsDoneForwarding: NSString.String ← Str[sDoneForwarding];
stringArray: ARRAY [0..3) OF NSString.String;
startSinceEpoch: LONG CARDINAL ← System.SecondsSinceEpoch[state.startForwardingTime];
endSinceEpoch: LONG CARDINAL ← System.SecondsSinceEpoch[System.GetGreenwichMeanTime[]];
IF endSinceEpoch >= startSinceEpoch
THEN
forwardTime ← endSinceEpoch - startSinceEpoch;
stringArray[0] ← state.qOH.fileName;
stringArray[1] ← Str[
SELECT status
FROM
merged => "merged"L,
canceledInForwarder => "canceledInForwarder"L,
forwardFailure => "forwardFailure"L,
ENDCASE => "forwarded"L];
String.AppendLongDecimal[sSeconds, forwardTime
! System.Overflow, String.Overflow, String.StringBoundsFault => CONTINUE];
stringArray[2] ← Str[sSeconds];
PSAsyncMsg.ExpandArrayAndPutString[nsDoneForwarding, DESCRIPTOR[stringArray]]
END;
state.qOH.currentStatus ← status;
IF state.file # NSFile.nullHandle
THEN
NSFile.Close[state.file, session]; --close interleaved ip file
SELECT
TRUE
FROM
status = merged =>
BEGIN
[] ← PrintQueue.Requeue[
qOH: state.qOH, fromQueue: forwarding, toQueue: merged, position: front];
END;
status = canceledInForwarder =>
BEGIN
[] ← PrintQueue.Requeue[
qOH: state.qOH, fromQueue: forwarding, toQueue: aborted];
IF state.canceledWhileForwarding #
NIL
THEN
state.canceledWhileForwarding[state.qOH.fileName, status];
END;
status # forwarded =>
[] ← PrintQueue.Requeue[
qOH: state.qOH, fromQueue: forwarding, toQueue: aborted];
ENDCASE =>
[] ← PrintQueue.Requeue[
qOH: state.qOH, fromQueue: forwarding, toQueue: forwarded];
state.file ← NSFile.nullHandle;
state.forwarding ← state.tpJob ← FALSE;
state.qOH ← PrintQueue.nilQueueObjectHandle;
control.jobQueueEntry ← NOT PrintQueue.Empty[merged];
control.tpQueueEntry ← NOT PrintQueue.Empty[tpMerged];
NOTIFY event; -- in case there's something to do
END; --Queue
DisplayForwardingStatus:
PROCEDURE [why: TargetPSStatus.Communication] =
BEGIN
insertArray: ARRAY [0..1) OF PSAsyncMsg.Insert ← ALL[];
insertArray[0].m ← MiscUtilities.KeyForCommunicationStatus[why];
state.putAsyncMsgFromKey[
msg: [domain: controlMsgs, key: XKey[mForwardingError]],
insertArray: DESCRIPTOR[insertArray]];
END;
--DisplayForwardingStatus
XKey:
PROCEDURE [key: ControlMessages.Key]
RETURNS [xKey: XMessage.MsgKey] =
{RETURN[ORD[key]]};
Str:
PROCEDURE [s:
REF
TEXT]
RETURNS [ns: NSString.String] =
INLINE {
RETURN[NSString.StringFromMesaString[s]]};
END. -- of ForwardingControlImpl
22-Oct-84 10:44:03 - Jacks - Created.
29-Oct-84 11:53:06 - Jacks - Added bannerOnly reference in call to ForwardDocument; added call to TargetPS.ForwardDocument.
16-Nov-84 12:05:05 - Jacks - Updated to second round of 9.0 ps interface changes.
17-Jan-85 14:46:42 - Jacks - Added reset of lastForwardingStatus in ForwardDocument proc; added prefix "ps" to msg keys for 9.0.