Date: Fri, 11 Jun 2004 00:45:28 -0700 From: Sean McNeil <sean@mcneil.com> To: Daniel Eischen <eischen@vigrid.com> Cc: freebsd-threads@freebsd.org Subject: Re: signal handler priority issue Message-ID: <1086939928.10026.26.camel@server.mcneil.com> In-Reply-To: <Pine.GSO.4.10.10406110242160.26412-100000@pcnet5.pcnet.com> References: <Pine.GSO.4.10.10406110242160.26412-100000@pcnet5.pcnet.com>
next in thread | previous in thread | raw e-mail | index | archive | help
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 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 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: thread 1 calls pthread_kill for SIGUSR1. thread 2 enters SIGUSR1 handler and SIGUSR2 is masked. thread 1 calls pthread_kill for SIGUSR2. signal is set pending as it is currently masked off. thread 2 calls sigsuspend thus unblocking SIGUSR2. Signal handler for SIGUSR2 is called and then sigsuspend in SIGUSR1 handler returns. Is this correct behavior? Should a pthread_kill of a blocked signal pend or should it be dropped? Right now, I've worked around this.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1086939928.10026.26.camel>