Re: Moving main loop to GLib.



On Wed, 18 Nov 1998, Owen Taylor wrote:

> Moving the main loop to GLIB is desirable, because it enables
> non-GUI applications to take advantage of a good event
> loop and of event driven programming. In particular, it
> would be desirable to use the main loop for ORBit.
> 
> The main reason why this operation is not simply copying
> code is that the X events from GDK need to be integrated
> into the event loop. To facilitate this, the proposed
> GLIB interface is meant to be extensible. The core
> code polls and dispatches events from various "event sources".

Agreed, all around. I've been writing some server code recently, among
other stuff, and I would very much appreciate a generalized and portable
event-loop API.

However, I've also played around at integrating dissimilar event-handling
code (GNU readline & Tk, for example), and realize the difficulties
involved. 

> [...API...]

This looks sufficient for basic functionality, but programmers might want
to request specific poll() events. Also, the notion of prioritized events
might be needed. 

> [...GSource API...]

But be careful not to override the local poll() mechanism (if it exists),
as poll() is designed to be extensible, and the programmer may want to use
the extended capabilities, without delving to the GSource level.

> The algorithm is, for each run of g_main_iteration(), we:
> 
> 1) While the list of currently pending sources is non-empty
>    call (*restart) on the head, and (*dispatch) on the rest,
>    removing sources from the list after each returns
> 
> 2) Call (*prepare) for each source.
> 
> 3) Poll with the union of the pollfd's from each source,
>    and the minimum of all the timeouts from all sources.
>    (timeout < 0 == infinite)

OK, I see what you are doing here. The problem is, this assumes that
poll() (or emulation) can be used to poll all GSource's simultaneously,
which is definitely not always the case under other operating systems (and
I'm sure cases for Unix could be designed, looking at directory contents,
for example.) Indeed, the idea that a GSource always has a set of
poll_fd's (which contain file descriptors in turn) isn't appropriate.

Tcl/Tk goes some way towards this end (necessary, considing its support
for Win'95), and makes a useful model, to some degree.

To try and summarize what is needed: we need something that I'll call
"Providers" (which I confused your Sources for) which are like poll() and
select(): given a set of opaque "tags" of a certain type, they will return
the first (and/or all, depending on various conditions) tags that match. 
poll() and select() operate exactly in this manner, with
"tags" of the file-descriptor and timeout type.

The problem, of course, is how to check with multiple Providers without
going into unneccesary spinloops. Unfortunately, I'm not aware of any
perfect solution for this, but consider some of the constraints we may
have: Providers that don't support timeouts at all, either waiting an
infinite period, or only supporting a "peek" with immediate timeout. Or
only timeouts of a limited nature might be available (integral seconds).

Even more confusing is interacting providers: one provider might only be
able to say whether the event is ready now or not (just a peek), but the
OS is capable of interrupting _other_ provider timeouts when the event
becomes ready. 

As I said, Tcl/Tk goes some way towards supporting this, but I'm not sure
how general-purpose the code is. (It definitely has the concepts of
Providers, Sources, etc., but I'm not sure whether the logic is up to
dealing with arbitrary types of Providers with arbitrary limits.)

In case this all seems a bit moot, I should point out that Windows has an
extraordinary number of different event sources going on at one time, and
that it wouldn't be at all difficult to need to monitor several different
sources. (Windows '95 is worse then NT, at 95's sockets are not usable as
file handles, and thus cannot be be used by the equivalent of select().) 

COM ports can be handled differently from files (and need to be, in some
cases), which can be handled differently from sockets (and need to be,
under '95), which (as I recall) are handled differently from directory
events, which are all handled _completely_ differently from process,
mutex, and other synchronization objects which are in another layer
altogether.

(You thought UNIX was bad? Windows is much much worse. Yes, it can handle
some event sources, like directory changes and task-exit notification,
that UNIX cannot, but it has all been supported by cramming in an
incredible variety of event and "descriptor" types.)

Personally, I would much prefer for GLib to have main-loop functionality
that is at least equal (preferably superior) to that of Tcl/Tk (and
everything else we can find). At the very least, each GSource should be
inserted into a GProvider (or whatever you want to call it), with one
GProvider being standard under UNIX. For now, we can probably skip
worrying about user-installed GProviders, and rely on the GLib porter to
figure out what specific GProvider's are necessary for an OS, and just how
to mediate between them. 

-- 
Kenneth Albanowski (kjahds@kjahds.com, CIS: 70705,126)






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