chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.88k stars 1.21k forks source link

A new signal_set API to handle SA_SIGINFO (sigqueue & sigaction) #417

Open skannan89 opened 5 years ago

skannan89 commented 5 years ago

Sigqueue can be used to send a signal and an accompanying data to a process. Example:

int main(int argc, char *argv[])
{
        union sigval value;
        int pid = atoi(argv[1]); // process id
​
        value.sival_int = 12345; // data
        if(sigqueue(pid, SIGUSR1, value) == 0) {
                printf("signal sent successfully!!\n");
        } else {
                perror("SIGSENT-ERROR:");
        }
        return 0;
}

The process can use sigaction to get the data sent using sigqueue. It needs to set SA_SIGINFO in sa_flags. Sample code:

void sighand(int signo, siginfo_t *info, void *extra)
{
       int int_val = info->si_value.sival_int;
       printf("Signal: %d, value: %d\n", signo, int_val);
}
int main()
{
        struct sigaction action;
        action.sa_flags = SA_SIGINFO;
        action.sa_sigaction = &sighand;
        if (sigaction(SIGUSR1, &action, NULL) == -1) {
                perror("sigusr: sigaction");
                return 0;
        }
        printf("Signal handler installed, waiting for signal\n");
        while(1) {sleep(2);}
        return 0;
}

signal_set seems to be using sigaction but doesn't set SA_SIGINFO. It will be very useful to have a new API that supports this.

lsem commented 1 year ago

@chriskohlhoff do you think this feature has a place in Asio? I would also like to use it in my service, but Asio sets its handler exclusively. I'm considering making my own changes into signal_set but would rather liked to have it from upstream.

vinipsmaker commented 1 year ago
value.sival_int = 12345; // data
if(sigqueue(pid, SIGUSR1, value) == 0) {

Signals can coalesce anyway (meaning the above code sample would have no effect), so what is this proposed API guaranteeing/offering exactly? One can use other IPC mechanisms if data needs to be actually transferred around (e.g. UNIX sockets).

Second, Boost.Asio needs to offer an API that integrates with its concurrency model (meaning completion handlers full of associated properties), and that is not appropriate to handle every signal type anyway (i.e. for some signals such as SIGBUS, if you really mean to handle it, you need to register your own handler anyway and deal with all restrictions that apply to a signal handler).

I certainly would be one of the users for SA_SIGINFO, but there are serious unresolved issues for which I don't know of a solution. Unless someone comes up with a creative way to expose a safe and useful API for it, I think it's best to just rely on the raw sigaction() API. Furthermore, very few signals exist (likely 32 at most on every system), so you can add a specific API for every signal that requires SA_SIGINFO instead of developing a general API that so far seems impossible to reliably design.

My 2 cents.