On Mon, 23 Jan 2017 09:30:17 -1000 (HST)
rbd <r...@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
_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Reply via email to