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