From c341010304064c9a6ae13fab15c7fa7883acaeeb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 24 Feb 2009 06:13:39 +0100 Subject: implement device reservation scheme --- src/modules/reserve-wrap.c | 158 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 src/modules/reserve-wrap.c (limited to 'src/modules/reserve-wrap.c') diff --git a/src/modules/reserve-wrap.c b/src/modules/reserve-wrap.c new file mode 100644 index 00000000..df2861f5 --- /dev/null +++ b/src/modules/reserve-wrap.c @@ -0,0 +1,158 @@ +/*** + This file is part of PulseAudio. + + Copyright 2009 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include + +#include + +#include "reserve.h" +#include "reserve-wrap.h" + +struct pa_reserve_wrapper { + PA_REFCNT_DECLARE; + pa_core *core; + pa_dbus_connection *connection; + pa_hook hook; + struct rd_device *device; + char *shared_name; +}; + +static void reserve_wrapper_free(pa_reserve_wrapper *r) { + pa_assert(r); + + if (r->device) + rd_release(r->device); + + pa_hook_done(&r->hook); + + if (r->connection) + pa_dbus_connection_unref(r->connection); + + if (r->shared_name) { + pa_assert_se(pa_shared_remove(r->core, r->shared_name) >= 0); + pa_xfree(r->shared_name); + } + + pa_xfree(r); +} + +static int request_cb(rd_device *d, int forced) { + pa_reserve_wrapper *r; + int k; + + pa_assert(d); + pa_assert_se(r = rd_get_userdata(d)); + pa_assert(PA_REFCNT_VALUE(r) >= 1); + + PA_REFCNT_INC(r); + + k = pa_hook_fire(&r->hook, PA_INT_TO_PTR(forced)); + pa_log_debug("Device unlock has been requested and %s.", k < 0 ? "failed" : "succeeded"); + + pa_reserve_wrapper_unref(r); + + return k < 0 ? -1 : 1; +} + +pa_reserve_wrapper* pa_reserve_wrapper_get(pa_core *c, const char *device_name) { + pa_reserve_wrapper *r; + DBusError error; + int k; + char *t; + + dbus_error_init(&error); + + pa_assert(c); + pa_assert(device_name); + + t = pa_sprintf_malloc("reserve-wrapper@%s", device_name); + + if ((r = pa_shared_get(c, t))) { + pa_xfree(t); + + pa_assert(PA_REFCNT_VALUE(r) >= 1); + PA_REFCNT_INC(r); + + return r; + } + + r = pa_xnew0(pa_reserve_wrapper, 1); + PA_REFCNT_INIT(r); + r->core = c; + pa_hook_init(&r->hook, r); + r->shared_name = t; + + pa_assert_se(pa_shared_set(c, r->shared_name, r) >= 0); + + if (!(r->connection = pa_dbus_bus_get(c, DBUS_BUS_SESSION, &error)) || dbus_error_is_set(&error)) { + pa_log_error("Unable to contact D-Bus session bus: %s: %s", error.name, error.message); + goto fail; + } + + if ((k = rd_acquire( + &r->device, + pa_dbus_connection_get(r->connection), + device_name, + _("PulseAudio Sound Server"), + 0, + request_cb, + &error)) < 0) { + + pa_log_error("Failed to acquire reservation lock on device '%s': %s", device_name, pa_cstrerror(-k)); + goto fail; + } + + pa_log_debug("Successfully acquired reservation lock on device '%s'", device_name); + + rd_set_userdata(r->device, r); + + return r; + +fail: + reserve_wrapper_free(r); + return NULL; +} + +void pa_reserve_wrapper_unref(pa_reserve_wrapper *r) { + pa_assert(r); + pa_assert(PA_REFCNT_VALUE(r) >= 1); + + if (PA_REFCNT_DEC(r) > 0) + return; + + reserve_wrapper_free(r); +} + +pa_hook* pa_reserve_wrapper_hook(pa_reserve_wrapper *r) { + pa_assert(r); + pa_assert(PA_REFCNT_VALUE(r) >= 1); + + return &r->hook; +} -- cgit