Re: External event loop for glib?

On 03/28/99, Owen Taylor said:

> - 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.

Tcl's core event provides the same functionality (including reenterancy),
and its great at it. However, it provides one thing that the model you
speak of is missing.. it provides a way for you to write a new event loop
and still work with Tcl.

For example, what if you are using someone else's event loop, that you don't
have source for, and that the company refuses to budge on. Examples of
these libs that I've had to deal with include are mentioned below.

No matter how good you make gtk's loop, gtk will always be the looser in
the case where you must use functionality of other broken products. They
are wrong, but gtk will suffer.


Tibco has a product named rendezvous. It is a very popular
publish-subscribe middle-ware. Its use is especially high on Wall
Street. The way their C event loop works is pretty simple. If you are
interested in receiving information on a certain subject (a subject is
much like a multicast address), you register your interest on the
subject and give them a function. Your function gets called when a
packet arrives. Since they provide guaranteed message delivery, you
can just send data to a subject whenever you want, you don't have
worry about checking for writablilty. For rendezvous to do its thing,
it needs to have control of the main loop. Since they have control of
the main loop, they do provide hooks for you to ask for timer events
and for readability/writability events on normal file descriptors.

Now they do provide another interface that doesn't require them have
control of the even loop. But when using this interface, most of the
functionality is gone. You get blocking reads, and data can be dropped
from other subjects while you are waiting for one. Basically, it sucks
and can't be used in a real application, leaving you with two choices:
(1) don't use rendevouz, (2) use their even loop.


Sybase Open Server, same situation as above, no control, no option to give
up the control either. They say you either give them control, or you run


Smart sockets, from Talarian, a similar middle ware we are switching
to, does have a way to get the file descriptor from a connection. I
have not used them at all, though. They may have timer event, and
not have an interface to query for the nearest-pending timer. I
ran into this type of problem with Xt. I needed the event loop for
various reasons. I would just listen on the X socket for incoming
data, and then let Xt do its thing. The problem was that there was
no interface to get timer events, so Xt cursors would not blink at a
steady speed (only when there were other X events). This sucked. The
ideal interface for a product would be something like:

int GetNextTimeout(struct timeval *);   /* return 1 if there is one, 0
                                         * otherwise */

int FillFdSets(int *max_p1, fd_set *read,
               fd_set *write, fd_set *except);
                                        /* add the appropriate
                                         * descriptors to the                                                                                                                                                              
                                         * approprate sets, and fill                                                                                                                                                       
                                         * max_p1 with the correct                                                                                                                                                         
                                         * value (assuming that select                                                                                                                                                     
                                         * were to be called).                                                                                                                                                             

void RunPendingTimers(const timeval *time_of_day);

void RunSelectTimers(int max_p1, const fd_set *read,
                     const fd_set *write, const fd_set *except);
                                        /* pretend like those are the
                                         * return values from select,
                                         * and deal with them how you
                                         * like.

An even better interface would get rid of the use of fd_sets and just
use arrays of integers. But anyway, thats just a general sketch.

Danny Dulai                                           Feet. Pumice. Lotion.                  

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