Re: Warnings/Errors during Threaded Execution



(Please move this discussion over to gtk-app-devel-list.  gtk-devel-list
is for the development of gtk itself.)

Christopher Bland wrote:
> Brian J. Tarricone wrote:
> 
>>> Clicking the first button fires the 'clicked' event where I make the
>>> following calls:
>>>
>>> g_thread_init(NULL);
>>> gdk_threads_init();
> 
>> Looks like you didn't read the docs well enough then.  Those two calls
>> *must* come *before* your gtk_init() call.  Then, as another poster
>> suggested, you need to surround the call to gtk_main() like so:
> 
> Right on... I did miss that part. I'm obviously new to GTK but not to
> threading and I'm having a hard time wrapping my brain around this for
> some reason.
> 
> I cleared up the warning messages, however I am still hung up; I've
> pasted a sample below. When I click the 'Start' button it freezes and
> I'm not using threads, although I think it should be set up to run
> them. I'm unfortunately the only developer in my shop so I can't get
> another pair of eyes to look at this and I've been driving myself crazy
> all day. Any suggestions would be appreciated.

That's cuz you missed one of the other things I said above: gtk signal
callbacks are run with the gdk lock held, so you must not call
gdk_threads_enter() in a signal callback.  Your beginScan() callback
calls setStatus(), which does just that.

(On a side note, I'd suggest you replace:

> 	while (g_main_context_iteration(NULL, FALSE));

with:

while(gtk_events_pending())
    gtk_main_iteration();

	-brian


> 
> 
> [code]
> #include <stdio.h>
> #include <gtk/gtk.h>
> 
> 
> GtkWidget *statusbar;
> static guint context_id;
> 
> int setStatus (char*, char*);
> 
> 
> static void beginScan (GtkWidget *widget, gpointer data)
> {
> 	printf("Hello World!\n");
> 	setStatus("0.0", "Working...");
> }
> 
> 
> /* Callback function to set the progress bar from other functions */
> int setStatus (char *fraction, char *text)
> {
> 	
> 	gdk_threads_enter();
> 	gtk_statusbar_push(GTK_STATUSBAR(statusbar), context_id, text);
> 	while (g_main_context_iteration(NULL, FALSE));
> 	gdk_threads_leave();
> 		
> 	return 0;
> }
> 
> 
> /* Callback to do some cleanup if a delete_event is called */
> static gboolean delete_event (GtkWidget *widget, GdkEvent *event,
> gpointer data )
> {
>     /* TODO: Need to put some cleanup stuff here... */
>     return FALSE;
> }
> 
> 
> /* Callback to destroy the window and all of its widgets */
> static void destroy (GtkWidget *widget, gpointer data)
> {
>     gtk_main_quit ();
> }
> 
> 
> int main(int argc, char *argv[])
> {
> 	GtkWidget *window, *button1;
> 	GtkWidget *vbox1, *info_frame;
> 	
>     g_thread_init(NULL);
>     gdk_threads_init();
>     
>     gtk_init (&argc, &argv);
>     
>     /* create a new window */
>     window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
>     gtk_window_set_title(GTK_WINDOW(window), "Aurora Hard Drive
> Forensics");
> 	gtk_window_set_default_size(GTK_WINDOW(window), 200, 125);
> 	gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS);
> 	gtk_container_set_border_width (GTK_CONTAINER(window), 3);
>     
>     g_signal_connect (G_OBJECT(window), "delete_event",
> G_CALLBACK(delete_event), NULL);
>     g_signal_connect (G_OBJECT(window), "destroy", G_CALLBACK(destroy),
> NULL);
>     
>     /* Create the vertical packing box and the two frames */
>     vbox1 = gtk_vbox_new(FALSE, 0);
>     info_frame = gtk_frame_new("Information");
>     
>     button1 = gtk_button_new_with_label("Start Scan");
>     g_signal_connect(G_OBJECT(button1), "clicked",
> G_CALLBACK(beginScan), NULL);
>     gtk_container_add(GTK_CONTAINER(info_frame), button1);
>     
>     /* Create the status bar */
>     statusbar = gtk_statusbar_new();
>     gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(statusbar), FALSE);
>     context_id = gtk_statusbar_get_context_id(GTK_STATUSBAR(statusbar),
> "Statusbar");
>     gtk_statusbar_push(GTK_STATUSBAR(statusbar), context_id, "Idle");
>     
>    
> /*************************************************************************/
>     /* Start packing the boxes and frames into the window */
>     gtk_box_pack_start(GTK_BOX(vbox1), info_frame, TRUE, TRUE, 0);
>     gtk_box_pack_start(GTK_BOX(vbox1), statusbar, FALSE, TRUE, 0);
>     gtk_container_add(GTK_CONTAINER(window), vbox1);
>     
>    
> /*************************************************************************/
>     /* The final step is to display this newly created widget. */
>     gtk_widget_show_all(window);
>     gtk_widget_show(window);
>     
>     gdk_threads_enter();
>     gtk_main();
>     gdk_threads_leave();
>     
>     return 0;
> }
> [/code]
> 
> c++ `pkg-config --cflags --libs gtk+-2.0 gthread-2.0` gtk_thread_test.c
> 
> 
> ________________________________________________________________________
> Try Juno Platinum for Free! Then, only $9.95/month!
> Unlimited Internet Access with 1GB of Email Storage.
> Visit http://www.juno.com/value to sign up today!
> 
> 



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