summaryrefslogtreecommitdiffstats
path: root/tools/dbus-viewer.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2005-02-13 17:16:25 +0000
committerHavoc Pennington <hp@redhat.com>2005-02-13 17:16:25 +0000
commitf349e6b8c50ea6faa48c8261198cf1b07bf59a79 (patch)
tree80661925d7864c5772e3c5999c131a068ea549e4 /tools/dbus-viewer.c
parent970be5fda36ea575973a9e7f25389e2ef173b940 (diff)
2005-02-13 Havoc Pennington <hp@redhat.com>
* 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
Diffstat (limited to 'tools/dbus-viewer.c')
-rw-r--r--tools/dbus-viewer.c189
1 files changed, 123 insertions, 66 deletions
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);