Strange interaction between GtkDialog and a GThread



Maybe I'm just doing something stupid here. But I'd
like to know what, at least!

Below is an example of a mysterious (well, mysterious
to me) problem I've encountered, involving some sort
of interaction between a gtk_file_chooser_dialog_new
and I thought was a completely separate thread.

I'm hoping someone here can tell me what's behind
this, and how I can avoid it.

This test example creates a thread which:

1) announces it is going to sleep for 30 seconds
2) attempts to sleep for 30 seconds
3) reports how long it actually slept

Once that sleeper thread is created, the main thread
creates a gtk_file_chooser_dialog_new. At which point
the sleeper thread instantly stops sleeping and
reports that it slept 0 seconds.

But if I call, say, gtk_message_dialog_new instead,
the sleeper thread sleeps the normal amount of time
(and reports such).

Incidentally, I realize that gtk_main is doing nothing
here; I've also tried launching the dialogs from a
timeout (with appropriate
gdk_threads_enter/gdk_threads_leave as stated in the
FAQ), and I see the same thing; I left that out here
just to make this as simple as possible.

Thanks for any info!
//////////////////////////////////////
/*
Demonstration of strange
gtk_file_chooser_dialog_new/thread interaction.
Compile with:
gcc main.c -o HelloThreadBreaker \
`pkg-config --cflags --libs gtk+-2.0 gthread-2.0`
*/
#include <unistd.h>
#include <gtk/gtk.h>

void *sleep_for_awhile (void *args)
{
time_t t1;
time_t t2;

g_print ("Going to sleep for 30 seconds\n");
time (&t1);
sleep (30);
time (&t2);
g_print ("I slept for %d seconds\n", (int) (t2 - t1));
return NULL;
}

int main (int argc, char *argv[])
{
char *filename;
GError *error = NULL;
GtkWidget *dialog = NULL;

g_thread_init (NULL);
gdk_threads_init ();
gdk_threads_enter ();

gtk_init (&argc, &argv);

if (!g_thread_create (sleep_for_awhile, NULL, FALSE,
&error))
{
g_printerr ("Failed to create sleep_for_awhile
thread:%s\n",
error->message);
return 1;
}

dialog = gtk_file_chooser_dialog_new ("Open File",
NULL,
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN,
GTK_RESPONSE_ACCEPT, NULL);

if (gtk_dialog_run (GTK_DIALOG (dialog)) ==
GTK_RESPONSE_ACCEPT)
{
filename = gtk_file_chooser_get_filename
(GTK_FILE_CHOOSER (dialog));
g_free (filename);
}

/*
//this variety doesn't affect thread:
dialog = gtk_message_dialog_new (NULL,
GTK_DIALOG_MODAL,
GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
"Message Box");
gtk_dialog_run (GTK_DIALOG (dialog));
*/
 
gtk_widget_destroy (dialog);

gtk_main ();
gdk_threads_leave ();

return 0;
}






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