On Mon, 29 Mar 2010 20:26:03 -0400, "A. Walton" <awal...@gnome.org> wrote:
> On Mon, Mar 29, 2010 at 6:58 PM, Thomas Stover
<tho...@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
_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Reply via email to