From 3b078b20683da8fde7e291373e7cec0c3901cbac Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 00:15:20 +0000 Subject: Avoid a race condition when one PA instance gets HAL's ACLAdded message before the previous owner instance has given up access to the device, and thus the device is blocked git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1611 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-hal-detect.c | 62 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) (limited to 'src/modules/module-hal-detect.c') diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index 5dffea55..39d8a44a 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -540,10 +540,21 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo if (d->sink_name) { pa_sink *sink; - if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK, 0))) - if (pa_sink_suspend(sink, suspend) >= 0) - if (!suspend) + if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK, 0))) { + + int prev_suspended = pa_sink_get_state(sink) == PA_SINK_SUSPENDED; + + if (pa_sink_suspend(sink, suspend) >= 0) { + if (!suspend && prev_suspended) pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, PA_VOLUME_NORM, 0); + else if (suspend && !prev_suspended) { + DBusMessage *msg; + msg = dbus_message_new_signal(udi, "org.pulseaudio.Server", "DirtyGiveUpMessage"); + dbus_connection_send(pa_dbus_connection_get(u->connection), msg, NULL); + dbus_message_unref(msg); + } + } + } } if (d->source_name) { @@ -555,9 +566,46 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo } else if (!suspend) hal_device_add(u, udi); - } + } else if (dbus_message_is_signal(message, "org.pulseaudio.Server", "DirtyGiveUpMessage")) { + /* We use this message to avoid a dirty race condition when we + get an ACLAdded message before the previously owning PA + sever has closed the device. We can remove this as + soon as HAL learns frevoke() */ + + const char *udi; + struct device *d; + + pa_log_debug("Got dirty give up message, trying resume ..."); + + udi = dbus_message_get_path(message); + + if ((d = pa_hashmap_get(u->devices, udi))) { + + if (d->sink_name) { + pa_sink *sink; + + if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK, 0))) { + + int prev_suspended = pa_sink_get_state(sink) == PA_SINK_SUSPENDED; + + if (pa_sink_suspend(sink, 0) >= 0) + if (prev_suspended && !prev_suspended) + pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, PA_VOLUME_NORM, 0); + } + } + + if (d->source_name) { + pa_source *source; + + if ((source = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_SOURCE, 0))) + pa_source_suspend(source, 0); + } + + } else + /* Yes, we don't check the UDI for validity, but hopefully HAL will */ + hal_device_add(u, udi); } finish: @@ -673,6 +721,12 @@ int pa__init(pa_core *c, pa_module*m) { pa_log_error("Unable to subscribe to HAL ACL signals: %s: %s", error.name, error.message); goto fail; } + + dbus_bus_add_match(pa_dbus_connection_get(conn), "type='signal',interface='org.pulseaudio.Server'", &error); + if (dbus_error_is_set(&error)) { + pa_log_error("Unable to subscribe to PulseAudio signals: %s: %s", error.name, error.message); + goto fail; + } pa_log_info("Loaded %i modules.", n); -- cgit