Re: =?UTF-8?Q?g=5Fmain=5Fcontext=5Fpush=5Fthread=5Fdefault=28=29=20=26=20?= =?UTF-8?Q?g=5Fio=5F*=28=29?=



On Mon, 29 Mar 2010 20:26:03 -0400, "A. Walton" <awalton gnome org> wrote:
On Mon, Mar 29, 2010 at 6:58 PM, Thomas Stover
<thomas wsinnovations com>
wrote:
In the documentation for g_main_context_push_thread_default(), the
following sentence appears:

"This will cause certain asynchronous operations (such as most
gio-based
I/O) which are started in this thread to run under context and deliver
their results to its main loop, rather than running under the global
default context in the main thread."

This makes me think my experiment program below would work, yet on
ubuntu
9.10 at least, it does not. Perhaps g_io_channel_unix_new() is not in
the
"most" group referred to above? Or maybe I'm doing this wrong. Thanks
for
any input.

GIO refers to the GIO library
(http://library.gnome.org/devel/gio/stable/), not to the g_io_* family
of functions. Probably worth filing a bug to make this clearer in the
documentation.

-A. Walton


Thanks for clearing that up.

In case anyone searching through list archives has this same issue, this
is how to delegate g_io_channel_* tasks to arbitrary threads /
GMainContexts. I had to look in giochannel.c.

-use g_io_create_watch() instead of _add_watch()
-then manually use g_source_attach() & g_source_set_callback()
-the callback must be typecast to GSourceFunc
-apparently the GMainContext used by g_source_attach() will add a
reference to the GSource, so call g_source_unref() on the GSource after the
attach().

modified example below:
===
#include <glib.h>
#include <unistd.h>
#include <sys/syscall.h>

GMainContext *thread1_context, *thread2_context;
GMainLoop *main_loop1, *main_loop2;

gboolean idle_callback(gpointer data)
{
 g_print("idle_callback() %d\n", (pid_t) syscall (SYS_gettid));
 return FALSE;
}

gboolean input_callback(GIOChannel *source,
                       GIOCondition condition,
                       gpointer data)
{
 GSource *idle_source;
 gchar buffer[16];
 gsize bytes_read;
 g_print("input_callback() %d\n", (pid_t) syscall (SYS_gettid));

 if(g_io_channel_read_chars(source, buffer, 1, &bytes_read, NULL) !=
G_IO_STATUS_NORMAL)
  return FALSE;

 g_print("  bytes_read = %d\n", (int) bytes_read);

 idle_source = g_idle_source_new();
 g_source_set_callback(idle_source, idle_callback, NULL, NULL);
 g_source_attach(idle_source, thread1_context);
 g_source_unref(idle_source);
 return TRUE;
}

gpointer thread2_entry(gpointer data)
{
 GIOChannel *channel;
 GSource *source;
 g_print("thread2_entry() %d\n", (pid_t) syscall (SYS_gettid));

 main_loop2 = g_main_loop_new(thread2_context, FALSE);

 channel = g_io_channel_unix_new(0);

 source = g_io_create_watch(channel, G_IO_IN);

 g_source_set_callback(source, (GSourceFunc) input_callback, NULL, NULL);

 g_source_attach(source, thread2_context);

 g_source_unref(source);

 g_main_loop_run(main_loop2);
}

int main(int argc, char **argv)
{
 g_thread_init(NULL);

 thread1_context = g_main_context_default();
 thread2_context = g_main_context_new();

 main_loop1 = g_main_loop_new(thread1_context, FALSE);

 g_thread_create(thread2_entry, NULL, FALSE, NULL);

 g_main_loop_run(main_loop1);
 return 0;
}
===

-- 
www.thomasstover.com



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