Re: watching a file descriptor in gtk3



On Mon, 23 Jan 2017 09:30:17 -1000 (HST)
rbd <rbd soest hawaii edu> wrote:
Hi Chris,

Thanks very much for all of that information -- it was very helpful!

I do not fully understand your question (especially I don't
understand your reference to using "g_idle_add_full() and do my
own non-blocking select() inside my callback", which would not
work), ...  

I won't be trying the above approach unless all else fails (see
below), but I am curious as to why you say that I could not
successfully call a non-blocking select() (or poll(), if you prefer)
on my file descriptor of interest inside a callback registered via
g_idle_add_full(), then read from that descriptor if select() tells
me there's something there. This is not as logically sensible as
registering a separate input source to be polled inside the main
loop, but I can't see why it wouldn't work.

The problem is that the main loop would enter a busy loop.  Well, maybe
a 'busy-ish' loop.  If you call up g_idle_add() with a repeating
callback (one which returns TRUE) which does nothing except examine a
non-blocking select(), you will end up with one CPU core using
approximately 100% CPU.  The default idle priority
G_PRIORITY_DEFAULT_IDLE will put the idle event somewhat at the end of
the main loop's event queue, but when there is nothing else to do it
will continue executing it.  (On a multi-core system this might not be
immediately apparent - you need to be able to interpret top or whatever
other tool you use to see it.)

You could make this work with a timeout, say of around 50mS delay,
which puts the main loop to sleep for a while between iterations.

... This may (or may not) help:
  
https://sourceforge.net/p/cxx-gtk-utils/git/ci/master/tree/c++-gtk-utils/io_$

Thanks very much for the above code sample -- unfortunately it
confirms my very worst expectations of what might be involved with
using g_source_add_unix_fd(), etc., to monitor a file descriptor,
i.e., create a new GSource, code up a whole set of GSourceFuncs
routines to implement a process which is not well-described in the
docs, etc. I'm clearly barking up the wrong tree on that!

It is not quite that bad.  The documentation for g_source_add_unix_fd()
is inadequate, but although not immediately obvious the prepare, check
and finalize handlers can in fact usually just be set to NULL (provided
you have set the 'events' argument for g_source_add_unix_fd()
correctly) so you only need to provide the dispatch handler, which
executes your callback when an event occurs.

The poor quality of the documentation is the real problem here.  I
would give it a try and see how you get on with it.
 
...
  
https://developer.gnome.org/glib/stable/glib-IO-Channels.html#g-io-add-watch

By the way, if you are thinking of using GIOChannel, you might also
want to look at the implementation of gdk_input_add() and
gdk_input_add_full() in gtk+-2. Although now deprecated in gtk+-2,
you can still use those functions if you happen to be building
against gtk+-2.  

Using gtk3, not 2.


If you are using gtk+3 you can set up a read watch as follows (I
have not done a test compile on this snippet but it is what I have
on occasions done in the past, and it avoids keeping an explicit
GIOChannel object in scope if you only want to execute a callback
when a descriptor is ready for input - you can use the internal
reference counting to control channel lifetime):


guint start_read_watch(int fd, GIOFunc func) {
 GIOChannel *channel = g_io_channel_unix_new(fd);
 guint id = g_io_add_watch(channel,
                           G_IO_IN | G_IO_HUP | G_IO_ERR,
                           func,
                           NULL);  

GIOChannel is the ticket, I think, thanks for pointing me there
(where I would probably have never gotten on my own)! Unlike 
g_source_add_unix_fd(), of which I could find no useful example code 
whatsoever other than the code you sent me, there seem to be a fair
number of examples around on basic use of GIOChannel to more or less
do what I want to do (I hope). This 2005 Robert Love article in
particular was quite useful:

http://www.linuxjournal.com/node/8545/print

Still not as drop-dead simple as libXt/Motif's XtAppAddInput() (and I 
cannot believe that I am actually favorably comparing Motif to any 
more contemporary API whatsoever ;-> ), but simple enough to be
useful.

The GIOChannel interface is not well designed by today's standards.  It
confuses concerns by combining a wrapper for poll() with an object for
locale-based reading to and writing from files.  It is against modern
design practice to combine purposes in this way.  But it is old (it goes
back to GTK+-1.2 days) when large multi-purpose objects were all the
rage. We know better now.

Its naming is also now highly confusing as it is not related to glib's
gio namespace, which also provides numerous i/o functions, with an
emphasis on asynchronicity (but which unfortunately suffers from an
overly java-like approach to its stream objects - it may also be a
victim of its times).

Chris


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