From f349e6b8c50ea6faa48c8261198cf1b07bf59a79 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sun, 13 Feb 2005 17:16:25 +0000 Subject: 2005-02-13 Havoc Pennington * dbus/dbus-object-tree.c (handle_default_introspect_and_unlock): fix a double-unlock * dbus/dbus-connection.c (_dbus_connection_detach_pending_call_unlocked): add this Initial semi-correct pass through to fix thread locking; there are still some issues with the condition variable paths I'm pretty sure * dbus/dbus-server.c: add a mutex on DBusServer and appropriate lock/unlock calls * dbus/dbus-connection.c (_dbus_connection_do_iteration_unlocked): rename to add _unlocked (struct DBusConnection): move "dispatch_acquired" and "io_path_acquired" to use only one bit each. (CONNECTION_LOCK, CONNECTION_UNLOCK): add checks with !DBUS_DISABLE_CHECKS (dbus_connection_set_watch_functions): hacky fix to reentrancy (_dbus_connection_add_watch, _dbus_connection_remove_watch) (_dbus_connection_toggle_watch, _dbus_connection_add_timeout) (_dbus_connection_remove_timeout) (_dbus_connection_toggle_timeout): drop lock when calling out to user functions; done in a hacky/bad way. (_dbus_connection_send_and_unlock): add a missing unlock (_dbus_connection_block_for_reply): add a missing unlock * dbus/dbus-transport.c (_dbus_transport_get_is_authenticated): drop lock in a hacky probably unsafe way to call out to user function --- tools/Makefile.am | 4 +- tools/dbus-tree-view.c | 2 + tools/dbus-viewer.c | 189 ++++++++++++++++++++++++++++++++----------------- 3 files changed, 127 insertions(+), 68 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index b6747b0f..7cc6cadf 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_GLIB_CFLAGS) $(DBUS_X_CFLAGS) $(DBUS_GTK_CFLAGS) -DDBUS_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" +INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_GLIB_CFLAGS) $(DBUS_X_CFLAGS) $(DBUS_GTK_THREADS_CFLAGS) -DDBUS_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" if HAVE_GLIB GLIB_TOOLS=dbus-monitor @@ -40,7 +40,7 @@ dbus_viewer_SOURCES= \ dbus_send_LDADD= $(top_builddir)/dbus/libdbus-1.la dbus_monitor_LDADD= $(top_builddir)/glib/libdbus-glib-1.la dbus_launch_LDADD= $(DBUS_X_LIBS) -dbus_viewer_LDADD= $(DBUS_GLIB_TOOL_LIBS) $(top_builddir)/glib/libdbus-gtool.la $(DBUS_GTK_LIBS) +dbus_viewer_LDADD= $(DBUS_GLIB_TOOL_LIBS) $(top_builddir)/glib/libdbus-gtool.la $(DBUS_GTK_THREADS_LIBS) man_MANS = dbus-send.1 dbus-monitor.1 dbus-launch.1 dbus-cleanup-sockets.1 EXTRA_DIST = $(man_MANS) diff --git a/tools/dbus-tree-view.c b/tools/dbus-tree-view.c index f9342ee9..7f143ab9 100644 --- a/tools/dbus-tree-view.c +++ b/tools/dbus-tree-view.c @@ -333,6 +333,8 @@ info_set_func_text (GtkTreeViewColumn *tree_column, break; case INFO_TYPE_PROPERTY: g_string_append (str, "property"); + g_string_append_printf (str, " %s", + type_to_string (property_info_get_type ((PropertyInfo*)info))); break; case INFO_TYPE_ARG: g_string_append_printf (str, "arg %s", diff --git a/tools/dbus-viewer.c b/tools/dbus-viewer.c index c3903097..338b8e05 100644 --- a/tools/dbus-viewer.c +++ b/tools/dbus-viewer.c @@ -82,6 +82,54 @@ show_error_dialog (GtkWindow *transient_parent, } } +typedef struct +{ + DBusGConnection *connection; + + GtkWidget *window; + GtkWidget *treeview; + GtkWidget *name_menu; + + GtkTreeModel *names_model; + + GtkWidget *error_dialog; + +} TreeWindow; + + +static void +tree_window_set_node (TreeWindow *w, + NodeInfo *node) +{ + char **path; + const char *name; + + name = node_info_get_name (node); + if (name == NULL || + name[0] != '/') + { + g_printerr (_("Assuming root node is at path /, since no absolute path is specified")); + name = "/"; + } + + path = _dbus_gutils_split_path (name); + + dbus_tree_view_update (GTK_TREE_VIEW (w->treeview), + (const char**) path, + node); + + g_strfreev (path); +} + +typedef struct +{ + DBusGConnection *connection; + char *service_name; + GError *error; + NodeInfo *node; + TreeWindow *window; /* Not touched from child thread */ +} LoadFromServiceData; + static gboolean load_child_nodes (const char *service_name, NodeInfo *parent, @@ -179,16 +227,52 @@ load_child_nodes (const char *service_name, return TRUE; } -static NodeInfo* -load_from_service (DBusGConnection *connection, - const char *service_name, - GError **error) +static gboolean +load_from_service_complete_idle (void *data) { - DBusGProxy *root_proxy; + /* Called in main thread */ + GThread *thread = data; + LoadFromServiceData *d; + NodeInfo *node; + + d = g_thread_join (thread); + + node = d->node; + + if (d->error) + { + g_assert (d->node == NULL); + show_error_dialog (GTK_WINDOW (d->window->window), &d->window->error_dialog, + _("Unable to load \"%s\": %s\n"), + d->service_name, d->error->message); + g_error_free (d->error); + } + else + { + g_assert (d->error == NULL); + + tree_window_set_node (d->window, node); + node_info_unref (node); + } + + g_free (d->service_name); + dbus_g_connection_unref (d->connection); + g_free (d); + + return FALSE; +} + +static void* +load_from_service_thread_func (void *thread_data) +{ + DBusGProxy *root_proxy; DBusGPendingCall *call; const char *data; NodeInfo *node; GString *path; + LoadFromServiceData *lfsd; + + lfsd = thread_data; node = NULL; call = NULL; @@ -196,22 +280,22 @@ load_from_service (DBusGConnection *connection, #if 1 /* this will end up autolaunching the service when we introspect it */ - root_proxy = dbus_g_proxy_new_for_name (connection, - service_name, + root_proxy = dbus_g_proxy_new_for_name (lfsd->connection, + lfsd->service_name, "/", DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE); g_assert (root_proxy != NULL); #else /* this will be an error if the service doesn't exist */ - root_proxy = dbus_g_proxy_new_for_name_owner (connection, - service_name, + root_proxy = dbus_g_proxy_new_for_name_owner (lfsd->connection, + lfsd->service_name, "/", DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE, - error); + &lfsd->error); if (root_proxy == NULL) { - g_printerr ("Failed to get owner of '%s'\n", service_name); - return NULL; + g_printerr ("Failed to get owner of '%s'\n", lfsd->service_name); + return lfsd->data; } #endif @@ -219,7 +303,7 @@ load_from_service (DBusGConnection *connection, DBUS_TYPE_INVALID); data = NULL; - if (!dbus_g_proxy_end_call (root_proxy, call, error, DBUS_TYPE_STRING, &data, + if (!dbus_g_proxy_end_call (root_proxy, call, &lfsd->error, DBUS_TYPE_STRING, &data, DBUS_TYPE_INVALID)) { g_printerr ("Failed to Introspect() %s\n", @@ -227,7 +311,7 @@ load_from_service (DBusGConnection *connection, goto out; } - node = description_load_from_string (data, -1, error); + node = description_load_from_string (data, -1, &lfsd->error); /* g_print ("%s\n", data); */ @@ -239,7 +323,7 @@ load_from_service (DBusGConnection *connection, path = g_string_new ("/"); if (!load_child_nodes (dbus_g_proxy_get_bus_name (root_proxy), - node, path, error)) + node, path, &lfsd->error)) { node_info_unref (node); node = NULL; @@ -254,70 +338,40 @@ load_from_service (DBusGConnection *connection, if (path) g_string_free (path, TRUE); - - return node; -} -typedef struct -{ - DBusGConnection *connection; - - GtkWidget *window; - GtkWidget *treeview; - GtkWidget *name_menu; - - GtkTreeModel *names_model; + lfsd->node = node; + g_assert (lfsd->node || lfsd->error); + g_assert (lfsd->node == NULL || lfsd->error == NULL); - GtkWidget *error_dialog; + /* Add idle to main thread that will join us back */ + g_idle_add (load_from_service_complete_idle, g_thread_self ()); -} TreeWindow; + return lfsd; +} static void -tree_window_set_node (TreeWindow *w, - NodeInfo *node) +start_load_from_service (TreeWindow *w, + DBusGConnection *connection, + const char *service_name) { - char **path; - const char *name; + LoadFromServiceData *d; - name = node_info_get_name (node); - if (name == NULL || - name[0] != '/') - { - g_printerr (_("Assuming root node is at path /, since no absolute path is specified")); - name = "/"; - } - - path = _dbus_gutils_split_path (name); + d = g_new0 (LoadFromServiceData, 1); - dbus_tree_view_update (GTK_TREE_VIEW (w->treeview), - (const char**) path, - node); - - g_strfreev (path); + d->connection = dbus_g_connection_ref (connection); + d->service_name = g_strdup (service_name); + d->error = NULL; + d->node = NULL; + d->window = w; + + g_thread_create (load_from_service_thread_func, d, TRUE, NULL); } static void tree_window_set_service (TreeWindow *w, const char *service_name) { - GError *error; - NodeInfo *node; - - error = NULL; - node = load_from_service (w->connection, service_name, &error); - if (node == NULL) - { - g_assert (error != NULL); - show_error_dialog (GTK_WINDOW (w->window), &w->error_dialog, - _("Unable to load \"%s\": %s\n"), - service_name, error->message); - g_error_free (error); - return; - } - - tree_window_set_node (w, node); - - node_info_unref (node); + start_load_from_service (w, w->connection, service_name); } static void @@ -444,10 +498,13 @@ main (int argc, char **argv) DBusGConnection *connection; GError *error; GtkTreeModel *names_model; + + g_thread_init (NULL); + dbus_g_thread_init (); bindtextdomain (GETTEXT_PACKAGE, DBUS_LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); + textdomain (GETTEXT_PACKAGE); gtk_init (&argc, &argv); -- cgit