A SignalWatcher
is part of the CoCoA mechanism for detecting and
reacting to interprocess signals (sometimes known as "interrupts").
Since CoCoALib is a software library, it does not change any existing
signal handlers unless you tell to do so explicitly. A SignalWatcher
is an RAII object: creating it installs CoCoA's "signal handler" for
the given signal; destroying it, reinstates the previous "signal
handler".
A SignalWatcher
by itself does not do much: it simply "takes note"
when a signal of the given type arrives. CoCoALib can react to a
signal only after it has been noted by a SignalWatcher
and
the procedure CheckForInterrupt
is called -- see interrupt
for a summary, or look at the example programs.
If several signals arrive before CheckForInterrupt
is called, only
the last signal is heeded; the others are "forgotten".
SignalWatcher(sig)
-- install the standard CoCoALib signal handler for the
signal sig
(usually this will be SIGINT
)
SignalWatcher(sig, OtherHandler)
-- install OtherHandler
for the signal
sig
; OtherHandler
is of type void OtherHandler(int)
DESTRUCTOR
-- the destructor reinstates the previous handler for the signal
specified in the constructor
The exception which thrown when CheckForInterrupt
detects a signal is
created by the following constructor:
InterruptedBySignal(sig, context)
-- where sig
is an int
indicating the
signal which has arrived, and context
is a string literal (usually indicating
the function which was interrupted)
Let SW
be a SignalWatcher
.
IsActive(SW)
-- true
iff SW
has not been deactivated (see below)
GetAndResetSignalReceived()
-- returns an int
: zero if no signal has arrived,
otherwise the integer value of the signal. Resets the register of last-signal-received.
Let SW
be of type SignalWatcher
; and let INTR
be of type InterruptedBySignal
deactivate(SW)
-- effectively "destroys" SW
, _i.e._ reinstates the previous signal handler
TriggeringSignal(INTR)
-- returns an int
indicating the signal specified when creating INTR
SetSignalReceived(sig)
-- sets the register of last-signal-received to sig
; note that zero
means no signal received. You probably should not use this function!
The implementation is straightforward (except for SetSignalReceived
which still involves a "dodgy hack" from an earlier implementation).
For portability the CoCoALib signal handler just sets
a "hidden" global variable CoCoA::<anon>::SignalReceived
(of type std::sig_atomic_t
).
The CoCoALib signal handler is registered by creating an object
of type SignalWatcher
; its constructor takes as arg the signal
to detect. The original signal is restored when the SignalWatcher
is destroyed (or when the mem fn myDeactivate
is called).
I do not know how threadsafe the implementation is: hopefully it is good, but I doubt it is perfect.
2017