Ticket #625: 0001-hal-detect-Add-logic-to-wait-for-hal-to-startup.patch

File 0001-hal-detect-Add-logic-to-wait-for-hal-to-startup.patch, 6.8 kB (added by rustyl, 3 years ago)

Proposed patch to fix the bug

  • src/modules/module-hal-detect.c

    From 09ef53aed06efec236f806b21ea823a4a80a9426 Mon Sep 17 00:00:00 2001
    From: Rusty Lynch <rusty.lynch@intel.com>
    Date: Sun, 9 Aug 2009 16:22:21 -0700
    Subject: [PATCH] hal-detect: Add logic to wait for hal to startup
    
    On fast booting system pulseaudio might startup before hal.
    ---
     src/modules/module-hal-detect.c |  143 ++++++++++++++++++++++++++++++---------
     1 files changed, 110 insertions(+), 33 deletions(-)
    
    diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c
    index b5b2aaf..5af5b30 100644
    a b  
    708708 
    709709    if (!libhal_ctx_init(hal_context, &error)) { 
    710710        pa_log_error("Couldn't connect to hald: %s: %s", error.name, error.message); 
     711        /* Attempting to free an invalid context will result in a SIGABRT */ 
     712        hal_context = NULL; 
    711713        goto fail; 
    712714    } 
    713715 
     
    722724    return NULL; 
    723725} 
    724726 
     727static pa_bool_t connect_and_register(DBusConnection *connection, void *data) 
     728{ 
     729    DBusError error; 
     730    struct userdata *u = (struct userdata *)data; 
     731 
     732    if (u->context) 
     733    return TRUE; 
     734 
     735    if (!(u->context = hal_context_new(pa_dbus_connection_get(u->connection)))) 
     736    return FALSE; 
     737 
     738    dbus_error_init(&error); 
     739 
     740    hal_device_add_all(u); 
     741 
     742    libhal_ctx_set_user_data(u->context, u); 
     743    libhal_ctx_set_device_added(u->context, device_added_cb); 
     744    libhal_ctx_set_device_removed(u->context, device_removed_cb); 
     745    libhal_ctx_set_device_new_capability(u->context, new_capability_cb); 
     746    libhal_ctx_set_device_lost_capability(u->context, lost_capability_cb); 
     747 
     748    if (!libhal_device_property_watch_all(u->context, &error)) { 
     749        pa_log_error("Error monitoring device list: %s: %s", error.name, error.message); 
     750        goto fail; 
     751    } 
     752 
     753    if (!dbus_connection_add_filter(pa_dbus_connection_get (u->connection), filter_cb, u, NULL)) { 
     754        pa_log_error("Failed to add filter function"); 
     755        goto fail; 
     756    } 
     757 
     758    if (pa_dbus_add_matches( 
     759                pa_dbus_connection_get (u->connection), &error, 
     760                "type='signal',sender='org.freedesktop.Hal',interface='org.freedesktop.Hal.Device.AccessControl',member='ACLAdded'", 
     761                "type='signal',sender='org.freedesktop.Hal',interface='org.freedesktop.Hal.Device.AccessControl',member='ACLRemoved'", 
     762                "type='signal',interface='org.pulseaudio.Server',member='DirtyGiveUpMessage'", NULL) < 0) { 
     763        pa_log_error("Unable to subscribe to HAL ACL signals: %s: %s", error.name, error.message); 
     764        goto fail; 
     765    } 
     766 
     767    return TRUE; 
     768 
     769fail: 
     770    dbus_error_free(&error); 
     771    return FALSE; 
     772} 
     773 
     774static DBusHandlerResult ownerchanged_handler(DBusConnection *connection, DBusMessage *message, void *data) 
     775{ 
     776    int ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 
     777 
     778    if (dbus_message_is_signal(message, "org.freedesktop.DBus", "NameOwnerChanged")) { 
     779        DBusError error; 
     780        char *name, *old_owner, *new_owner; 
     781 
     782        dbus_error_init(&error); 
     783        dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old_owner, DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_INVALID); 
     784 
     785        if (dbus_error_is_set(&error)) { 
     786            pa_log_error("failed to get NameOwnerChanged args: %s (%s)", error.name, error.message); 
     787        } else if (name && strcmp (name, "org.freedesktop.Hal") == 0) { 
     788            if (!old_owner || !strlen (old_owner)) { 
     789                pa_log_warn ("HAL startup detected."); 
     790                if (connect_and_register (connection, data)) 
     791                    dbus_connection_unregister_object_path (connection, "/org/freedesktop/DBus"); 
     792                else 
     793                    pa_log_error ("Failed to connect to HAL bus."); 
     794            } 
     795 
     796            ret = DBUS_HANDLER_RESULT_HANDLED; 
     797        } 
     798        dbus_error_free(&error); 
     799    } 
     800 
     801    return ret; 
     802} 
     803 
     804static pa_bool_t listen_for_startup(DBusConnection *connection, void *data) 
     805{ 
     806    DBusObjectPathVTable vtable = { .message_function = ownerchanged_handler, }; 
     807    DBusError error; 
     808    const char MATCH_RULE[] = "sender='org.freedesktop.DBus'," 
     809        "interface='org.freedesktop.DBus'," 
     810        "type='signal'," 
     811        "path='/org/freedesktop/DBus'," 
     812        "member='NameOwnerChanged'"; 
     813    pa_bool_t rc = FALSE; 
     814 
     815    dbus_error_init(&error); 
     816    dbus_bus_add_match(connection, MATCH_RULE, &error); 
     817    if (!dbus_error_is_set(&error)) { 
     818        if (dbus_connection_register_object_path (connection, "/org/freedesktop/DBus", &vtable, data)) 
     819            rc = TRUE; 
     820        else 
     821            pa_log_error("cannot register object path.\n"); 
     822    } else { 
     823        pa_log_error("Couldn't add match rule: %s (%s)\n", error.name, error.message); 
     824        pa_log_error("Cannot detect a HAL startup."); 
     825    } 
     826 
     827    dbus_error_free(&error); 
     828 
     829    return rc; 
     830} 
     831 
    725832int pa__init(pa_module*m) { 
    726833    DBusError error; 
    727834    struct userdata *u = NULL; 
    728     int n = 0; 
    729835    pa_modargs *ma; 
    730836    const char *api; 
    731837 
     
    783889        goto fail; 
    784890    } 
    785891 
    786     if (!(u->context = hal_context_new(pa_dbus_connection_get(u->connection)))) { 
    787         /* pa_hal_context_new() logs appropriate errors */ 
    788         goto fail; 
     892    if (!connect_and_register(pa_dbus_connection_get(u->connection), u) && 
     893    !listen_for_startup(pa_dbus_connection_get(u->connection), u)) { 
     894    goto fail; 
    789895    } 
    790896 
    791     n = hal_device_add_all(u); 
    792  
    793     libhal_ctx_set_user_data(u->context, u); 
    794     libhal_ctx_set_device_added(u->context, device_added_cb); 
    795     libhal_ctx_set_device_removed(u->context, device_removed_cb); 
    796     libhal_ctx_set_device_new_capability(u->context, new_capability_cb); 
    797     libhal_ctx_set_device_lost_capability(u->context, lost_capability_cb); 
    798  
    799     if (!libhal_device_property_watch_all(u->context, &error)) { 
    800         pa_log_error("Error monitoring device list: %s: %s", error.name, error.message); 
    801         goto fail; 
    802     } 
    803  
    804     if (!dbus_connection_add_filter(pa_dbus_connection_get(u->connection), filter_cb, u, NULL)) { 
    805         pa_log_error("Failed to add filter function"); 
    806         goto fail; 
    807     } 
    808  
    809     if (pa_dbus_add_matches( 
    810                 pa_dbus_connection_get(u->connection), &error, 
    811                 "type='signal',sender='org.freedesktop.Hal',interface='org.freedesktop.Hal.Device.AccessControl',member='ACLAdded'", 
    812                 "type='signal',sender='org.freedesktop.Hal',interface='org.freedesktop.Hal.Device.AccessControl',member='ACLRemoved'", 
    813                 "type='signal',interface='org.pulseaudio.Server',member='DirtyGiveUpMessage'", NULL) < 0) { 
    814         pa_log_error("Unable to subscribe to HAL ACL signals: %s: %s", error.name, error.message); 
    815         goto fail; 
    816     } 
    817  
    818     pa_log_info("Loaded %i modules.", n); 
    819  
    820897    pa_modargs_free(ma); 
    821898 
    822899    return 0;