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