I am trying to implement system-signal handling into my code, which looks basically like this
struct Foo{
bool should_stop_;
std::thread* _internal_thread_;
Foo(): should_stop_(false) {};
// this is what the thread does at heard
void operator()() {
while(!should_stop_) {
std::cout << "sleeping" <<endl;
sleep(1);
}
};
//start the execution in an thread; i.e. not blocking
void run() {
_internal_thread_ = new std::thread(std::ref(*this));
};
//end the thread execution, and join the thread
void stop() {
should_stop_ = true;
_internal_thread_->join();
}
};
int main () {
auto foo_ptr = new Foo();
foo_ptr->run(); // non blocking
try{
sleep(5); // while(True) {do_other_things();}
} catch(...) {
std::cout << "unexpected.\n";
}
foo_ptr->stop();
};
this works quite well for me [while the program could be in principle running indefinitely, I cut I short with five cycles, to demonstrate the call to stop()
].
This does, however, not handle system-signals like SIGINT, SIGTERM etc. Having read the cpp-reference on signal()
I wanted to wrap my Foo
object into a functor and let it Handle the signal, aka interrupt the execution of foo
by calling to stop
as soon as the signal is received. I tried this:
struct myHandler {
Foo* foo_ptr_;
myHandler(Foo* foo_ptr) : foo_ptr_(foo_ptr) {};
void operator()(int signum) {
call(signum);
};
void call(int signum) {
std::cout << "Interrupt signal (" << signum << ") received.\n";
foo_ptr_->stop();
exit(signum);
};
};
int main() {
auto foo_ptr = new Foo();
auto my_sighandler = myHandler(foo_ptr);
signal(SIGINT, (void (*)(int))&my_sighandler); // -> should go through MyHandler::operator()
signal(SIGTERM, (void (*)(int))&my_sighandler::call); // -> should go through MyHandler::call
foo_ptr->run();
};
This, does not work for either of the two registered signals (SIGINT or SIGTERM). I can not find a viable solution to resolve this. On my quick search I was able to find some solutions which go through the length of registering global volatile variables for which their classes [what is here Foo] listen to. However this would seriously break my class design as well as violate the program structure, which should be bottom-to-top.
Can anybody provide some hints here?