[PATCH] config: if we can't connect to HAL, listen for a startup notification.

Peter Hutterer peter.hutterer at who-t.net
Wed Feb 4 22:00:27 PST 2009


On Thu, Feb 05, 2009 at 03:45:51PM +1000, Peter Hutterer wrote:
> If HAL isn't available when we try to connect, register a NameOwnerChanged
> handler and wait until HAL is available. This allows HAL to be started in
> parallel or after the server has started.

Eric pointed out that there's a time window between the server noticing that
HAL isn't up and registering for the signal. HAL may start up in that time and
we wouldn't notice.

I'll revise the patch, in the meantime I'd appreciate it if you could test
this one for correctness on the other bits.

> 
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
>  config/hal.c |   98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 files changed, 94 insertions(+), 4 deletions(-)
> 
> diff --git a/config/hal.c b/config/hal.c
> index 8dfbb07..c662562 100644
> --- a/config/hal.c
> +++ b/config/hal.c
> @@ -467,11 +467,10 @@ disconnect_hook(void *data)
>      info->system_bus = NULL;
>  }
>  
> -static void
> -connect_hook(DBusConnection *connection, void *data)
> +static BOOL
> +connect_and_register(DBusConnection *connection, struct config_hal_info *info)
>  {
>      DBusError error;
> -    struct config_hal_info *info = data;
>      char **devices;
>      int num_devices, i;
>  
> @@ -512,7 +511,7 @@ connect_hook(DBusConnection *connection, void *data)
>  
>      dbus_error_free(&error);
>  
> -    return;
> +    return TRUE;
>  
>  out_ctx2:
>      if (!libhal_ctx_shutdown(info->hal_ctx, &error))
> @@ -526,6 +525,97 @@ out_err:
>      info->hal_ctx = NULL;
>      info->system_bus = NULL;
>  
> +    return FALSE;
> +}
> +
> +
> +/**
> + * Handle NewOwnerChanged signals to deal with HAL startup at X server runtime.
> + *
> + * NewOwnerChanged is send once when HAL shuts down, and once again when it
> + * comes back up. Message has three arguments, first is the name
> + * (org.freedesktop.Hal), the second one is the old owner, third one is new
> + * owner.
> + */
> +static DBusHandlerResult
> +ownerchanged_handler(DBusConnection *connection, DBusMessage *message, void *data)
> +{
> +    int ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
> +
> +    if (dbus_message_is_signal(message,
> +                               "org.freedesktop.DBus",
> +                               "NameOwnerChanged")) {
> +        DBusError error;
> +        char *name, *old_owner, *new_owner;
> +
> +        dbus_error_init(&error);
> +        dbus_message_get_args(message, &error,
> +                              DBUS_TYPE_STRING, &name,
> +                              DBUS_TYPE_STRING, &old_owner,
> +                              DBUS_TYPE_STRING, &new_owner,
> +                              DBUS_TYPE_INVALID);
> +
> +        if (dbus_error_is_set(&error)) {
> +            ErrorF("[config/hal] failed to get NameOwnerChanged args: %s (%s)\n",
> +                   error.name, error.message);
> +        } else if (name && strcmp(name, "org.freedesktop.Hal") == 0) {
> +
> +            if (!old_owner || !strlen(old_owner)) {
> +                DebugF("[config/hal] HAL startup detected.\n");
> +                if (connect_and_register(connection, (struct config_hal_info*)data))
> +                    dbus_connection_unregister_object_path(connection,
> +                                                     "/org/freedesktop/DBus");
> +                else
> +                    ErrorF("[config/hal] Failed to connect to HAL bus.\n");
> +            }
> +
> +            ret = DBUS_HANDLER_RESULT_HANDLED;
> +        }
> +        dbus_error_free(&error);
> +    }
> +
> +    return ret;
> +}
> +
> +/**
> + * Register a handler for the NameOwnerChanged signal.
> + */
> +static void
> +listen_for_startup(DBusConnection *connection, void *data)
> +{
> +    DBusObjectPathVTable vtable = { .message_function = ownerchanged_handler, };
> +    DBusError error;
> +    const char MATCH_RULE[] = "sender='org.freedesktop.DBus',"
> +                              "interface='org.freedesktop.DBus',"
> +                              "type='signal',"
> +                              "path='/org/freedesktop/DBus',"
> +                              "member='NameOwnerChanged'";
> +
> +    dbus_error_init(&error);
> +    dbus_bus_add_match(connection, MATCH_RULE, &error);
> +    if (!dbus_error_is_set(&error)) {
> +        if (!dbus_connection_register_object_path(connection,
> +                                                  "/org/freedesktop/DBus",
> +                                                  &vtable,
> +                                                  data))
> +            ErrorF("[config/hal] cannot register object path.\n");
> +    } else {
> +        ErrorF("[config/hal] couldn't add match rule: %s (%s)\n", error.name,
> +                error.message);
> +        ErrorF("[config/hal] cannot detect a HAL startup.\n");
> +    }
> +
> +    dbus_error_free(&error);
> +}
> +
> +static void
> +connect_hook(DBusConnection *connection, void *data)
> +{
> +    struct config_hal_info *info = data;
> +
> +    if (!connect_and_register(connection, info))
> +        listen_for_startup(connection, data);
> +
>      return;
>  }
>  
> -- 
> 1.6.0.6
> 
> _______________________________________________
> xorg mailing list
> xorg at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/xorg
> 
> 
> !DSPAM:498a7d53293365876319797!
> 
Cheers,
  Peter



More information about the xorg mailing list