As of version 3.1.0, SWI-Prolog is able to handle software interrupts (signals) in Prolog as well as in foreign (C) code (see section 12.4.17).
Signals are used to handle internal errors (execution of a non-existing CPU instruction, arithmetic domain errors, illegal memory access, resource overflow, etc.), as well as for dealing with asynchronous interprocess communication.
Signals are defined by the POSIX standard and part of all Unix machines. The MS-Windows Win32 provides a subset of the signal handling routines, lacking the vital functionality to raise a signal in another thread for achieving asynchronous interprocess (or interthread) communication (Unix kill() function).
on_signal(Signal, Current, Current)
.
The action description is an atom denoting the name of the predicate that will be called if Signal arrives. on_signal/3 is a meta-predicate, which implies that <Module>:<Name> refers to <Name>/1 in module <Module>. The handler is called with a single argument: the name of the signal as an atom. The Prolog names for signals are explained below.
Four names have special meaning. throw
implies Prolog
will map the signal onto a Prolog exception as described in section
4.10,
ignore
causes Prolog to ignore the signal entirely,
debug
specifies the debug interrupt prompt that is
initially bound to SIGINT
(Control-C) and default
resets the handler to the settings active before SWI-Prolog manipulated
the handler.
Signals bound to a foreign function through PL_signal()
are reported using the term ’$foreign_function’(Address)
.
After receiving a signal mapped to throw
, the exception
raised has the following structure:
error(signal(<SigName>, <SigNum>), <Context>)
The signal names are defined by the POSIX standard as symbols of the
form SIG
<SIGNAME>. The Prolog name for a
signal is the lowercase version of <SIGNAME>. The
predicate current_signal/3
may be used to map between names and signals.
Initially, the following signals are handled unless the command line option --no-signals is specified:
SIGUSR2
. See also --sigalert. New
can be a signal name or number. See on_signal/3
for how the Prolog signal name is defined. The Old argument
is unified to the signal name if known and the number otherwise. Notably
the value 0 (zero) indicates that the system does not use an alarm
signal. On POSIX systems, this implies that system calls are not
interrupted by
thread_signal/2.
This predicate is only defined on systems where the alert signal mechanism is used.
Before deciding to deal with signals in your application, please consider the following:
throw
are unsafe. Handlers defined to call a predicate are safe. Note that the
predicate can call throw/1,
but the delivery is delayed until Prolog is in a safe state.
The C-interface described in section
12.4.17 provides the option
PL_SIGSYNC
to select either safe synchronous or unsafe
asynchronous delivery.
throw
or a foreign handler, signals are delivered
immediately (as defined by the OS). When using a Prolog predicate,
delivery is delayed to a safe moment. Blocking system calls or foreign
loops may cause long delays. Foreign code can improve on that by calling PL_handle_signals().
Signals are blocked when the garbage collector is active.