Hamilton LaboratoriesHamilton C shell 2012User guideTutorials

Interrupts

Oregon Coast

Interrupts
Previous | Next

Topics

Interrupts
Masking interrupts
See also

Interrupts

Normally, when you type Ctrl-C, you interrupt the foreground activity. But what if you were in the midst of a complex script and needed to do some kind of cleanup before you exited? What if you wanted to be sure you had a chance to delete any temporary files you might have littered around?

The solution is the onintr statement, which allows you to define the action to be taken when an interrupt is received. It causes whatever’s running to be interrupted all the way back up to the block in which the onintr routine was defined and for the interrupt routine to be run in that current thread. Within that interrupt routine, you could, for example, remove all your temporary files and goto the end of the script or return a special value from a procedure or whatever else might be appropriate.

530 D% onintr echo hello 531 D% for i = 1 to 5 do 532 D? echo $i 533 D? sleep 1 534 D? end 1 ^C hello

Here’s another example, returning from a procedure. Note how the value returned (and printed) is the one produced by the onintr statement.

535 D% proc foobar() 536 D? onintr return 5 537 D? for i = 1 to 5 do 538 D? echo $i 539 D? sleep 1 540 D? end 541 D? return 2 542 D? end 543 D% foobar 1 ^C 5

When execution leaves the block in which an onintr is defined, the previous onintr (if any) again takes effect. Note that a null onintr routine does not mean that interrupts are ignored, merely that after processing bubbles back up to the level where that onintr was defined, that it will continue with the next statement. Notice how, in this example, when the Ctrl-C is received when obviously execution is stuck in the infinite loop inside bar, that the onintr goto xx causes a branch to xx in the same block in which the onintr was defined, not the xx in the block where execution was going on. Also, notice that once both procedures have been exited, we’re back to the same onintr routine we defined a few statements earlier.

544 D% proc foo() 545 D? onintr goto xx 546 D? bar 547 D? xx: echo this is foo 548 D? end 549 D% proc bar() 550 D? while (1) # Deliberately infinite loop 551 D? end 552 D? xx: echo this is bar 553 D? end 554 D% foo ^C this is foo 555 D% ^C hello 555 D% _

Masking interrupts

In cases where you’d like to simply turn off interrupts or defer processing them, use the irqmask variable. By default, it’s set to 0, meaning interrupts will be accepted immediately. Setting it to 1 means interrupts will be deferred until the mask is cleared again. Setting it to 2 means interrupts will be totally ignored.

irqmask is a per-thread variable, meaning each thread can independently decide how it will respond to interrupts. Each new thread always starts out with irqmask = 0 (interrupts enabled).

See also

Miscellaneous statements
Order of evaluation
Tutorial: Scheduling

Previous | Next

Getting started with Hamilton C shell

Hamilton C shell, as it first wakes up.

Getting started with Hamilton C shell

A first few commands.

You can set the screen colors to your taste.

You can set the screen colors to your taste.