Date: Fri, 11 Jun 2004 16:26:50 +0800 From: David Xu <davidxu@freebsd.org> To: Daniel Eischen <eischen@vigrid.com> Cc: freebsd-threads@freebsd.org Subject: Re: signal handler priority issue Message-ID: <40C96CCA.9060704@freebsd.org> In-Reply-To: <Pine.GSO.4.10.10406110358250.12394-100000@pcnet5.pcnet.com> References: <Pine.GSO.4.10.10406110358250.12394-100000@pcnet5.pcnet.com>
next in thread | previous in thread | raw e-mail | index | archive | help
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.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?40C96CCA.9060704>