Signaler - interrupt handling

The Signaler class enables the API programmer to register functions to be called when the client application receives an interrupt signal. The Signaler class maintains a list of registered functions and calls each one in turn. See Signaler methods.

By default, after all of the registered functions have been executed, the process exits, returning -1 to the operating system.

Important

If using the P4API in an application which is NOT a console app, you must change the default memory management and exit() behavior during the initialization of the class.

By default, when the P4API is initialized, it creates the Signal() object and provides a default handler. The signaler tracks memory allocations made by FileSys() objects and frees those memory allocations on termination. This code is intended for console applications to free allocated memory when an interrupt is processed before exit().

However, if the P4API is used in an environment where the application uses its own memory manager, a crash might occur on exit because the signal handler is trying to free memory from the wrong pool.

To avoid this problem, disable Signaler() after the initialization of P4Libraries:

void initializeP4API()
{
    Error e;
    P4Libraries::Initialize(P4LIBRARIES_INIT_ALL, &e);
    signal(SIGINT, SIG_DFL); // unset the default set by global signaler in C++ so it does not exit 
    signaler.Disable(); // disable the global signaler memory tracking at runtime
}

Otherwise a crash might occur with a call stack similar to this:

#0 Signaler::DeleteOnIntr (this=0x990330 <signaler>, ptr=0x1ba87e0) at ../p4/sys/signaler.cc:228
#1 0x00000000004b86e3 in Rpc::~Rpc (this=0x1ba87e0, __in_chrg=<optimized out>) at ../p4/rpc/rpc.cc:312
#2 0x00000000004d72b7 in Client::~Client (this=0x1ba87e0, __in_chrg=<optimized out>) at ../p4/support/strbuf.h:369
#3 0x00000000004a7f1c in ClientApi::~ClientApi (this=0x1b9dac0, __in_chrg=<optimized out>) at ../p4/client/clientapi.cc:21

See P4Libraries methods.