gdk_input_add select wrapper problem



Hello,

I recently wrote a C++ wrapper to the select() function. I called it a
Selector. Basically you could register and unregister handlers with it
and it would handle read and write events on a file descriptor by
calling your handlers. It worked fine in my terminal mode networking
program, but when I needed to connect a GUI written in Gtk-- to the
networking code, I realized I needed to use Gtk's event loop, not my
own. So I made Selector into an abstract base class, called my select()
wrapper Unix_selector, and created a new class derived from Selector,
Gtk_selector, to wrap gdk_input_add et al instead of select().

First, the only docs I found on gdk_input_add was the tutorial, which
doesn't explain that GDK_INPUT_READ and GDK_INPUT_WRITE are meant to be
bitmasks so you need to do "if (condition & GDK_INPUT_READ)", not "if
(condition == GDK_INPUT_READ)". This definitely needs to be documented!

My first question was whether I could separately register two different
callbacks for the same fd, one for read and one for write. I need to do
this for my interface. Again, no docs, so I looked at the source code
for gdk_input_add and gdk_input_remove, and it seems like it should
work. However it didn't. For example, even though I requested read
condition from gdk_input_add, my callback was getting called even when
the read condition didn't happen, merely because some other module in
the program requested write event notification on the same fd. (In a big
program, the other module might even be written by another person.)

Well, since there is no documentation, I suppose you could argue that
this is intended behavior, but it does seem non intuitive and bizarre
and so I'd say it's a bug. My guess is that the intention was if you
want read and write events on the same fd, to pass a single callback
with condition (GDK_INPUT_READ | GDK_INPUT_WRITE). That's fine (although
again the bitmask nature of the parameter needs to be documented) but
there's no reason not to support separate callbacks also. I believe it's
a one line change to gdk.c, at the end of the gdk_event_wait function,
change:

              if (condition && input->function)
                (* input->function) (input->data, input->source,
condition);

to:

              if ((condition & input->condition) && input->function)
                (* input->function) (input->data, input->source,
condition);

This will prevent callbacks from being called for a condition they
didn't request. It seems unlikely that this would break any existing
code, so could this be applied to the source tree? I've already made a
workaround for the strange behavior in my Gtk_selector class, but I
still think it would be nice if this was fixed.

- Michael



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