Interrupts

## 13.3 Interrupts

- Interrupt Identifiers
- Asynchronous handling

Operating systems such as Unix provide a notion of asynchronous interrupts or signals. In a standalone ECLiPSe system, the signals can be handled by defining interrupt handlers for them. In fact, a set of default handlers is already predefined in this case.
In an embedded ECLiPSe, signals are usually handled by the host application, and it is recommended to use the event mechanism described above (the ec_post_event() library function) to communicate between the host application and the ECLiPSe code. However, even in this setting, ECLiPSe can also handle signals directly, provided the programmer sets up a corresponding interrupt handler.

### 13.3.1 Interrupt Identifiers

Interrupts are identified either by their signal number (Unix) or by a name which is derived from the name the signal has in the operating system. Most built-ins understand both identifiers. It is usually more portable to use the symbolic name. The built-in current_interrupt/2 is provided to check and/or generate the valid interrupt numbers and their mnemonic names.

### 13.3.2 Asynchronous handling

When an interrupt happens, the ECLiPSe system calls an interrupt handling routine in a manner very similar to the case of event handling. The only argument to the handler is the interrupt number. Just as event handlers may be user defined, so it is possible to define interrupt handlers. The goal

>     set_interrupt_handler(N, PredSpec)

assigns the procedure specified by PredSpec as the interrupt handler for the interrupt identified by N (a number or a name). Some interrupts cannot be caught by the user (e.g. the kill signal), trying to establish a handler for them yields an error message. Note that PredSpec should be one of the predefined handlers. The use of general user defined predicates is deprecated because of portability considerations.
To test interrupt handlers, the built-in kill/2 may be used to send a signal to the own process.
The predicate get_interrupt_handler/3 may be used to find the current interrupt handler for an interrupt N, in the same manner as get_event_handler:

>     get_interrupt_handler(N, PredSpec, HomeModule)

An interrupt handler has one optional argument, which is the interrupt number. There is no argument corresponding to the error culprit, since the interrupt has no relation to the currently executed predicate. A handler may be defined which takes no argument (such as when the handler is defined for only one interrupt type). If the handler has one argument, the identifier of the interrupt is passed to the handler when it is called.
The following is the list of predefined interrupt handlers:

default/0
  performs the standard UNIX handling of the specified interrupt (signal). Setting this handler is equivalent to calling signal(N, SIG_DFL) on the C level. Thus e.g. specifying

  >         ?- set_interrupt_handler(int, default/0)

  will exit the ECLiPSe system when ∧C is pressed.
true/0
  This is equivalent to calling signal(N, SIG_IGN) on the C level, ie. the interrupt is ignored.
throw/1
  Invoke exit_block/1 with the interupt's symbolic name.
abort/0
  Invoke exit_block(abort).
halt/0
  Terminate the ECLiPSe process.
internal/0
  Used by ECLiPSe to implement internal functionality like the profiler. This is not intended to be used by the user.
event/1
  The signal is handled by posting a (synchronous) event. The event name is the symbolic name of the interrupt.

Apart from these special cases, all other arguments will result in the specified predicate to be called when the appropriate interrupt occurs. This general asynchronous interrupt handling is not supported on all hardware/platforms, neither in an embedded ECLiPSe (including the tkeclipse development environment), and is therefore deprecated.