signal handler priority issue
David Xu
davidxu at freebsd.org
Fri Jun 11 08:24:35 GMT 2004
This proves thread programming is so complicate, it is no longer
streamline. ;-)
David Xu
Daniel Eischen wrote:
> On Fri, 11 Jun 2004, Sean McNeil wrote:
>
>
>>OK, I think I have it figured out....
>>
>>The problem is, that when the first signal handler, SIGUSR1, is run
>
> the
>
>>SIGUSR2 signal is blocked. I think this is what Daniel was trying to
>
> ^ not
>
>
>>say, or I didn't provide enough information for him to catch it. So,
>>I've fixed the sigaction call to unblock SIGUSR2 while SIGUSR1 is
>
> going
> ^^^^^^^ block
>
>
>>and rearranged a few things:
>>
>> me->stop_info.signal = 0;
>> me->stop_info.last_stop_count = my_stop_count;
>>
>> /* Tell the thread that wants to stop the world that this */
>> /* thread has been stopped. Note that sem_post() is */
>> /* the only async-signal-safe primitive in LinuxThreads. */
>> sem_post(&GC_suspend_ack_sem);
>>
>>#if DEBUG_THREADS
>> GC_printf2("Waiting for restart #%d of 0x%lx\n", my_stop_count,
>
> my_thread);
>
>>#endif
>>
>> /* Wait until that thread tells us to restart by sending */
>> /* this thread a SIG_THR_RESTART signal. */
>> if (sigfillset(&mask) != 0) ABORT("sigfillset() failed");
>> if (sigdelset(&mask, SIG_THR_RESTART) != 0) ABORT("sigdelset()
>
> failed");
>
>># ifdef NO_SIGNALS
>> if (sigdelset(&mask, SIGINT) != 0) ABORT("sigdelset() failed");
>> if (sigdelset(&mask, SIGQUIT) != 0) ABORT("sigdelset() failed");
>> if (sigdelset(&mask, SIGTERM) != 0) ABORT("sigdelset() failed");
>> if (sigdelset(&mask, SIGABRT) != 0) ABORT("sigdelset() failed");
>># endif
>>
>> while (me->stop_info.signal != SIG_THR_RESTART) {
>> sigsuspend(&mask); /* Wait for signal */
>> }
>>
>>There might still be a bug that I'm just hiding. I think that the
>>problem is while in the handler for SIGUSR1 and someone calls
>>pthread_kill with SIGUSR2, the signal isn't marked as pending because
>
> it
>
>>is masked off. It appears to rely on the following behavior:
>
> ^^^^^^^^^^
>
> No, the problem is because SIGUSR2 is _not_ blocked. I read
> "masked off" as "blocked" (the desired behavior). If the
> signal handler runs, that means that the signal is not blocked.
> Your goal is to prevent the signal handler (for SIGUSR2) from
> running until sigsuspend() is hit. Once sigsuspend() is hit,
> then SIGUSR2 becomes unblocked, the signal handler is run,
> and sigsuspend() returns.
More information about the freebsd-threads
mailing list