Re: Handling Unix signals in a GTK+ application

That's well over 1548533 executions (I forgot to print the
counter after the 10th second) of the idle callback, or
172059 calls to the idler function per second. Personally,
I'd call that a busy wait.
Its not a busy wait; your idle handler has never returned FALSE;
so whenever your application is idle (i.e. all the time) then
the idle handler will run; whether it be the gmain.c code or the
code in poll( /* timeout == 0 */ ) that decided to return directly.

I wrote that test, in response to the suggestion that the Unix signal handler set a flag, and an idle handler 
watches that flag to detect whether the signal has occured.  My idle handler incrementing a variable, is 
symbolic of checking a flag that hasn't been tripped.

Because the main loop has an idle handler, it sets a wait time on the poll() call to zero, causing it to 
return immediately.  Effectively generating a busy-wait, via the main loop.

If the idle handler returns FALSE, the idle handler will be destroyed.  If a signal then comes in, the flag 
will be set, but never checked since that's the idle handlers job.

If you call g_idle_add() from another thread or from a signal;
the g_idle_add() will either:
o Just queue an idle handler if the loop is busy
o Queue an idle handler and wakeup the loop if the loop is sleeping

The problem, as I recall, was a statement that no GTK/Glib/Gwhatever functions are safe to call from within a 
signal handler; they're not even thread-safe, so I doubt they'll be signal-safe; even non-Gblah programs 
suffer from this problem, hence the number of re-enterant functions present in the standard libraries.  What 
would happen if the signal came in while the program was in the wrong part of using g_idle_add() already?

Which BTW; is done by writing an arbitrary charachter into a
pipe() that will force the mainloop out of poll() if its sleeping.

Which is the "pipe to GIO" method.  That isn't a busy wait, because there's no constant idle handler.  The 
bit I was responding to was one of the messages giving the idle loop alternative to creating a pipe entirely 
within the application (and all the blocking issues that go along with it).  Personally, I think the pipe is 
a fairly elegant solution, though I do wish there was a more direct method that didn't go through a tonne of 
kernel code.

As I understand it, a Unix signal will interrupt a running poll() (and in fact, most long-running kernal 
functions), causing it to return early (returns the EAGAIN error, or something).  If that is indeed the case, 
the main loop should complete its iteration, going more or less straight back into another poll().  Which 
opens up another possible solution; some kind of hook function that gets called every time the main loop 
iterates.  Would creating a new event source should offer the opportunity for such a purpose?  The Unix 
signal handler could stash the signal number somewhere, and the event source would check each iteration, and 
cause the relevant handler to be called.


Join Excite! -
The most personalized portal on the Web!

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]