.TH "FBB::Signal" "3bobcat" "2005\-2022" "libbobcat\-dev_6\&.02\&.02" "signal handler" .PP .SH "NAME" FBB::Signal \- Signal Handler .PP .SH "SYNOPSIS" \fB#include \fP .br Linking option: \fI\-lbobcat\fP .PP .SH "DESCRIPTION" .PP Signals have the well known drawback that signals arrive free of context\&. E\&.g\&., assume a program runs a flow control loop like this: .nf void Class::run() { while (d_continue) handleTasks(); cleanup(); } .fi then if the program needs to recognize a termination signal then the typical signal handler looks like this: .nf void signalHandler(int signal) { // perform required actions } .fi Since the \fIsignalHandler\fP is called asynchronically, there is no context available, and the usual way of communicating between objects and signal handlers is via static variables, like this: .nf // declared as static bool s_continue; bool Class::s_continue = true; void Class::run() { while (s_continue) handleTasks(); cleanup(); } // declared as static void signalHander(int signal); void Class::signalHandler(int signal) { s_continue = false; } .fi The class \fISignal\fP allows the signal handler to operate in the context of a class\&. The advantage of this is that static data members are no longer required and that the signal may be used to control data members of individual objects\&. .PP The signal is now handled by an object, whose class must define a member .nf void signalHandler(size_t signum) override; .fi and this function is responsible for handling the received signal\&. Since it is a member function it may affect its object\(cq\&s local variables and it may call its object\(cq\&s member functions\&. Static data members are not required anymore (see below for an example)\&. .PP Note that, as the signal may arrive at unpredicable times data members that can be modified by \fIsignalHandler\fP should be declared using the \fIvolatile\fP modifier\&. Moreover, data that can be modified by the \fIsignalHandler\fP member and by other class members should be protected by \fImutexes\fP (cf\&. the \fBC++\-11\fP class \fIstd::mutex\fP or \fBpthread_mutex_lock\fP(3posix))\&. .PP .SH "NAMESPACE" \fBFBB\fP .br All constructors, members, operators and manipulators, mentioned in this man\-page, are defined in the namespace \fBFBB\fP\&. .PP .SH "INHERITS FROM" \fISignal\fP is not derived from other classes, but the classes for which signals must be handled by \fISignal\fP must themselves publicly be derived from the class \fIFBB::SignalHandler\fP and must implement a member .nf void signalHandler(size_t signum) override; .fi handling the received signal\&. .PP .SH "CONSTRUCTORS AND OVERLOADED OPERATORS" \fISignal\fP is defined as a \fIsingleton\fP, and does not offer public or protected constructors, nor does it offer overloaded operators\&. .PP .SH "STATIC MEMBER FUNCTION" .IP o \fBstatic Signal &instance()\fP: .br .br This static member can be used to access a reference to the program\(cq\&s single \fISignal\fP object\&. .PP .SH "MEMBER FUNCTIONS" All of \fISignal\fP\(cq\&s member functions can only be called through a reference to the program\(cq\&s \fISignal\fP object, returning a reference to the program\(cq\&s single \fISignal\fP object: .IP o \fBvoid add(size_t signum, SignalHandler &object)\fP: .br .br \fISignalHandler object\fP is activated on arrival of signal \fIsignum\fP\&. If multiple \fISignalHandler\fP objects must be called then multiple \fISignal::add\fP calls can be provided, and the various \fISignalHandler::signalHandler\fP members are called in the same sequence as their respective \fISignal::add\fP calls\&. If one of the earlier \fIsignalHandler\fP members terminates the program then later \fIsignalHandler\fP members are not activated anymore\&. If \fISignal::add\fP is called by, e\&.g\&., an object\(cq\&s constructor, then its destructor should call \fISignal::remove\fP to prevent the object\(cq\&s signal handler from being called after its destruction\&. .IP o \fBvoid remove(size_t signum, SignalHandler &object)\fP: .br .br \fISignalHandler object\fP for signal \fIsignum\fP is removed from the \fISignal\fP object\&. It is the responsibility of \fIobject\fP to deregister itself from \fISignal\fP just before \fIobject\fP goes out of scope\&. Objects can only deregister themselves if they\(cq\&ve previously registered themselves using \fIadd\fP\&. .IP o \fBvoid ignore(size_t signum)\fP: .br .br Any previously installed \fISignalHandler\fP object is no longer activated on arrival of signal \fIsignum\fP\&. In addition, if possible, signal \fIsignum\fP is completely ignored (some signals cannot be caught, blocked, of ignored, like \fISIGKILL\fP and \fISIGSTOP\fP (cf\&. \fBsignal\fP(7)))\&. .IP o \fBvoid reset(size_t signum)\fP: .br .br Any previously installed \fISignalHandler\fP object is no longer activated on arrival of signal \fIsignum\fP\&. In addition, the default action the program takes on arrival of signal \fIsignum\fP is reinstalled (cf\&. \fBsignal\fP(7))\&. .PP If the \fIsignum\fP value that is passed to \fISignal\fP\(cq\&s members is not a defined signal value, then an \fBFBB::Exception\fP exception is thrown\&. .PP .SH "EXAMPLE" .nf #include #include #include #include \(dq\&\&.\&./signal\(dq\& class SignalDemo: public FBB::SignalHandler { volatile size_t d_signal; volatile bool d_continue; pid_t d_pid; public: SignalDemo(); void run(); private: void signalHandler(size_t signum) override; }; using namespace std; using namespace FBB; SignalDemo::SignalDemo() : d_signal(0), d_continue(true), d_pid(getpid()) {} void SignalDemo::run() { while (d_continue) { cout << \(dq\&Send a SIGINT (2) or SIGTERM (15) \&.\&.\&. to process \(dq\& << d_pid << endl; sleep(1); } cout << \(dq\&Ending `run\(cq\& after receiving signal \(dq\& << d_signal << endl; } void SignalDemo::signalHandler(size_t signal) { if (signal == SIGINT) cout << \(dq\&Process \(dq\& << d_pid << \(dq\& received SIGINT\(dq\& << endl; else if (signal == SIGTERM) { cout << \(dq\&Process \(dq\& << d_pid << \(dq\& received SIGTERM\(dq\& << endl; d_signal = SIGTERM; d_continue = false; } } int main() { SignalDemo signalDemo; Signal::instance()\&.add(SIGINT, signalDemo); Signal::instance()\&.add(SIGTERM, signalDemo); signalDemo\&.run(); } .fi .PP .SH "FILES" \fIbobcat/signal\fP \- defines the class interface .PP .SH "SEE ALSO" \fBbobcat\fP(7), \fBpthread_mutex_lock\fP(3posix), \fBsignal\fP(7), .br and the \fBC++\-11\fP class \fIstd::mutex\fP\&. .PP .SH "BUGS" None Reported\&. .PP .SH "BOBCAT PROJECT FILES" .PP .IP o \fIhttps://fbb\-git\&.gitlab\&.io/bobcat/\fP: gitlab project page; .IP o \fIbobcat_6\&.02\&.02\-x\&.dsc\fP: detached signature; .IP o \fIbobcat_6\&.02\&.02\-x\&.tar\&.gz\fP: source archive; .IP o \fIbobcat_6\&.02\&.02\-x_i386\&.changes\fP: change log; .IP o \fIlibbobcat1_6\&.02\&.02\-x_*\&.deb\fP: debian package containing the libraries; .IP o \fIlibbobcat1\-dev_6\&.02\&.02\-x_*\&.deb\fP: debian package containing the libraries, headers and manual pages; .PP .SH "BOBCAT" Bobcat is an acronym of `Brokken\(cq\&s Own Base Classes And Templates\(cq\&\&. .PP .SH "COPYRIGHT" This is free software, distributed under the terms of the GNU General Public License (GPL)\&. .PP .SH "AUTHOR" Frank B\&. Brokken (\fBf\&.b\&.brokken@rug\&.nl\fP)\&. .PP