Wojciech Reszelewski
Wojciech Reszelewski

Reputation: 2716

pthread_sigmask won't work in signal handler

I've got such a signal handler:

void my_signal_handler(int signo )
{
    sigset_t sa_mask;
    sigsetemptyset(&sa_mask);
    sigaddset(&sa_mask, SIGINT);
    int res = pthread_sigmask(SIG_BLOCK, &sa_mask, NULL);
    int i;
    for(i=0;i<NUM_OF_THREADS;i++) {
        pthread_kill(my_threads[i], SIGINT);
    }
}

I use it to handle SIGINT. It has to turn off other threads when it receives a SIGINT. I'm trying to block SIGINT in the thread not to cause signal storm. Unfortunately signals don't stop to send. What I'm doing wrong?

Upvotes: 0

Views: 636

Answers (1)

caf
caf

Reputation: 239151

The signal mask is per-thread - if your other threads don't already have SIGINT blocked, they'll also enter this handler when you signal them in the loop, and start sending signals as well.

Additionally, thread-directed signals that arrive while the thread has the signal blocked are not lost - they are delivered when the thread unblocks the signal. So what happens here is that your thread sends itself a SIGINT, which is queued until the signal handler returns. At that point, the signal is unblocked, which allows the signal to be delivered, and the handler is re-entered.

You could call sigaction() as the first action in your signal handler to change the signal handler for SIGINT, which will affect all threads.

Upvotes: 1

Related Questions