is it possible to set a promise in a signal handler?
Asked Answered
R

1

2

I was looking for a way to stop a thread that perform a task every 2 seconds. I decided to try to use a std::promise/future so that the thread can exit immediately when the promise is set.

#include <future>
#include <iostream>
#include <chrono>
#include <csignal>

std::promise<void> stop;

int main() {

    std::signal(SIGINT, [] (int)  { stop.set_value(); } );

    auto future = stop.get_future();

    while (future.wait_for(std::chrono::seconds(1)) != std::future_status::ready) {
            std::cout << "I'm still there" << std::endl;
    }
}

Actually this does not work and crashes that way:

$ ./a.out I'm still there ^Cterminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1 Abandon (core dumped)

Ok, One should take care of what he does in handler context, but I must say I was not expecting this crash; and I don't really understand it... Do you have any idea?

Retrad answered 26/10, 2018 at 19:38 Comment(1)
I'd be expecting a crash? Did you examine the insane restrictions signal handling has: en.cppreference.com/w/cpp/utility/program/signalAmorete
A
5

I believe what you have here is undefined behaviour as a result of calling a standard library function (not in list of signal safe functions) in the signal handler.

The limitations on the signal handler function (that is user-defined) are extensive and are documented here.

Another thing to watch out for is if the signal handler refers to any object with static or thread-local(since C++11) storage duration that is not std::atomic(since C++11) or volatile std::sig_atomic_t.

And as @BasileStarynkevitch pointed out, if you are on Linux, ensure that only async-signal-safe functions are called from the signal handler.

Anciently answered 27/10, 2018 at 7:27 Comment(3)
On Linux, signal-safety(7) is also very relevantCatlaina
@BasileStarynkevitch: Updated the answer with your comment.Anciently
I was expecting it, but the answer seems to be definitely no :)Retrad

© 2022 - 2024 — McMap. All rights reserved.