io_watch

#include <c++-gtk-utils/io_watch.h> More...

## Functions

guint | Cgu::start_iowatch (int fd, const Callback::CallbackArg< bool & > *cb, GIOCondition io_condition, gint priority=G_PRIORITY_DEFAULT, GMainContext *context=0)
guint | Cgu::start_iowatch (int fd, const Callback::CallbackArg< bool & > *cb, Releaser &r, GIOCondition io_condition, gint priority=G_PRIORITY_DEFAULT, GMainContext *context=0)
guint | Cgu::start_iowatch (int fd, const Callback::CallbackArg< GIOCondition, bool & > *cb, GIOCondition io_condition, gint priority=G_PRIORITY_DEFAULT, GMainContext *context=0)
guint | Cgu::start_iowatch (int fd, const Callback::CallbackArg< GIOCondition, bool & > *cb, Releaser &r, GIOCondition io_condition, gint priority=G_PRIORITY_DEFAULT, GMainContext *context=0)
template<class F , class = typename std::enable_if<!std::is_convertible<typename std::remove_reference<F>::type, const Callback::CallbackArg<GIOCondition, bool&>*>::value && !std::is_convertible<typename std::remove_reference<F>::type, const Callback::CallbackArg<bool&>*>::value>::type>
guint | Cgu::start_iowatch (int fd, F &&func, GIOCondition io_condition, gint priority=G_PRIORITY_DEFAULT, GMainContext *context=0)
template<class F , class = typename std::enable_if<!std::is_convertible<typename std::remove_reference<F>::type, const Callback::CallbackArg<GIOCondition, bool&>*>::value && !std::is_convertible<typename std::remove_reference<F>::type, const Callback::CallbackArg<bool&>*>::value>::type>
guint | Cgu::start_iowatch (int fd, F &&func, Releaser &r, GIOCondition io_condition, gint priority=G_PRIORITY_DEFAULT, GMainContext *context=0)

## Detailed Description

#include <c++-gtk-utils/io_watch.h>

The start_iowatch() function connects a Unix file descriptor to an event loop owned by a GMainContext object (normally the main program loop). It both saves the overhead of having to construct a GIOChannel object where the only thing wanted is to execute a callback when there is something to be read from a pipe, fifo or socket or a pipe or fifo can be written to, and it also provides for automatic disconnection when an object whose function the callback represents or calls into is destroyed.

For the GIOCondition argument of start_iowatch(), G_IO_IN can be bitwise-ORed with G_IO_HUP, and should be if the callback has the task of cleaning up if EOF is reached (see http://www.greenend.org.uk/rjk/2001/06/poll.html ), which is detected by read() returning 0. A cast will be required to do this for the third argument of start_iowatch() (that is, pass GIOCondition(G_IO_IN | G_IO_HUP)). In addition, G_IO_IN and G_IO_OUT can be bitwise-ORed with G_IO_ERR (and passed as GIOCondition(G_IO_IN | G_IO_HUP | G_IO_ERR) or GIOCondition(G_IO_OUT | G_IO_ERR)), which would be detected in the callback by read() or write() returning -1.

The start_iowatch() function has a number of overloads for the callback to be executed when the file descriptor becomes available for reading or writing. The simplest to use take an ordinary callable object, such as a lambda expression or the return value of std::bind. For these, the callable object should take two unbound arguments, the first a GIOCondition type and the second a bool& type. When the callable object is executed, the GIOCondition argument is passed a value representing the bitwise-ORed events which caused the call: this enables a single watch to be provided for both reading and writing (if the file descriptor has been opened for reading and writing), by testing for G_IO_IN and G_IO_OUT on that argument in the callback function. It also enables, by testing for G_IO_HUP and G_IO_ERR, a hang-up or error condition to be detected without having to inspect the return value of read() or write() (but note the test results referred to in http://www.greenend.org.uk/rjk/2001/06/poll.html , which show that the ending of a connection can only reliably be determined by testing whether read() returns 0, or whether the iostream wrapper on top of it reports end of file after attempting a read.)

The second bool& argument can be used to end the watch. If it is set by the callable object when executed to false, say because end-of-file has been reached, then the watch will be ended and all resources connected with it deleted without further user action being required (there is no need for the callable object to set it to true if the watch is to continue, as that is the default).

Other overloads of start_iowatch() take the more explicitly typed Callback::CallbackArg<GIOCondition, bool&> callback object (as constructed with Callback::lambda(), Callback::make() or Callback::make_ref()) instead of a simple callable object, and others take a Callback::CallbackArg<bool&> object for cases where a GIOCondition argument is unnecessary (although there is nothing stopping the other overloads being used and that argument being ignored, and that version is mainly kept to retain compatibility with the 1.2 and 2.0 series of the library).

All of the start_iowatch() overloads have an option to take a Callback::Releaser object as their third argument, which provides for automatic ceasing of the watch if the target object which has the Releaser as a member is destroyed. (Note that for this to be race free, the lifetime of the remote target object whose method is to be invoked must be determined by the thread to whose main loop the watch has been attached. When the main loop begins invoking the execution of the watch callback, the remote object must either wholly exist, in which case the callback will be invoked, or have been destroyed, in which case the callback will be ignored, and not be in some transient half-state governed by another thread.)

start_iowatch() is thread-safe (it may be called in any thread) provided that, if glib < 2.32 is used, the glib main loop has been made thread-safe by a call to g_thread_init(). glib >= 2.32 does not require g_thread_init() to be called in order to be thread-safe.

As mentioned above, the connected callback passed to start_iowatch() has an unbound bool& argument. The watch will be ended if that argument is set by the connected callback to false, say because end-of-file has been reached. In addition, the watch will be ended automatically and resources deleted if (i) as mentioned above, the callback passed to start_iowatch() is protected by a Releaser object and the target object having the Releaser as a member is destroyed, or (ii) g_source_remove() is called on the source id returned by start_iowatch() (where the watch is attached to the default main context) or g_source_destroy() is called on the GSource object obtained from that id with g_main_context_find_source_by_id() (where the watch has been attached to a non-default main context). If the source has been removed automatically by virtue of the bool& argument being set to false or by virtue of a Releaser object releasing, g_source_remove() or g_source_destroy() should not afterwards be called in respect of the id value returned by start_iowatch() in case it has been reused by the main context concerned in the meantime.

## Function Documentation

## start_iowatch() [1/6]

guint Cgu::start_iowatch | ( | int | fd,
|  | const Callback::CallbackArg< bool & > * | cb,
|  | GIOCondition | io_condition,
|  | gint | priority = `G_PRIORITY_DEFAULT`,
|  | GMainContext * | context = `0`
| ) |  |

Starts an io watch in the glib main loop on a file descriptor, and executes the callback if the condition in io_condition is met. It is thread-safe (it may be called in any thread) provided that, if glib < 2.32 is used, g_thread_init() has been called. glib >= 2.32 does not require g_thread_init() to be called to be thread-safe. From version 2.0.24/2.2.7 of the library this function will not throw. (Prior to that, it could throw std::bad_alloc if memory was exhausted and the system threw in that case, or Cgu::Thread::MutexError if initialisation of the mutex in a SafeEmitterArg object failed, in which case the CallbackArg object would be disposed of.)

Parameters

  fd | The file descriptor.
  cb | The callback object. Ownership is taken of this object, and it will be deleted when it has been finished with
  io_condition | The condition to be watched for (G_IO_IN may be bitwise-ored with G_IO_HUP, and G_IO_IN and G_IO_OUT may be bitwise-ored with G_IO_ERR).
  priority | The priority to be given to the watch in the main loop. In ascending order of priorities, priorities are G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE, G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is G_PRIORITY_DEFAULT. This determines the order in which the callback will appear in the event list in the main loop, not the priority which the OS will adopt
  context | The glib main context to which the watch is to be attached (the default of NULL will cause the watch to be attached to the main program loop, and this is almost always what is wanted).

Returns
  The glib source id of the watch.

Note
  1. Cancellation of the thread to which the watch is attached is blocked during execution of the callback.
  2. If the callback throws an exception, the exception will be consumed to protect the main loop and a g_critical() warning will be issued.

## start_iowatch() [2/6]

guint Cgu::start_iowatch | ( | int | fd,
|  | const Callback::CallbackArg< bool & > * | cb,
|  | Releaser & | r,
|  | GIOCondition | io_condition,
|  | gint | priority = `G_PRIORITY_DEFAULT`,
|  | GMainContext * | context = `0`
| ) |  |

Starts an io watch in the glib main loop on a file descriptor, and executes the callback if the condition in io_condition is met. This version provides for automatic watch disconnection when the object whose function the callback represents is destroyed, via the Releaser object. It is thread-safe (it may be called in any thread) provided that, if glib < 2.32 is used, g_thread_init() has been called. glib >= 2.32 does not require g_thread_init() to be called to be thread-safe.

Parameters

  fd | The file descriptor.
  cb | The callback object. Ownership is taken of this object, and it will be deleted when it has been finished with.
  r | A Releaser object which the protected object has as a public member.
  io_condition | The condition to be watched for (G_IO_IN may be bitwise-ored with G_IO_HUP, and G_IO_IN and G_IO_OUT may be bitwise-ored with G_IO_ERR).
  priority | The priority to be given to the watch in the main loop. In ascending order of priorities, priorities are G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE, G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is G_PRIORITY_DEFAULT. This determines the order in which the callback will appear in the event list in the main loop, not the priority which the OS will adopt
  context | The glib main context to which the watch is to be attached (the default of NULL will cause the watch to be attached to the main program loop, and this is almost always what is wanted).

Returns
  The glib source id of the watch.

Exceptions

  std::bad_alloc | This function might throw std::bad_alloc if memory is exhausted and the system throws in that case. If it does so, the CallbackArg object will be disposed of.
  Cgu::Thread::MutexError | This function might throw Cgu:Thread::MutexError if initialisation of the mutex in a SafeEmitterArg object constructed by this function fails. If it does so, the CallbackArg object will be disposed of. (It is often not worth checking for this exception, as it means either memory is exhausted or pthread has run out of other resources to create new mutexes.)

Note
  1. Cancellation of the thread to which the watch is attached is blocked during execution of the callback.
  2. If the callback throws an exception, the exception will be consumed to protect the main loop and a g_critical() warning will be issued.

## start_iowatch() [3/6]

guint Cgu::start_iowatch | ( | int | fd,
|  | const Callback::CallbackArg< GIOCondition, bool & > * | cb,
|  | GIOCondition | io_condition,
|  | gint | priority = `G_PRIORITY_DEFAULT`,
|  | GMainContext * | context = `0`
| ) |  |

Starts an io watch in the glib main loop on a file descriptor, and executes the callback if the condition in io_condition is met. This version provides the GIOCondition status which caused the callback to be invoked as the first unbound argument of the callback object. It is thread-safe (it may be called in any thread) provided that, if glib < 2.32 is used, g_thread_init() has been called. glib >= 2.32 does not require g_thread_init() to be called to be thread-safe. From version 2.0.24/2.2.7 of the library this function will not throw. (Prior to that, it could throw std::bad_alloc if memory was exhausted and the system threw in that case, or Cgu::Thread::MutexError if initialisation of the mutex in a SafeEmitterArg object failed, in which case the CallbackArg object would be disposed of.)

Parameters

  fd | The file descriptor.
  cb | The callback object. Ownership is taken of this object, and it will be deleted when it has been finished with.
  io_condition | The condition(s) to be watched for (G_IO_IN, G_IO_OUT, G_IO_HUP and G_IO_ERR may all be bitwise-ored).
  priority | The priority to be given to the watch in the main loop. In ascending order of priorities, priorities are G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE, G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is G_PRIORITY_DEFAULT. This determines the order in which the callback will appear in the event list in the main loop, not the priority which the OS will adopt
  context | The glib main context to which the watch is to be attached (the default of NULL will cause the watch to be attached to the main program loop, and this is almost always what is wanted).

Returns
  The glib source id of the watch.

Note
  1. Cancellation of the thread to which the watch is attached is blocked during execution of the callback.
  2. If the callback throws an exception, the exception will be consumed to protect the main loop and a g_critical() warning will be issued.

Since 2.0.0-rc2

## start_iowatch() [4/6]

guint Cgu::start_iowatch | ( | int | fd,
|  | const Callback::CallbackArg< GIOCondition, bool & > * | cb,
|  | Releaser & | r,
|  | GIOCondition | io_condition,
|  | gint | priority = `G_PRIORITY_DEFAULT`,
|  | GMainContext * | context = `0`
| ) |  |

Starts an io watch in the glib main loop on a file descriptor, and executes the callback if the condition in io_condition is met. This version provides both automatic watch disconnection when the object whose function the callback represents is destroyed, via the Releaser object, and provides the GIOCondition status which caused the callback to be invoked as the first unbound argument of the callback object. It is thread-safe (it may be called in any thread) provided that, if glib < 2.32 is used, g_thread_init() has been called. glib >= 2.32 does not require g_thread_init() to be called to be thread-safe.

Parameters

  fd | The file descriptor.
  cb | The callback object. Ownership is taken of this object, and it will be deleted when it has been finished with.
  r | A Releaser object which the protected object has as a public member.
  io_condition | The condition(s) to be watched for (G_IO_IN, G_IO_OUT, G_IO_HUP and G_IO_ERR may all be bitwise-ored).
  priority | The priority to be given to the watch in the main loop. In ascending order of priorities, priorities are G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE, G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is G_PRIORITY_DEFAULT. This determines the order in which the callback will appear in the event list in the main loop, not the priority which the OS will adopt
  context | The glib main context to which the watch is to be attached (the default of NULL will cause the watch to be attached to the main program loop, and this is almost always what is wanted).

Returns
  The glib source id of the watch.

Exceptions

  std::bad_alloc | This function might throw std::bad_alloc if memory is exhausted and the system throws in that case. If it does so, the CallbackArg object will be disposed of.
  Cgu::Thread::MutexError | This function might throw Cgu:Thread::MutexError if initialisation of the mutex in a SafeEmitterArg object constructed by this function fails. If it does so, the CallbackArg object will be disposed of. (It is often not worth checking for this exception, as it means either memory is exhausted or pthread has run out of other resources to create new mutexes.)

Note
  1. Cancellation of the thread to which the watch is attached is blocked during execution of the callback.
  2. If the callback throws an exception, the exception will be consumed to protect the main loop and a g_critical() warning will be issued.

Since 2.0.0-rc2

## start_iowatch() [5/6]

template<class F , class = typename std::enable_if<!std::is_convertible<typename std::remove_reference<F>::type, const Callback::CallbackArg<GIOCondition, bool&>*>::value && !std::is_convertible<typename std::remove_reference<F>::type, const Callback::CallbackArg<bool&>*>::value>::type>

guint Cgu::start_iowatch | ( | int | fd,
|  | F && | func,
|  | GIOCondition | io_condition,
|  | gint | priority = `G_PRIORITY_DEFAULT`,
|  | GMainContext * | context = `0`
| ) |  |

Starts an io watch in the glib main loop on a file descriptor, and executes a callable object if the condition in io_condition is met. It provides the GIOCondition status which caused the callback to be invoked as the first unbound argument of the callable object, and the second is a bool& argument which if set to 'true' will cause the io watch to end. It is thread-safe (it may be called in any thread) provided that, if glib < 2.32 is used, g_thread_init() has been called. glib >= 2.32 does not require g_thread_init() to be called to be thread-safe.

Parameters

  fd | The file descriptor.
  func | A callable object, such as formed by a lambda expression or the result of std::bind. It should take two unbound arguments of type 'GIOCondition' and 'bool&'.
  io_condition | The condition to be watched for (G_IO_IN may be bitwise-ored with G_IO_HUP, and G_IO_IN and G_IO_OUT may be bitwise-ored with G_IO_ERR).
  priority | The priority to be given to the watch in the main loop. In ascending order of priorities, priorities are G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE, G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is G_PRIORITY_DEFAULT. This determines the order in which the callback will appear in the event list in the main loop, not the priority which the OS will adopt
  context | The glib main context to which the watch is to be attached (the default of NULL will cause the watch to be attached to the main program loop, and this is almost always what is wanted).

Returns
  The glib source id of the watch.

Exceptions

  std::bad_alloc

  This function might throw std::bad_alloc if memory is exhausted and the system throws in that case. (From version 2.2.7 of the library this exception will not be thrown if the library has been installed using the --with-glib-memory-slices-no-compat configuration option. Prior to version 2.2.7 Cgu::Thread::MutexError could also be thrown if initialisation of the mutex in a SafeEmitterArg object failed.)

Note
  1. This function may also throw if the copy or move constructor of the callable object throws.
  2. Cancellation of the thread to which the watch is attached is blocked during execution of the callback.

Since 2.1.0

## start_iowatch() [6/6]

template<class F , class = typename std::enable_if<!std::is_convertible<typename std::remove_reference<F>::type, const Callback::CallbackArg<GIOCondition, bool&>*>::value && !std::is_convertible<typename std::remove_reference<F>::type, const Callback::CallbackArg<bool&>*>::value>::type>

guint Cgu::start_iowatch | ( | int | fd,
|  | F && | func,
|  | Releaser & | r,
|  | GIOCondition | io_condition,
|  | gint | priority = `G_PRIORITY_DEFAULT`,
|  | GMainContext * | context = `0`
| ) |  |

Starts an io watch in the glib main loop on a file descriptor, and executes a callable object if the condition in io_condition is met. It provides the GIOCondition status which caused the callback to be invoked as the first unbound argument of the callable object, and the second is a bool& argument which if set to 'true' will cause the io watch to end. This version provides for automatic watch disconnection if an object whose function the callback represents or calls into is destroyed, via the Releaser object. It is thread-safe (it may be called in any thread) provided that, if glib < 2.32 is used, g_thread_init() has been called. glib >= 2.32 does not require g_thread_init() to be called to be thread-safe.

Parameters

  fd | The file descriptor.
  func | A callable object, such as formed by a lambda expression or the result of std::bind. It should take two unbound arguments of type 'GIOCondition' and 'bool&'.
  r | A Releaser object which the protected object has as a public member.
  io_condition | The condition to be watched for (G_IO_IN may be bitwise-ored with G_IO_HUP, and G_IO_IN and G_IO_OUT may be bitwise-ored with G_IO_ERR).
  priority | The priority to be given to the watch in the main loop. In ascending order of priorities, priorities are G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE, G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is G_PRIORITY_DEFAULT. This determines the order in which the callback will appear in the event list in the main loop, not the priority which the OS will adopt
  context | The glib main context to which the watch is to be attached (the default of NULL will cause the watch to be attached to the main program loop, and this is almost always what is wanted).

Returns
  The glib source id of the watch.

Exceptions

  std::bad_alloc | This function might throw std::bad_alloc if memory is exhausted and the system throws in that case.
  Cgu::Thread::MutexError | This function might throw Cgu:Thread::MutexError if initialisation of the mutex in a SafeEmitterArg object constructed by this function fails. (It is often not worth checking for this exception, as it means either memory is exhausted or pthread has run out of other resources to create new mutexes.)

Note
  1. This function may also throw if the copy or move constructor of the callable object throws.
  2. Cancellation of the thread to which the watch is attached is blocked during execution of the callback.

Since 2.1.0