GDSX (Extended General Device Support) Manual

DEVICE^HANDLER Example, Design
Extended General Device Support (GDSX) Manual529931-001
5-19
The USER^STOP Procedure
The USER^STOP Procedure
In an exercise in the previous section, an SU was stopped with an SCF ABORT
command. The abort message was sent to TSCODE, which then stopped the
DEVICE^HANDLER task.
When the task was stopped, the USER^STOP user exit was called by TSCODE, as
shown in Example 5-5. Because the stopped task, whose TCB address is passed in
the call to USER^STOP, was waiting on a ^WRITEREAD (dcb.wt^rd^pend equal to
TRUE) and was indeed a DEVICE^HANDLER task (in which case tcb.state is less than
or equal to 15), then ^CANCEL was called on the file to which the task was mapped
(tcb.term, which is the same as term^file^num for the DEVICE^HANDLER task).
The variable dcb.wt^rd^pend was tested to see whether a WRITEREAD was pending,
because attempting to cancel a nonexistent I/O operation may cause the GDSX
process to stop. Calling ^CANCEL cancels the last incomplete operation sent to the
file, the ^WRITEREAD, which in this case, because the DEVICE^HANDLER effectively
uses waited I/O, was also the only outstanding operation. The ^CANCEL resulted in
TSCODE deleting the IOCB associated with the request and returning a file-system
error 66 to the requester process. The requester then sent a close message to GDSE
and stopped itself.
The SU was not configured under a LINE, so dcb.lineno is equal to 0, and therefore the
“D^H TASK STOPPED“ message was written to the task’s file.
Fault-Tolerance Processing
The next part of the tutorial uses Inspect to observe the action of GDSX fault-tolerance
features of the DEVICE^HANDLER example. TSCODE provides several features for
Example 5-5. The USER^STOP Procedure
PROC USER^STOP (TCB);
INT .EXT TCB(TCB^TEMPLATE);
BEGIN
INT FILENO;
INT MESSG[0:8] := "D^H TASK STOPPED ";
INT .EXT DCB(DCB^TEMPLATE);
@DCB := TCB.DCBADDR;
IF ((TCB.STATE.<10:15> < 16 ) ! A D^H TASK IS BEING STOPPED
AND
(DCB.WT^RD^PEND = TRUE)) THEN ! WAITING ON A WRITEREAD
BEGIN ! CANCEL OUTSTANDING I/O FROM A D^H TASK
CALL ^CANCEL(TCB.TERM); ! (EITHER FOR DEVICE I/O OR FOR ITC)
IF <> THEN CALL DEBUG;
IF (DCB.LINENO = 0 ) THEN
BEGIN
FILENO := TCB.TERM;
CALL ^WRITE(FILENO, MESSG, 18); !We don't use WRITEX
IF <> THEN CALL DEBUG; !because MESSG is in local stack
CALL ^AWAITIO(FILENO);
END;
END;
END;