Re: [gtk-list] Re: callback synchronisation



>> However, Tim's code doesn't directly receive the POSIX signal;
>> instead, it appears to rely on the signal interrupting the glib main
>> loop (see below for a comment on this), at which point the g_source_()
>> functions get executed and the callback you set up runs. This isn't
>
>Meaning it interrupts any other callback which might have been running?

Yes and no. In the simple case, we have:

	  in select/poll() of glib main loop
	->POSIX signal
	->POSIX signal handler (via sigaction/signal/etc.) (if any)
	->return from signal handler
	->return from select/poll
	->check input sources
	->discovered "signal source" with "input ready"
	->foreach callback for "signal source/input ready"
	    call each signal callback
	->continue with glib_main_loop

so, your callbacks should be called serially.

If, on the other hand, another SIGPOLL arises to be delivered while
the first one is being "handled", you could end up with this:

	  in select/poll() of glib main loop
	->POSIX signal
	->POSIX signal handler (via sigaction/signal/etc.)
	  calls g_signal_notify(SIGPOLL)
	->return from signal handler
	->return from select/poll
	->check input sources
	->discover "signal source" with "input ready"
	->foreach callback for "signal source/input ready"
	    call each signal callback
	    ->POSIX signal
	    ->POSIX signal handler (via sigaction/signal/etc.)
	      calls g_signal_notify(SIGPOLL)
	    ->return from signal handler
	->continue with glib_main_loop

now, if all that the POSIX signal handler only does g_signal_notify(),
then the "reentrant" signal doesn't cause any problems, except that
its action *may* not be noted until the next return from select/poll
in the main loop, because glib doesn't *recheck* the input sources
after all the callbacks have been executed for further events. I think.

either way, your callbacks are executed serially.

>solve my problem. I'll get a burst of SIGPOLLs for one logical event, so
>they might easily interrupt each other's callback. Actually, I think some
>bugs might be explained that way, but I'm not sure right now.

I dont think so, as shown above. If all you do is to call
g_signal_notify() from the handler, you will nothing to alter the
order or relative call stack layout of the callbacks' execution.

HOWEVER: on some systems (Linux in particular) many system calls do
not restart after a signal, at least not by default. You can use
sigaction(2) to alter this (on Linux, and probably Solaris too). If
this behaviour occurs with Solaris, then if your callback was in the
middle of just such a system call, then the "reentrant" (its not
really) POSIX signal will cause the syscall to return prematurely,
thus making the existence of the signal visible and changing the
behaviour of the callback.

On Linux, this can be a real pain for read/write with Pthreads, for
example. Pthreads on Linux uses two RT POSIX signals, and they get
delivered to threads that might be in the middle of a read/write
call. The call returns early, apparently having failed in some way,
when it was really just interrupted (you can discover this by checking
errno). I don't know if this is a problem in your case.

>I'm using sigaction(2), which blocks SIGPOLL while I'm in the handler.
>I don't know what glib uses for SIGALRM. Does it use SIGALRM at all
>for g_timeout_add(), or it's handled by select/poll timeout? In any

the latter. it does not use SIGALRM.

>> I need to do this as well sometimes, so I use <asm/atomic.h> on Linux
>> and equivalents on other systems. Within critical sections, I do this:
>
>Not available on Solaris in userland. :-(

actually, they are, but they are not wrapped nicely. all architectures
have atomic data types for increment and decrements. all sane
architectures anyway, and the SPARC/x86 that Solaris runs on are among
the reasonably sane.

--p



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