Thanks for the reply. Interesting. Replacing sleep() with select() did return an error with errno == EINTR. If I understand you correctly, this is a clue that gtk_file_chooser_dialog_new is calling alarm() somewhere.
That may indeed factor in to what I am trying to solve. But fact is, getting a thread to sleep wasn't really my goal, I just used that to make a simple example that would "break." The real challenge I've been having for a couple weeks is with a thread running a blocking D-Bus server. The server works great, but if I launch a gtk_file_chooser_dialog_new, the entire app goes very weird! Below is as simple an example as I could make (without the client; I could paste that code too if wanted, but it is not needed to see the weirdness). Basically, the inconsistent results look like some kind of deadlock; usually on my system, it will not open the dialog, but if the dialog does open, it is dead. Yet normally the D-Bus thread happily continues to serve clients. But not always. Strangest to me is the backtrace; before the call to gtk_file_chooser_dialog_new, the main thread has (as one would expect) no calls to libdbus-1.so.3; after the call to gtk_file_chooser_dialog_new, the main thread is polluted with myriad calls to libdbus-1.so.3., as if it merged with the other thread. Initially, I thought this was a D-Bus problem, so I posted to the D-Bus list; then I started to think it was a GTK issue, so I've posted here. BTW, the D-Bus list did offer one interesting response about how what I see may be related to the strange code behind gtk_dialog_run, in that it "re-enters the main loop." I did look at it's code, and it did mystify me. Here's the thread: [ http://lists.freedesktop.org/archives/dbus/2007-November/008968.html ] Any ideas? Thanks again! ////////////////////////////////////// /* Demonstration of strange gtk_file_chooser_dialog_new/dbus interaction. Compile with: gcc main.c -o HelloThreadBreaker \ `pkg-config --cflags --libs \ gtk+-2.0 gthread-2.0 dbus-1` */ #include <unistd.h> #include <gtk/gtk.h> #include <dbus/dbus.h> #define GNAURAL_DBUS_SERVER "org.gnaural.Server" #define GNAURAL_DBUS_INTERFACE "org.gnaural.Interface" DBusConnection *main_remote_connection = NULL; time_t main_startime; ///////////////////////////// void GetBeatfreq (DBusMessage * msg, DBusConnection * conn) { DBusMessage *reply; DBusMessageIter args; unsigned int voice = 0; if (!dbus_message_iter_init (msg, &args)) { fprintf (stderr, "Message has no arguments\n"); } else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type (&args)) { fprintf (stderr, "Argument is not DBUS_TYPE_UINT32\n"); } else { dbus_message_iter_get_basic (&args, &voice); } reply = dbus_message_new_method_return (msg); double result = (double) (time (NULL) - main_startime); dbus_message_iter_init_append (reply, &args); if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_DOUBLE, &result)) { fprintf (stderr, "Out Of Memory\n"); return; } if (!dbus_connection_send (conn, reply, NULL)) { fprintf (stderr, "Out Of Memory\n"); return; } dbus_connection_flush (conn); dbus_message_unref (reply); } ///////////////////////////// int main_init_connection (void) { DBusError err; int ret; dbus_error_init (&err); main_remote_connection = dbus_bus_get (DBUS_BUS_SESSION, &err); if (dbus_error_is_set (&err)) { fprintf (stderr, "Connection Error (%s)\n", err.message); dbus_error_free (&err); } if (NULL == main_remote_connection) { fprintf (stderr, "Connection Null\n"); return 1; } ret = dbus_bus_request_name (main_remote_connection, GNAURAL_DBUS_SERVER, DBUS_NAME_FLAG_REPLACE_EXISTING, &err); if (dbus_error_is_set (&err)) { fprintf (stderr, "Name Error (%s)\n", err.message); dbus_error_free (&err); } if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { fprintf (stderr, "Not Primary Owner (%d)\n", ret); return 1; } return 0; } //////////////////////////////// void main_check_for_methodcall (gpointer arg) { DBusMessage *msg; if (NULL == main_remote_connection) { fprintf (stderr, "Connection invalid!\n"); return; } fprintf (stderr, "Entering blocking loop\n"); while (dbus_connection_read_write_dispatch (main_remote_connection, -1)) { msg = dbus_connection_pop_message (main_remote_connection); if (NULL == msg) { fprintf (stderr, "Message == NULL\n"); continue; } else { fprintf (stderr, "Got Something... "); } if (dbus_message_is_method_call (msg, //DBusMessage * msg GNAURAL_DBUS_INTERFACE,//char * interface "GetBeatfreq"))//char * method { GetBeatfreq (msg, main_remote_connection); fprintf (stderr, "Running GetBeatfreq\n"); } else { fprintf (stderr, "Call not recognized\n"); } dbus_message_unref (msg); } fprintf (stderr, "Leaving wait for methodcall loop\n"); } ////////////////////////////////// void *sleep_for_awhile (void *args) { time_t t1; time_t t2; g_print ("Sleeping for 2 seconds\n"); time (&t1); sleep (1); time (&t2); g_print ("Slept for %d seconds\n", (int) (t2 - t1)); main_init_connection (); g_print ("Blocking forever\n"); main_check_for_methodcall (NULL); time (&t2); g_print ("Blocked for %d seconds\n", (int) (t2 - t1)); g_print ("Thread terminated naturally\n"); return NULL; } //////////////////////////////// int main (int argc, char *argv[]) { GError *error = NULL; GtkWidget *dialog = NULL; time (&main_startime); 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 ("g_thread_create failed:%s\n", error->message); return 1; } //this does not work with thread: 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) { g_free (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog))); } /* //this variety does work with 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; } _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list