Re: Merge of nickrob-async-20060513 to mainline?

Daniel Jacobowitz
2006-10-06T01:26:38Z

On Fri, Oct 06, 2006 at 01:50:34PM +1300, Nick Roberts wrote:
> > Ideally you'd be able to reuse the signal handler logic (see the calls
> > to sigprocmask and sigsuspend) and thus not have a millisecond latency
> > and excessive spinning. That's actually a pretty important feature,
> > because context switching to gdb every millisecond or so is going to
> > really hurt performance of the debuggee.
>
> From the event loop, GDB needs to detect that a process/thread has changed
> status and check for user input. If it does the first with sigsuspend, the
> only way I can see how it can do the second is by using threads. This would
> almost take us back to where we started.

Correct. You can't do it quite the same way. The key is not
sigsuspend itself, but the use of signals, and blocking them when you
don't need them.

The easy way to combine the two would be with pselect, but it's
inadequately portable. Here's a bit from the man page of that function
on my system, which explains a useful alternative:

Since version 2.1, glibc has provided an emulation of pselect()
that is implemented using sig- procmask(2) and select(). This
implementation remains vulnerable to the very race condition
that pselect() was designed to prevent. On systems that lack
pselect() reliable (and more portable) signal trapping can be
achieved using the self-pipe trick (where a signal handler
writes a byte to a pipe whose other end is monitored by select()
in the main program.)

So when you want to wait, you make sure such a signal handler is
installed for SIGCHLD, unblock SIGCHLD, and call select on a set of fds
that includes the one written to by the signal handler. If you get a
byte on that fd, you know there's a child ready to be waited for. When
you're done waiting, you re-block the signal. It's possible to get
spurious wakeups this way (for instance if a signal is received between
the return of select and the re-blocking), but with a little care
everything works out OK.

This is actually pretty similar to the way you do it with threads.

Does that make sense?

--
Daniel Jacobowitz
CodeSourcery