Re: GIOChannel & Intercepting stdout



On 08/26/2010 12:53 PM, richard boaz wrote:
The actual program I intend to use this in is a background process where
the actual processing executes in a separate thread while the main
thread sits in the main loop.  With the watch on the read-end of the
pipe, the callback is fired and executes within the main loop, while all
writing occurs on the execution thread; i.e, backwards from what you
suggest, but both processing entities (write to, read from) are separate

Exactly; it doesn't matter which thread is which, it's just important that they're in different threads or processes, so they don't deadlock. For example, it wouldn't be enough to place the output sink in the main loop of a single-threaded program, because it wouldn't get a chance to run during a printf(). This means that you must never print anything to stdout from the thread that runs the mainloop; if you do (and the size of the output exceeds the pipe's buffer, which is fairly small), that thread will deadlock deep inside stdio. This can be a nasty gotcha for someone that maintains the code later, so a big fat comment might be in order.

I have only one comment on the code itself:

gboolean my_callback(GIOChannel *source, GIOCondition condition, gpointer data)
{
   GMainLoop *loop = (GMainLoop *) data;
   switch (condition)
   {
     case G_IO_IN:
     {
       gchar buf2[100];
       memset(buf2, 0, sizeof(buf2));
       read(fd[READFD], buf2, sizeof(buf2));    // read the data from

Since you're already using the GIOChannel source, why not also use it for reading, by calling g_io_channel_read_chars? This has the advantage that you don't need global variables to store the pipe file descriptor, and also you get a richer array of functions for reading.

Regardless of whether you use read() or g_io_channel_read_chars(), be sure to check the errors returned.

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