Re: External event loop for glib?




Per Hedbor <per@idonex.se> writes:

> > As Danny has pointed out it would be nice to provide functions that give
> > enough information to start the run phase of gtk+ at appropriate times
> > (descriptors and timers). This probably isn't particulary difficult and
> > would solve some problems - at least for me.
> 
> This would be very welcome. My current solution is to call
> g_main_iteration(0) once every 1/50:th second. It doesn't use any
> noticeable amount of CPU (less than 0.001% on a dual PII350), but it's
> rather UGLY, really.
> 
> A simple 
> int msecs = g_next_timeout();
> 
> or 
> 
> struct timeval next_timeout = g_next_timeout() would be rather
> welcome. :-)
> 
> Actually, there is also the problem with idle timers (If there are any 
> in the GTK internals, I have no idea).

All over the place. Of course, this works fine if g_next_timeout()
just returns 0 when there are idle handlers waiting.

You must also account for file descriptors, though. Currently,
the only one you need to worry about is ConnectionNumber(GDK_DISPLAY()),
but that is is not guaranteed to stay that way.

So, basically, the interface you are asking for is something like:

 g_main_prepare (gint *timeout, GPollFD **sources, gint *nsources);
 g_main_dispatch (gint timeout, GPollFD *sources, gint nsources);

Or in other words, breaking g_main_iterate() (glib/gmain.c)
into two pieces.

There are a couple of reasons why that is not currently implemented:

 - Somebody has to be responsible for the main loop. The 
   tradition in Unix (Xt, etc.) is that the toolkit handles
   the main loop. So I concentrated on making GTK's main
   loop as good as possible, and making it very easy to
   integrate other things into it, rather than making it
   easy to embed into other main loops.

 - GTK+'s main loop has a lot of functionality that you won't
   find in just any main loop. In particular it is pretty
   much 100% reentrant - you can make a recursive call
   to g_main_run() anywhere.

There is one way that you can sort of achieve the effect that
you are looking for with the current interfaces, assumming
that you can run small pieces of your event loop -

 g_main_set_poll_func()

Your poll function can:

 - set up appropriate watches in your main loop
 - run your main loop until one of the file descriptiors
   or timeouts expires
 - return

This is going to be somewhat inefficient. (As would
g_main_prepare()/g_main_dispatch()). 

I'd look seriously into seeing if you can use the
GLib main loop as a backend to your loop. I know
of very litle functionality that the GLib main
loop doesn't provide already, and the GSource API
means that it is easy to supply such functionality
if it missing.

Basically, if your main loop provides the functionality
that you wanted from the GLib main loop, than it
will be trivial to integrate it into the GLib
main loop. And (IMO) the result is going to be
better than doing it the other way.

                                        Owen

[ Three cheers for main-loop egotism! ]





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