The Harlequin server loop
This page applies to Harlequin v13.1r0 and later; and to Harlequin Core but not Harlequin MultiRIP.
The purpose of the server loop is to obtain and run PostScript-language jobs continuously in a protected environment, so that one cannot affect the next. The protected environment is provided by the PostScript-language save
and restore
operators, and the stopped
operator to catch errors.
Therefore, there are three exceptions to the protections provided by this mechanism: changes to the filing system made through the device interface; setting system and device parameters, which are not subject to save
/ restore
contexts; and use of the exitserver
or startjob
procedures.
The server loop actually consists of three nested loops:
- The inner loop waits for data to become available on the
%config%
device. It checks for this by using thebytesavailable
operator. If no data is waiting, the RIP performs idle-time tasks (if this behavior is turned on). - The middle loop runs the inner loop and then repeatedly runs the file
(%config%)
to completion, until it findstrue
on the operand stack. If it findsfalse
, it returns to the inner loop; any other value is an error. - The outer loop runs the PostScript jobs, normally to completion, identified by the file objects left on the stack under the
true
returned by the%config%
device.
The server loop is simply implemented as a set of PostScript-language procedures, albeit using some rather specialized operators, files and devices. The much-simplified version given below (among other things not showing how exitserver
/ startjob
operates) illustrates the key points most easily.
Because the RIP can handle input from several types of jobs, the relevant operator is not always exec
. Some of the alternatives are pdfexec
and epsexec
, both described in Operators for handling specific file types.
The executive a method by which PostScript-language code can be executed interactively is treated as one job so far as the server loop is concerned. See the Harlequin RIP OEM Manual for a description of the executive.
do-bootstrap
{ % outer loop
{ % middle loop (%config%)(r) file cvx
{ % inner loop
dup % the config file bytesavailable 0 ne { exit } if do-some-idle-time-processing
} loop % inner
{
exec % the config file
} stopped {
(ERROR IN CONFIG FILE\n) print false
} if
{ exit } if
} loop % middle
/ouputfile exch def
/inputfile exch cvx def
/outersave save def
serverdict /setrealdevice get exec
/innersave save def
/inputfile load dup /outputfile load statusdict /setstdio get exec
stopped { % execute the job
% it might have stopped because of exitserver /
% startjob, omitted here handle-an-error
} if
innersave restore outersave restore
} loop % outer