Re: main loop & asynchronous queues
- From: Thomas Stover <thomas wsinnovations com>
- To: Chris Vine <chris cvine freeserve co uk>, gtk-app-devel-list gnome org
- Subject: Re: main loop & asynchronous queues
- Date: Thu, 24 Sep 2009 14:32:30 -0500
Chris Vine wrote:
In your code you didn't create a GMainContext object for each of your
threads, which is the key point. Each thread in which you want a main
loop should call g_main_context_new() which will create a GMainContext
object for the calling thread, then use that to create a GMainLoop
object, then call g_main_loop_run() on it to run it.
I was getting GMainContexts and GMainLoops confused. Thanks for you
input, I've learned several things.
The end goal I'm working for is to improve some programs I have that
send and receive messages over udp that require "slow" RSA operations
for each one. I want to move the RSA and related processing to another
thread, so that a worker thread listens for socket input, does some
openssl work, then gives a message to the main thread without blocking
on sockets or polling mutexes. At the same time the main thread can send
a message to a worker thread to be processed before sent instead of
slowing down the main thread. The adding of an idle_source to another
thread's main loop technique being discussed will certainly do the trick
nicely. The more I learn, glib just keeps getting better.
For anyone in the future searching around for more info on this topic,
here is a variation of the gtk hello world program I was doing some
experiments with. My main question at this point to anyone who might
know is, should the idle source get dereferenced / freed somehow? My
other question is g_source_attach() working on another thread's
GMainContext with atomic operations, will it possibly have to block for
access, or I'm I not doing this in a thread safe way?
/* build with gcc source.c `pkg-config --cflags --libs gtk+2.0 gthread-2.0`
One thread opens a window with a button, and another prints to the
console every 2 seconds. Each has a separate main context and main loop.
When the button in the first thread is pushed, the other thread's event
loop data structures are manipulated to schedule the running of
idle_callback() when possible in the other thread. */
#include <glib.h>
#include <gtk/gtk.h>
GMainContext *thread1_context, *thread2_context;
gboolean timeout_callback(gpointer data)
{
g_print("timeout_callback()\n");
return TRUE;
}
gboolean idle_callback(gpointer data)
{
g_print("idle_callback()\n");
return FALSE;
}
gpointer thread2_entry(gpointer data)
{
GMainLoop *main_loop;
GSource *seconds_timeout_source;
main_loop = g_main_loop_new(thread2_context, FALSE);
seconds_timeout_source = g_timeout_source_new_seconds(2);
g_source_set_callback(seconds_timeout_source, timeout_callback, NULL,
NULL);
g_source_attach(seconds_timeout_source, thread2_context);
g_main_loop_run(main_loop);
}
void button_click(GtkWidget *widget, gpointer data)
{
GSource *idle_source;
idle_source = g_idle_source_new();
g_source_set_callback(idle_source, idle_callback, NULL, NULL);
g_source_attach(idle_source, thread2_context);
}
gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
return FALSE;
}
void destroy(GtkWidget *widget, gpointer data)
{
gtk_main_quit();
}
int main(int argc, char **argv)
{
GtkWidget *window;
GtkWidget *button;
gtk_init(&argc, &argv);
g_thread_init(NULL);
thread1_context = g_main_context_default();
thread2_context = g_main_context_new();
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(window), "delete_event",
G_CALLBACK(delete_event), NULL);
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(destroy), NULL);
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
button = gtk_button_new_with_label("Test");
g_signal_connect(G_OBJECT(button), "clicked",
G_CALLBACK(button_click), NULL);
gtk_container_add(GTK_CONTAINER(window), button);
gtk_widget_show_all(window);
g_thread_create(thread2_entry, NULL, FALSE, NULL);
gtk_main();
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]