I am trying to do interruption handling with a member function from a class.
The code is
signal(SIGABRT, socketServer.signalHandler);
where the definition of signalHandler
is
public:
void SocketServer::signalHandler(int sig)
{
logger.info("Receive SIG"+to_string(sig)+" Stopping server now...");
stop();
}
When I compile the code, I got an error says
main.cpp:32:32: error: reference to non-static member function must be called
signal(SIGABRT, socketServer.signalHandler);
I am trying to capture SIGABRT
using this signalHandler
function and to clean up and stop the socketServer
instance. I guess I can use global variable and a global function to do the job, but any thoughts about doing this with a member function?
No, you can not do this.
The reason is that all member functions have an "implied/hidden" this
pointer argument. If we "flattened" out your handler definition to produce the C equivalent, it would look like:
void SocketServer::signalHandler(SocketServer *this,int sig);
The signal
function [in C] knows nothing of this [pun intended]. If it compiled, the handler would be called with sig
going into the this
argument and not the sig
argument.
So, you really must do:
SocketServer my_global_server;
void
my_handler(int sig)
{
my_global_server.signalHandler(sig);
}
int
main(void)
{
signal(SIGABRT,my_handler);
return 0;
}
Actually, the above is quite dangerous because my_global_server
may be in an indeterminate state when the signal handler is called, causing UB. Also, when in a signal handler, there are a limited number of things you are permitted to do. For example, no heap manipulations are permitted.
Here is a better way to implement this:
volatile int signal_flag;
SocketServer my_global_server;
void
my_handler(int sig)
{
signal_flag = sig;
}
int
main(void)
{
signal(SIGABRT,my_handler);
while (! signal_flag) {
...
}
my_global_server.signalHandler(signal_flag);
return 0;
}