The article directories

$HALT variable

Contains pause trap routine calls.

The outline

$HALT
Copy the code

describe

$HALT contains the name of the current pause trap routine. When the HALT command is encountered, the application invokes the pause trap routine. The pause trap routine can perform cleanup or logging processing before issuing the HALT command, or it can substitute other processing instead of suspending program execution.

You can use the SET command to SET $HALT as a pause trap routine. The pause trap routine is specified by a quoted string in the following format

SET $HALT=location
Copy the code

The position here can be specified as label (the label in the current routine or procedure), ^routine (specifying the start of the external routine), or label^routine (specifying the specified label in the external routine).

$HALT supports label + offset in some cases (but not in the program). The optional +offset is an integer that specifies the number of rows to be offset from the label. InterSystems recommends avoiding row offsets when specifying locations.

You cannot specify a + offset when calling a procedure or CACHESYS % routine. If you try to do so, the Cache issues a

error.

$HALT defines a pause trap routine for the current context. If a stop trap has been defined for the current context, the new trap replaces it. If a non-existent routine name is specified, the HALT command ignores $HALT and expands the stack to locate the valid $HALT at the previous context level.

To remove the pause trap for the current context, set $HALT to an empty string. Attempting to remove the pause trap using the NEW or KILL commands results in a

error.

Pause trap execution

When the HALT command is issued, the Cache checks $HALT in the current context. If $HALT is not defined for the current context (or set to a nonexistent routine name or an empty string), the Cache expands the stack to the previous context and looks for $HALT in it. This process continues until the defined $HALT is found or the stack is completely unrolled. The Cache uses the value of $HALT to move execution to the specified pause trap routine. The pause trap routine executes in the context in which $HALT is defined. No error codes are set or error messages are sent.

If no valid $HALT is set in the current or previous context, issuing the HALT command will fully unroll the stack and perform the actual program pause.

Typically, the pause trap routine performs some cleanup or reporting processing and then issues the HALT command. Note that in the case of $HALT defined, the original HALT command invokes the pause trap, but does not perform the actual program pause. To actually stop, the stop trap routine must contain a second HALT command.

HALT commands issued by the pause trap routine are not caught by the pause trap, but may be caught by pause traps established at lower context levels. Thus, a cascade of stop traps can be invoked by a single HALT command.

$the HALT and ^ % ZSTOP

If $HALT is set and code is defined for ^%ZSTOP when HALT is issued, $HALT is executed first. $HALT prevents the process from terminating if its HALT trap routine does not contain HALT commands.

When the process actually terminates, the ^%ZSTOP routine is executed.

The sample

The following example uses $HALT to set up a HALT trap:

/// d ##class(PHA.TEST.SpecialVariables).HALT()
ClassMethod HALT(a)
{
   SET $HALT="CleanupRoutine"WRITE ! ."the halt trap is: ",$HALT
CleanupRoutine
	w 1
}
Copy the code
DHC-APP>d ##class(PHA.TEST.SpecialVariables).HALT(a)the halt trap is: + 101 ^PHA.TEST.SpecialVariables11.Copy the code

Note that the terminal ensures that the specified routine exists.

The following example shows how to execute a pause trap routine in the context of defining $HALT. In this example, $HALT is defined as $ESTACK level 0, HALT is emitted as $ESTACK level 1, and the pause trap routine executes at $ESTACK level 0.

/// d ##class(PHA.TEST.SpecialVariables).HALT1()
ClassMethod HALT1(a)
{
Main
	NEW $ESTACK
	SET $HALT="OnHalt"WRITE ! ."Main $ESTACK= ",$ESTACK," $HALT= ",$HALT   / / 0DO SubA WRITE ! ."Returned from SubA"   // not executedQUIT SubA WRITE ! ."SubA $ESTACK= ",$ESTACK," $HALT= ",$HALT   / / 1HALT WRITE ! ."this should never display"QUIT OnHalt WRITE ! ."OnHalt $ESTACK= ",$ESTACK   / / 0
	HALT
	QUIT
}
Copy the code

The following example is the same as the previous one, except that $HALT is defined at $ESTACK level 1. HALT commands issued at $ESTACK level 1 and pause trap routines executed at $ESTACK level 1. The pause trap routine unhooks the stack, and if $HALT defined at the previous context level is not found, it suspends program execution. Therefore, the WRITE command following the DO command is not executed.

/// d ##class(PHA.TEST.SpecialVariables).HALT2()
ClassMethod HALT2(a)
{ Main NEW $ESTACK WRITE ! ."Main $ESTACK= ",$ESTACK," $HALT= ",$HALT   / / 0DO SubA WRITE ! ."Returned from SubA"   // not executed
	QUIT
SubA
	SET $HALT="OnHalt"WRITE ! ."SubA $ESTACK= ",$ESTACK," $HALT= ",$HALT   / / 1HALT WRITE ! ."this should never display"QUIT OnHalt WRITE ! ."OnHalt $ESTACK= ",$ESTACK   / / 1
	HALT
	QUIT
}
Copy the code

The following example shows how to invoke a cascading series of pause traps. Pause trap Halt0 is defined as $ESTACK level 0, and pause trap Halt1 is defined as $ESTACK level 1. The HALT command is issued at $ESTACK level 2. The Cache unwinds the stack to invoke the pause trap Halt1 at $ESTACK level 1. The stop trap issues a HALT command. The Cache unwinds the stack to call the pause trap Halt0 at $ESTACK level 0. This pause trap issues a HALT command, which pauses program execution.

/// d ##class(PHA.TEST.SpecialVariables).HALT3()
ClassMethod HALT3(a)
{
Main
	NEW $ESTACK
	SET $HALT="Halt0"WRITE ! ."Main $ESTACK= ",$ESTACK," $HALT= ",$HALT   / / 0DO SubA WRITE ! ."Returned from SubA"   // not executed
	QUIT
SubA
	SET $HALT="Halt1"WRITE ! ."SubA $ESTACK= ",$ESTACK," $HALT= ",$HALT   / / 1DO SubB WRITE ! ."Returned from SubA"   // not executedQUIT SubB WRITE ! ."SubB $ESTACK= ",$ESTACK," $HALT= ",$HALT   / / 2HALT WRITE ! ."this should never display"QUIT Halt0 WRITE ! ."Halt0 $ESTACK= ",$ESTACK   / / 0WRITE ! ."Bye-bye!"HALT QUIT Halt1 WRITE ! ."Halt1 $ESTACK= ",$ESTACK   / / 1
	HALT
	QUIT
}
Copy the code