Question

I have the following code snippet:

#include <signal.h>
#include <boost/asio.hpp>
#include <iostream>

void startAsyncWaitForSignal(boost::asio::io_service& ioService)
{
    boost::asio::signal_set signals{ioService};
    signals.add(SIGTERM);
    signals.async_wait(
        [&ioService](boost::system::error_code errorCode, int signalNumber)
        {
            std::cerr << errorCode.message() << std::endl;
            if (!errorCode) {
                std::cerr << "received signal " <<  signalNumber << std::endl;
                startAsyncWaitForSignal(ioService);
            }
        }
    );
}

int main() {
    boost::asio::io_service ioService;
    startAsyncWaitForSignal(ioService);
    ioService.run();
}

I'd expect this program to wait, until the first SIGTERM is arrived, then wait to the next, then again to the next, ...

However the program is immediately terminates with the following output:

Operation canceled

What is the reason of this immediate operation cancel? I tried to make an io_service::work object, but that just changed the fact that ioService.run() was not finished, but the signal_set was still canceled immediately.

I am using boost 1.54. There is a bug fix related to asio/signals in 1.55, but that looks like a different issue.

Was it helpful?

Solution

When leaving startAsyncWaitForSignal() the local signal_set variable gets destroyed and the async_wait() call gets cancelled. The signal_set needs to live just a little longer. Move it out of startAsyncWaitForSignal() and pass it as a parameter, for example:

#include <signal.h>
#include <boost/asio.hpp>
#include <iostream>

void startAsyncWaitForSignal(boost::asio::io_service& ioService, boost::asio::signal_set& signals)
{
    signals.async_wait(
        [&ioService, &signals](boost::system::error_code errorCode, int signalNumber)
        {
            std::cerr << errorCode.message() << std::endl;
            if (!errorCode) {
                std::cerr << "received signal " <<  signalNumber << std::endl;
                startAsyncWaitForSignal(ioService, signals);
            }
        }
    );
}

int main() {
    boost::asio::io_service ioService;
    boost::asio::signal_set signals{ioService};
    signals.add(SIGTERM);
    startAsyncWaitForSignal(ioService, signals);
    ioService.run();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top