signal handler priority issue
Sean McNeil
sean at mcneil.com
Fri Jun 11 05:08:08 GMT 2004
On Thu, 2004-06-10 at 21:55, Daniel Eischen wrote:
> On Thu, 10 Jun 2004, Sean McNeil wrote:
>
> > On Thu, 2004-06-10 at 21:19, Daniel Eischen wrote:
> > >
> > > The critical section should prevent the signal handler
> > > from being invoked. Put some printf()'s in after the
> > > sem_post() and in the signal handler(). The signal
> > > handler printf()'s should always occur after the sem_post().
> > > Plus, you shouldn't be getting that signal since it
> > > should be masked until sigsuspend() is called.
> > >
> > > Is it getting past sem_post() and into sigsuspend() or not?
> > > If it is getting past sem_post(), then I don't think that is
> > > your problem.
> >
> > Here is what I see:
> >
> > master thread calls pthread_kill with SIGUSR1 and waits on semaphore.
> > other thread gets signal and calls sem_post. It yields the scheduler.
>
> This is fine as long as this thread doesn't get a signal
> until after sem_post(). Being signal safe doesn't mean
> that other threads can't be scheduled.
>
> > master thread gets semaphore and continues on it's way.
> > master thread calls pthread_kill with SIGUSR2 and keeps going.
>
> It can't keep going if there is a possibility that it can
> send the same thread another SIGUSR2.
I don't follow. Sorry.
> > Later, master calls pthread_kill with SIGUSR1 and waits on semaphore.
> > other thread gets signal and calls sem_post. It yields the scheduler.
>
> Why is it getting SIGUSR1? It is waiting for SIGUSR2, not
> SIGUSR1. You need to mask SIGUSR1 before the sem_post() and
> until after the sigsuspend() on SIGUSR2.
The problem is that it never gets to the sigsuspend. It yields right
after the sem_post and gets interrupted again by another SIGUSR1. I see
this because it never prints a message that is following the sigsuspend
and the sig hander count is incrementing showing me that it is called 2
times before getting to the sigsuspend.
> > master thread gets semaphore and continues on it's way.
> > master thread calls pthread_kill with SIGUSR2 and keeps going.
> > Finally, master scheduler is done and yields the scheduler.
> > other thread gets to run now and then it goes into sigsuspend waiting
> > for SIGUSR2, but it never gets it because it wasn't masked until
> > sigsuspend is called.
> > threads are all hung.
> >
> > The problem is that sem_post should not cause a reschedule of threads
> > when inside a signal handler and it does.
>
> Nope, that is allowable. Please don't confuse signal safe with
> "will not yield the CPU". Also, on SMP, there are not guarantees
> regardless!
OK. Then I suppose what is happening is that it is losing the SIGUSR2.
But I don't really know why a signal handler would not be pushed to be
high priority. Doesn't it seem logical that it should keep the
scheduler past a sem_post? Perhaps that is the issue? Should a thread
inside a signal handler have highest priority?
> I'm not saying that there isn't a bug somewhere, but don't go
> reading more into what the requirements of sem_post() are.
I guess I read more into the comment than I should:
/*
* sem_post() is required to be safe to call from within
* signal handlers. Thus, we must enter a critical region.
*/
I took this to mean (plus the critical enter/leave surrounding it) that
sem_post should not yield the scheduler when inside a signal handler.
More information about the freebsd-threads
mailing list