Hello All
I have posted this example as before and Errol has corrected it alot as my threading was not correct.
Now I have added a queue to the same example.
There is a button which when clicked adds 10 message strings one by one every 50 msec to the queue .
There is also Slow Thread which flashes the button every 250 msec and also checks the queue.
There is also a Fast thread that can be ignored for the moment.
The program works, but I need to know if all my Queue functions are in proper order and that none of them are missing or out of place.
Code:
// gcc -o thread_q_test -g button_queue.c `pkg-config --cflags --libs gtk+-2.0 gthread-2.0`
#include <gtk/gtk.h>
typedef struct
{
GtkWidget * winx;
GtkWidget * button;
GdkColor Colors[2];
} xwindow;
xwindow * tw;
volatile gint running = 1;
GThread *thread1, *thread2;
GAsyncQueue *myQueue;
gpointer fast_thread(gpointer data)
{
int t = 0;
while (g_atomic_int_get(&running))
{
g_usleep(100 * 1000);
printf("FAST %d\n", t);
t ++;
}
return NULL;
}
gpointer slow_thread(gpointer data)
{
gboolean phase = FALSE;
g_async_queue_ref(myQueue);
gpointer queueData;
while (g_atomic_int_get(&running))
{
g_usleep(250 * 1000);
gdk_threads_enter();
if(phase == FALSE)
{
phase = TRUE;
gtk_widget_modify_bg (tw->button, GTK_STATE_NORMAL, &tw->Colors[0]);
gtk_widget_modify_bg (tw->button, GTK_STATE_PRELIGHT, &tw->Colors[0]);
}
else
{
phase = FALSE;
gtk_widget_modify_bg (tw->button, GTK_STATE_NORMAL, &tw->Colors[1]);
gtk_widget_modify_bg (tw->button, GTK_STATE_PRELIGHT, &tw->Colors[1]);
}
queueData = g_async_queue_try_pop (myQueue);
if(queueData != NULL)
{
printf("Queue message %s\n",(char*)queueData);
}
gdk_threads_leave();
}
return NULL;
}
static gint i;
gboolean button_timeout(gpointer data)
{
if (i < 10) {
g_async_queue_ref(myQueue);
gchar *s = g_strdup_printf("set %i", i);
gtk_button_set_label(GTK_BUTTON(data), s);
g_async_queue_push(myQueue,(gpointer) g_strdup(s));
g_async_queue_unref(myQueue);
++i;
g_free(s);
return TRUE;
}
return FALSE;
}
void button_click(GtkWidget *button, gpointer data)
{
i = 0;
button_timeout(button);
g_timeout_add(50, button_timeout, button);
}
void destroy_cb(GtkObject *object, gpointer user_data)
{
// Must kill the threads here before carrying on
g_atomic_int_set(&running, 0);
g_thread_join(thread1);
// Note locking for slow_thread()
gdk_threads_leave();
g_thread_join(thread2);
gdk_threads_enter();
gtk_main_quit();
}
int main (int argc, char *argv[])
{
GError *err1, *err2;
if(!g_thread_supported())
{
g_thread_init(NULL);
gdk_threads_init();
}
else
{
return 1;
}
gdk_threads_enter();
gtk_init (&argc, &argv);
myQueue=g_async_queue_new();
tw = g_slice_new (xwindow);
// build window
gdk_color_parse ("#000000", &tw->Colors[0]);// black
gdk_color_parse ("#ffffff", &tw->Colors[1]);// white
tw->winx = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request (tw->winx, 200, 100);
g_signal_connect (tw->winx, "destroy",G_CALLBACK (destroy_cb), NULL);
tw->button = gtk_button_new();
gtk_container_add (GTK_CONTAINER(tw->winx), tw->button);
g_signal_connect (G_OBJECT (tw->button), "clicked", G_CALLBACK (button_click), NULL);
gtk_widget_show_all(tw->winx);
if(!(thread1 = g_thread_create(fast_thread, NULL, TRUE, &err1)))
{
g_print("FAST Thread create failed: %s!!\n", err1->message );
g_error_free ( err1 ) ;
}
else
{
g_print(" vvvvv FAST vvvvv\n");
}
if(!(thread2 = g_thread_create(slow_thread, NULL, TRUE, &err2)))
{
printf("SLOW Thread create failed: %s!!\n", err2->message );
g_error_free ( err2 ) ;
}
else
{
g_print(" vvvvv SLOW vvvvv\n");
}
gtk_main ();
gdk_threads_leave();
g_slice_free (xwindow, tw);
return 0;
}
Thanks Errol for fixing the threads...
Thanks in advance.