|
|
57da029 |
From 9bd9e83179e863c8bd25da423d6c69f57c3317ba Mon Sep 17 00:00:00 2001
|
|
|
57da029 |
From: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
57da029 |
Date: Wed, 4 Feb 2009 11:50:18 +1000
|
|
|
57da029 |
Subject: [PATCH] config: if we can't connect to HAL, listen for a startup notification.
|
|
|
57da029 |
|
|
|
57da029 |
If HAL isn't available when we try to connect, the registered NameOwnerChanged
|
|
|
57da029 |
signal handler waits until HAL is available. Once we connected to HAL, we
|
|
|
57da029 |
unregister the signal handler again.
|
|
|
57da029 |
This allows HAL to be started in parallel or after the server has started.
|
|
|
57da029 |
|
|
|
57da029 |
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
57da029 |
---
|
|
|
57da029 |
config/hal.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
|
|
|
57da029 |
1 files changed, 105 insertions(+), 6 deletions(-)
|
|
|
57da029 |
|
|
|
57da029 |
diff --git a/config/hal.c b/config/hal.c
|
|
|
57da029 |
index 8dfbb07..36fa839 100644
|
|
|
57da029 |
--- a/config/hal.c
|
|
|
57da029 |
+++ b/config/hal.c
|
|
|
57da029 |
@@ -467,11 +467,10 @@ disconnect_hook(void *data)
|
|
|
57da029 |
info->system_bus = NULL;
|
|
|
57da029 |
}
|
|
|
57da029 |
|
|
|
57da029 |
-static void
|
|
|
57da029 |
-connect_hook(DBusConnection *connection, void *data)
|
|
|
57da029 |
+static BOOL
|
|
|
57da029 |
+connect_and_register(DBusConnection *connection, struct config_hal_info *info)
|
|
|
57da029 |
{
|
|
|
57da029 |
DBusError error;
|
|
|
57da029 |
- struct config_hal_info *info = data;
|
|
|
57da029 |
char **devices;
|
|
|
57da029 |
int num_devices, i;
|
|
|
57da029 |
|
|
|
57da029 |
@@ -479,8 +478,10 @@ connect_hook(DBusConnection *connection, void *data)
|
|
|
57da029 |
|
|
|
57da029 |
dbus_error_init(&error);
|
|
|
57da029 |
|
|
|
57da029 |
- if (!info->hal_ctx)
|
|
|
57da029 |
- info->hal_ctx = libhal_ctx_new();
|
|
|
57da029 |
+ if (info->hal_ctx)
|
|
|
57da029 |
+ return TRUE; /* already registered, pretend we did something */
|
|
|
57da029 |
+
|
|
|
57da029 |
+ info->hal_ctx = libhal_ctx_new();
|
|
|
57da029 |
if (!info->hal_ctx) {
|
|
|
57da029 |
LogMessage(X_ERROR, "config/hal: couldn't create HAL context\n");
|
|
|
57da029 |
goto out_err;
|
|
|
57da029 |
@@ -512,7 +513,7 @@ connect_hook(DBusConnection *connection, void *data)
|
|
|
57da029 |
|
|
|
57da029 |
dbus_error_free(&error);
|
|
|
57da029 |
|
|
|
57da029 |
- return;
|
|
|
57da029 |
+ return TRUE;
|
|
|
57da029 |
|
|
|
57da029 |
out_ctx2:
|
|
|
57da029 |
if (!libhal_ctx_shutdown(info->hal_ctx, &error))
|
|
|
57da029 |
@@ -526,6 +527,104 @@ out_err:
|
|
|
57da029 |
info->hal_ctx = NULL;
|
|
|
57da029 |
info->system_bus = NULL;
|
|
|
57da029 |
|
|
|
57da029 |
+ return FALSE;
|
|
|
57da029 |
+}
|
|
|
57da029 |
+
|
|
|
57da029 |
+
|
|
|
57da029 |
+/**
|
|
|
57da029 |
+ * Handle NewOwnerChanged signals to deal with HAL startup at X server runtime.
|
|
|
57da029 |
+ *
|
|
|
57da029 |
+ * NewOwnerChanged is send once when HAL shuts down, and once again when it
|
|
|
57da029 |
+ * comes back up. Message has three arguments, first is the name
|
|
|
57da029 |
+ * (org.freedesktop.Hal), the second one is the old owner, third one is new
|
|
|
57da029 |
+ * owner.
|
|
|
57da029 |
+ */
|
|
|
57da029 |
+static DBusHandlerResult
|
|
|
57da029 |
+ownerchanged_handler(DBusConnection *connection, DBusMessage *message, void *data)
|
|
|
57da029 |
+{
|
|
|
57da029 |
+ int ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
|
|
57da029 |
+
|
|
|
57da029 |
+ if (dbus_message_is_signal(message,
|
|
|
57da029 |
+ "org.freedesktop.DBus",
|
|
|
57da029 |
+ "NameOwnerChanged")) {
|
|
|
57da029 |
+ DBusError error;
|
|
|
57da029 |
+ char *name, *old_owner, *new_owner;
|
|
|
57da029 |
+
|
|
|
57da029 |
+ dbus_error_init(&error);
|
|
|
57da029 |
+ dbus_message_get_args(message, &error,
|
|
|
57da029 |
+ DBUS_TYPE_STRING, &name,
|
|
|
57da029 |
+ DBUS_TYPE_STRING, &old_owner,
|
|
|
57da029 |
+ DBUS_TYPE_STRING, &new_owner,
|
|
|
57da029 |
+ DBUS_TYPE_INVALID);
|
|
|
57da029 |
+
|
|
|
57da029 |
+ if (dbus_error_is_set(&error)) {
|
|
|
57da029 |
+ ErrorF("[config/hal] failed to get NameOwnerChanged args: %s (%s)\n",
|
|
|
57da029 |
+ error.name, error.message);
|
|
|
57da029 |
+ } else if (name && strcmp(name, "org.freedesktop.Hal") == 0) {
|
|
|
57da029 |
+
|
|
|
57da029 |
+ if (!old_owner || !strlen(old_owner)) {
|
|
|
57da029 |
+ DebugF("[config/hal] HAL startup detected.\n");
|
|
|
57da029 |
+ if (connect_and_register(connection, (struct config_hal_info*)data))
|
|
|
57da029 |
+ dbus_connection_unregister_object_path(connection,
|
|
|
57da029 |
+ "/org/freedesktop/DBus");
|
|
|
57da029 |
+ else
|
|
|
57da029 |
+ ErrorF("[config/hal] Failed to connect to HAL bus.\n");
|
|
|
57da029 |
+ }
|
|
|
57da029 |
+
|
|
|
57da029 |
+ ret = DBUS_HANDLER_RESULT_HANDLED;
|
|
|
57da029 |
+ }
|
|
|
57da029 |
+ dbus_error_free(&error);
|
|
|
57da029 |
+ }
|
|
|
57da029 |
+
|
|
|
57da029 |
+ return ret;
|
|
|
57da029 |
+}
|
|
|
57da029 |
+
|
|
|
57da029 |
+/**
|
|
|
57da029 |
+ * Register a handler for the NameOwnerChanged signal.
|
|
|
57da029 |
+ */
|
|
|
57da029 |
+static BOOL
|
|
|
57da029 |
+listen_for_startup(DBusConnection *connection, void *data)
|
|
|
57da029 |
+{
|
|
|
57da029 |
+ DBusObjectPathVTable vtable = { .message_function = ownerchanged_handler, };
|
|
|
57da029 |
+ DBusError error;
|
|
|
57da029 |
+ const char MATCH_RULE[] = "sender='org.freedesktop.DBus',"
|
|
|
57da029 |
+ "interface='org.freedesktop.DBus',"
|
|
|
57da029 |
+ "type='signal',"
|
|
|
57da029 |
+ "path='/org/freedesktop/DBus',"
|
|
|
57da029 |
+ "member='NameOwnerChanged'";
|
|
|
57da029 |
+ int rc = FALSE;
|
|
|
57da029 |
+
|
|
|
57da029 |
+ dbus_error_init(&error);
|
|
|
57da029 |
+ dbus_bus_add_match(connection, MATCH_RULE, &error);
|
|
|
57da029 |
+ if (!dbus_error_is_set(&error)) {
|
|
|
57da029 |
+ if (dbus_connection_register_object_path(connection,
|
|
|
57da029 |
+ "/org/freedesktop/DBus",
|
|
|
57da029 |
+ &vtable,
|
|
|
57da029 |
+ data))
|
|
|
57da029 |
+ rc = TRUE;
|
|
|
57da029 |
+ else
|
|
|
57da029 |
+ ErrorF("[config/hal] cannot register object path.\n");
|
|
|
57da029 |
+ } else {
|
|
|
57da029 |
+ ErrorF("[config/hal] couldn't add match rule: %s (%s)\n", error.name,
|
|
|
57da029 |
+ error.message);
|
|
|
57da029 |
+ ErrorF("[config/hal] cannot detect a HAL startup.\n");
|
|
|
57da029 |
+ }
|
|
|
57da029 |
+
|
|
|
57da029 |
+ dbus_error_free(&error);
|
|
|
57da029 |
+
|
|
|
57da029 |
+ return rc;
|
|
|
57da029 |
+}
|
|
|
57da029 |
+
|
|
|
57da029 |
+static void
|
|
|
57da029 |
+connect_hook(DBusConnection *connection, void *data)
|
|
|
57da029 |
+{
|
|
|
57da029 |
+ struct config_hal_info *info = data;
|
|
|
57da029 |
+
|
|
|
57da029 |
+ if (listen_for_startup(connection, data) &&
|
|
|
57da029 |
+ connect_and_register(connection, info))
|
|
|
57da029 |
+ dbus_connection_unregister_object_path(connection,
|
|
|
57da029 |
+ "/org/freedesktop/DBus");
|
|
|
57da029 |
+
|
|
|
57da029 |
return;
|
|
|
57da029 |
}
|
|
|
57da029 |
|
|
|
57da029 |
--
|
|
|
57da029 |
1.6.0.6
|
|
|
57da029 |
|