Re: watching a file descriptor in gtk3
- From: Chris Vine <chris cvine freeserve co uk>
- To: gtk-app-devel-list gnome org
- Cc: rbd <rbd soest hawaii edu>
- Subject: Re: watching a file descriptor in gtk3
- Date: Mon, 23 Jan 2017 21:41:31 +0000
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]