Re: watching a file descriptor in gtk3



On Mon, 23 Jan 2017 00:29:46 +0000
Chris Vine <chris cvine freeserve co uk> wrote:
[snip]
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), but you can
either use glib's g_poll()/g_source_add_poll() implementation or (on
unix) its g_source_add_unix_fd() implementation to watch on a file
descriptor. The functionality of both is equivalent, and on unix both
use poll() underneath. This may (or may not) help:

https://sourceforge.net/p/cxx-gtk-utils/git/ci/master/tree/c++-gtk-utils/io_watch.cpp

If you want to use glib's g_source_add_poll() implementation rather
than its g_source_add_unix_fd() implementation, you can avoid some of
the boiler plate with g_io_add_watch() - you can use this to call up a
callback function whenever a file descriptor is ready (you don't need
to use the GIOChannel object for any other purpose, such as reading
from or writing to the descriptor):

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.

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);
  /*
     The call to g_io_add_watch incremented the channel's reference
     count.  Decrement the count now so that when func returns FALSE
     or g_source_remove() is applied to the returned id, the channel
     object will automatically be destroyed.
  */
  g_io_channel_unref(channel);
  return id;
}

This will not close the file descriptor when the watch has finished
(but see g_io_channel_set_close_on_unref()).

g_source_add_unix_fd() may be more efficient if you have a large number
of file watches in any one program.

Chris


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