Reprinting After Errors

Certain errors, such as complete failure of the printing hardware, are obviously fatal. However, the errors which are most likely to occur in practice during printing can typically be corrected by the user; examples would be a paper jam or running out of paper. The usual requirement when such an error occurs is that the application should detect it, prompt the user to correct it and then continue printing from the point at which it stopped.

It may be inconvenient to test for errors after every line of printing in the application, and in any case if asynchronous printing is implemented the application may have sent other lines to be printed after the line which is causing the error; these will be queued up inside the OSDI. Also, there may be a requirement for some sort of header to be printed when the error has been corrected, before the currently queued printing is resumed.

A suggested approach to this problem is as follows:

1 The application checks for print errors periodically during printing. At most N lines of print are submitted to the OSDI between each check, where N is some fixed number.

2 The OSDI is set up with more than N print buffers (the size of the pdesc[] array should be greater then N).

3 During normal operation, when no error has occurred, the OSDI code ensures that at least N+1 pdesc[] entries are left free at all times. This is done by flushing any outstanding asynchronous printing at the beginning of prn_print() whenever the number of free entries becomes too small. Note that the global variable used_pdesc contains the number of pdesc[] entries currently in use, from which the number free can be calculated.

4 When an error such as a paper jam or running out of paper occurs, the OSDI stops all asynchronous commands currently in progress but does not call prn_complete(), so that they remain in the linked list of pending commands. Also, any additional calls to prn_print() made by the application should return 0 to add the commands to the queue, but does not actually print them. Thus, at the point when the application discovers the error, there are at most N outstanding print commands in the queue, not being processed by the OSDI.

 The user is then be prompted to repair the problem. If this proves impossible, the application should select a POD whose only function is to generate a prn_complete() call for each pdesc[] entry in the linked list, thereby throwing away the pending printing and releasing the pdesc[] entries for reuse. If, however, the problem is corrected by the user, the application selects another POD whose function is to step through the linked list of lines waiting to be printed and restart the printing for each.

5 Any header information to be printed before the printing is restarted is handled via a special COD which prints synchronously regardless of the setting of prn_error.

This approach to error handling has two advantages. Firstly, it is only necessary to test for errors at one point (or at most a few selected points) in the application, so the application error handling code can be made as complicated as required without it being duplicated within the code. Secondly, it provides an automatic mechanism for reprinting lines which were in the process of being printed when the error occurred.

The disadvantage is that, if the number N is under-estimated, the OSDI code might hang waiting for a free pdesc[] entry to become free, while all the pdesc[] entries were taken up with lines waiting to be printed after the error has been repaired.