Harlequin RIP SDK
Stopping the Harlequin RIP and SDK

The Harlequin RIP SDK and the RIP itself may be started and shutdown many times in your application process's lifetime. You can stop the RIP without shutting down the SDK, or you can shutdown both the RIP and the SDK. You may want to shutdown the RIP, but leave the SDK running if:

  • You have a memory intensive processing step after RIPping a whole job, and you want to use the memory that was allocated to the RIP for it. (Note that the memory allocated to the RIP will be returned to the operating system by MPS, the address space allocated will remain under its control. So you will either need to ensure you have sufficient address space range to allocate outside MPS, or use MPS to allocate for your processing step.)
  • You want to ensure a complete "hard reboot" of the RIP, but want to retain any extra modules or backends installed during the start up process.
  • You may want to use the capabilities provided in the SDK in your own application. For example, RDR, Events, and Timelines may be useful for decoupling components or monitoring processing steps; Timers may be useful for cross-platform programmable callbacks; Hot folders and the Input Queue may be kept running if you wish to prepare jobs for RIPping while the RIP itself is not running.

Stopping the RIP

Once the RIP is started, it will ultimately be stopped by processing a special fragment of configuration PostScript in a stop job. The special fragment of configuration PostScript that will be run is defined in the SDK in a macro called SW_LE_STOP_PS. This same fragment of PostScript may be submitted to the RIP using an API call, by a signal handler, as a configuration job, or as a normal job through any input method, including by writing a file containing the configuration PostScript into a hot folder file. The configuration PostScript that stops the RIP is:

/HqnConfigProvider /ProcSet findresource /quitrip get exec

The method you use to stop the RIP depends upon whether it is waiting for input and whether you want to complete processing of jobs on the input queue first. If your job processing loop calls SwLeDo() or SwLeProcessJobs() with SwLeDoParams::fProcessQueueWait set to TRUE, then your application thread may be blocked waiting for more input to arrive on the input queue. In this case, you need to either:

If the job processing loop is not running and is not blocked then you can either:

Submitting a stop job directly to the input queue

To submit the stop job directly from an application thread, queue the stop job PostScript as a configuration job:

int32 job_id = -1 ;
-1, // end of queue
&job_id) != SW_INPUTQ_SUCCESS ) {
// ...Can't submit stop job. Take more drastic action...
}
#define inputq_print_job
Insert a job into the input queue for printing by the RIP.
Definition: inputsapi.h:401
@ SW_INPUTQ_SUCCESS
Definition: inputsapi.h:91
#define SW_LE_STOP_PS
PostScript to shut down the RIP.
Definition: skinkit.h:657
uint8_t uint8
8-bit unsigned integer
Definition: hqtypes.h:88
int32_t int32
32-bit signed integer
Definition: hqtypes.h:91
#define NULL
Definition of NULL pointer.
Definition: hqtypes.h:37

This will stop the RIP after processing all jobs currently on the queue. If you wish to stop after the current job rather than waiting for all queued jobs to complete, simply change the queue insertion position to the start of the queue:

int32 job_id = -1 ;
0, // start of queue
&job_id) != SW_INPUTQ_SUCCESS ) {
// ...Can't submit stop job. Take more drastic action...
}

If you wish to stop the RIP immediately without waiting for any jobs currently processing to complete, you can follow the method used by the signal handler to stop the RIP.

Submitting a stop job indirectly through an input source

You may stop the RIP indirectly, if you have registered an input source, by ensuring that the stop job PostScript is presented by that input source. For example, if you have started a hot folder, you can write the stop job PostScript to a file in that hot folder. You do not have much control over when the stop job will be processed using this method, it is better to submit the stop job directly. However, this method may be useful when the RIP is running as a persistent server process, and a different process is being used to submit jobs to the RIP through an input source.

Stopping the RIP from the application program

If the job processing loop is not running, then the preferred method of stopping the RIP is to call SwLeDo() with the SW_LE_DO_RIP_STOP or SW_LE_DO_SHUTDOWN operations.

Shutting down the RIP using low-level functions

The low-level function SwLeStop() is called by SwLeDo() to shut down the RIP. SwLeDo() is preferred because it performs state checks to ensure the RIP is running before attempting to shut it down, and can also perform SDK shutdown if desired in the same call.

SIGINT and control-C handling

The "clrip" application layer installs a control-C or signal handler to shut the RIP down cleanly on receiving a process interrupt. The handler is installed after the RIP is started (so that the RIP threads do not attempt to execute it) using the PKSetCtrlCHandler() SDK function.

The "clrip" handler shows the best practice for trying to stop the RIP cleanly from a signal handler:

  1. If it has been called before, it issues a message, and does not attempt to shut down again.
  2. It pauses the input queue, so jobs will not be started while the handler is running.
  3. It issues an interrupt event, with the timeline reference set to interrupt all jobs.
  4. It inserts the special stop job at the start of the input queue: if it cannot do this, it issues an asynchronous PostScript request to stop the RIP.
  5. It restarts the input queue.

The RIP should interrupt the current job, stop its processing, and then run the stop job and terminate itself. This same sequence of operations can be followed if you do not want to wait for all jobs on the queue to complete before stopping the RIP.

Rebooting the RIP

The RIP can be forced to perform a "soft reboot" by executing a fragment of PostScipt:

systemdict /quit get exec

This will restart the interpreter, forgetting any base configuration installed on startup. Soft reboots are unusual, and are not normally expected when operating the RIP. A soft reboot does not terminate the RIP threads, or return RIP memory to the operating system. You may install a callback function that will notify you of soft reboots by using SwLeSetRipRebootFunction(). If the RIP is rebooted in this way, your callback function will be called as the interpreter terminates the RIP. You may use this to re-submit changes to the base configuration.

RIP failures and exit values

The RIP returns an exit value, indicating if there was an error starting the RIP up or if it processed jobs and shut down normally. The exit value is stored in the SwLeDoParams::exitvalue field. It does not indicate anything about the status of jobs processed by the RIP, only whether the RIP started up and shut down normally. The exit value will be zero if the RIP started and shutdown normally.

The exit value itself does not directly indicate all reasons for RIP failure, just that the RIP shut down normally or abnormally. You may to capture the reason for a failure by installing an exit callback using SwLeSetRipExitFunction(), after initializing the SDK runtime. Your callback function will be provided with the exit value and an error detail string. The error detail string will be NULL when the exit value is zero, indicating success. The RIP exit function will also capture failure reasons in the SDK initialization functions, up to the point that the RIP is started.

Shutting down the SDK

Stopping the RIP using SW_LE_DO_RIP_STOP or SwLeStop() terminates the RIP threads, but leaves the SDK still initialized. You may restart the RIP by calling SwLeDo() with any state up to and including SW_LE_DO_PROCESS_QUEUE. If you made modifications to the base configuration of the RIP, you will need to re-submit them when restarting the RIP.

Alternatively, you may wish to terminate the entire SDK, releasing all memory, address space, and other resources reserved by it. The recommended method to shutdown the Harlequin RIP SDK is to call SwLeDo() with the SW_LE_DO_SHUTDOWN operation.

Shutting down the SDK using low-level functions

Older integrations may use the control flow functions individually. Calling SwLeDo() with SW_LE_DO_SHUTDOWN will ensure that the functions SwLeSDKEnd() and then SwLeShutdown() are called as necessary, and in the right order. There is no good reason to call these low-level functions directly, and there is no operation that can be usefully performed in between these function calls.

After SDK shutdown

After shutting down the SDK, you may restart it again by repeating the steps in Starting the Harlequin RIP.