From 0ec4a7c40d36b9c25f3d2e3f82e2323c98077e55 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Wed, 25 Jun 2008 00:28:53 +0300 Subject: Replace streq with ca_streq MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marc-André Lureau Signed-off-by: Lennart Poettering --- src/alsa.c | 2 +- src/common.c | 6 +++--- src/dso.c | 2 +- src/macro.h | 2 +- src/null.c | 2 +- src/pulse.c | 2 +- src/sound-theme-spec.c | 14 +++++++------- 7 files changed, 15 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/alsa.c b/src/alsa.c index 14156f3..a1dea98 100644 --- a/src/alsa.c +++ b/src/alsa.c @@ -84,7 +84,7 @@ int driver_open(ca_context *c) { struct private *p; ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(!c->driver || streq(c->driver, "alsa"), CA_ERROR_NODRIVER); + ca_return_val_if_fail(!c->driver || ca_streq(c->driver, "alsa"), CA_ERROR_NODRIVER); ca_return_val_if_fail(!PRIVATE(c), CA_ERROR_STATE); if (!(c->private = p = ca_new0(struct private, 1))) diff --git a/src/common.c b/src/common.c index 71b887a..1e57e94 100644 --- a/src/common.c +++ b/src/common.c @@ -703,11 +703,11 @@ int ca_parse_cache_control(ca_cache_control_t *control, const char *c) { ca_return_val_if_fail(control, CA_ERROR_INVALID); ca_return_val_if_fail(c, CA_ERROR_INVALID); - if (streq(c, "never")) + if (ca_streq(c, "never")) *control = CA_CACHE_CONTROL_NEVER; - else if (streq(c, "permanent")) + else if (ca_streq(c, "permanent")) *control = CA_CACHE_CONTROL_PERMANENT; - else if (streq(c, "volatile")) + else if (ca_streq(c, "volatile")) *control = CA_CACHE_CONTROL_VOLATILE; else return CA_ERROR_INVALID; diff --git a/src/dso.c b/src/dso.c index 31db543..02eb672 100644 --- a/src/dso.c +++ b/src/dso.c @@ -106,7 +106,7 @@ static int lt_error_from_string(const char *t) { const struct lt_error_code *c; for (c = lt_error_codes; c->text; c++) - if (streq(t, c->text)) + if (ca_streq(t, c->text)) return c->code; return -1; diff --git a/src/macro.h b/src/macro.h index c57c922..4b9324f 100644 --- a/src/macro.h +++ b/src/macro.h @@ -245,6 +245,6 @@ typedef void (*ca_free_cb_t)(void *); #define PA_UINT32_TO_BE(x) PA_UINT32_SWAP(x) #endif -#define streq(a, b) (strcmp((a),(b)) == 0) +#define ca_streq(a, b) (strcmp((a),(b)) == 0) #endif diff --git a/src/null.c b/src/null.c index dd33808..2412786 100644 --- a/src/null.c +++ b/src/null.c @@ -30,7 +30,7 @@ int driver_open(ca_context *c) { ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(!c->driver || streq(c->driver, "null"), CA_ERROR_NODRIVER); + ca_return_val_if_fail(!c->driver || ca_streq(c->driver, "null"), CA_ERROR_NODRIVER); return CA_SUCCESS; } diff --git a/src/pulse.c b/src/pulse.c index 1d64c86..785c967 100644 --- a/src/pulse.c +++ b/src/pulse.c @@ -248,7 +248,7 @@ int driver_open(ca_context *c) { int ret; ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(!c->driver || streq(c->driver, "pulse"), CA_ERROR_NODRIVER); + ca_return_val_if_fail(!c->driver || ca_streq(c->driver, "pulse"), CA_ERROR_NODRIVER); ca_return_val_if_fail(!PRIVATE(c), CA_ERROR_STATE); if (!(c->private = p = ca_new0(struct private, 1))) diff --git a/src/sound-theme-spec.c b/src/sound-theme-spec.c index 02b8de2..8bea151 100644 --- a/src/sound-theme-spec.c +++ b/src/sound-theme-spec.c @@ -82,7 +82,7 @@ static ca_bool_t data_dir_matches(ca_data_dir *d, const char*output_profile) { /* We might want to add more elaborate matching here eventually */ - return streq(d->output_profile, output_profile); + return ca_streq(d->output_profile, output_profile); } static ca_data_dir* find_data_dir(ca_theme_data *t, const char *name) { @@ -92,7 +92,7 @@ static ca_data_dir* find_data_dir(ca_theme_data *t, const char *name) { ca_assert(name); for (d = t->data_dirs; d; d = d->next) - if (streq(d->name, name)) + if (ca_streq(d->name, name)) return d; return NULL; @@ -166,7 +166,7 @@ static int load_theme_path(ca_theme_data *t, const char *prefix, const char *nam if (!ln[0]) continue; - if (streq(ln, "[Sound Theme]")) { + if (ca_streq(ln, "[Sound Theme]")) { in_sound_theme_section = TRUE; current_data_dir = NULL; continue; @@ -243,7 +243,7 @@ static int load_theme_path(ca_theme_data *t, const char *prefix, const char *nam if (!strncmp(ln, "OutputProfile=", 14)) { - if (current_data_dir->output_profile && !streq(current_data_dir->output_profile, ln+14)) { + if (current_data_dir->output_profile && !ca_streq(current_data_dir->output_profile, ln+14)) { ret = CA_ERROR_CORRUPT; goto fail; } @@ -309,7 +309,7 @@ static int load_theme_dir(ca_theme_data *t, const char *name) { if ((ret = get_data_home(&e)) < 0) return ret; - if (streq(name, FALLBACK_THEME)) + if (ca_streq(name, FALLBACK_THEME)) t->loaded_fallback_theme = TRUE; if (e) { @@ -358,7 +358,7 @@ static int load_theme_data(ca_theme_data **_t, const char *name) { ca_return_val_if_fail(name, CA_ERROR_INVALID); if (*_t) - if (streq((*_t)->name, name)) + if (ca_streq((*_t)->name, name)) return CA_SUCCESS; if (!(t = ca_new0(ca_theme_data, 1))) @@ -520,7 +520,7 @@ static int find_sound_for_subname(ca_sound_file **f, ca_theme_data *t, const cha return ret; /* Then, fall back to stereo */ - if (!streq(profile, DEFAULT_OUTPUT_PROFILE)) + if (!ca_streq(profile, DEFAULT_OUTPUT_PROFILE)) if ((ret = find_sound_for_profile(f, t, name, locale, DEFAULT_OUTPUT_PROFILE)) != CA_ERROR_NOTFOUND) return ret; } -- cgit From 67a93bb292c91572b3745428ec04939e58eb349e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jun 2008 01:30:57 +0200 Subject: fix another s/streq/ca_streq/ --- src/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/common.c b/src/common.c index 1e57e94..260c461 100644 --- a/src/common.c +++ b/src/common.c @@ -532,12 +532,12 @@ int ca_context_play_full(ca_context *c, uint32_t id, ca_proplist *p, ca_finish_c ca_mutex_lock(c->props->mutex); if ((t = ca_proplist_gets_unlocked(c->props, CA_PROP_CANBERRA_ENABLE))) - enabled = !streq(t, "0"); + enabled = !ca_streq(t, "0"); ca_mutex_unlock(c->props->mutex); ca_mutex_lock(p->mutex); if ((t = ca_proplist_gets_unlocked(p, CA_PROP_CANBERRA_ENABLE))) - enabled = !streq(t, "0"); + enabled = !ca_streq(t, "0"); ca_mutex_unlock(p->mutex); ca_return_val_if_fail_unlock(enabled, CA_ERROR_DISABLED, c->mutex); -- cgit From b42c4ecf22cf23170ed223c5c2a42164def060fa Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jun 2008 01:31:16 +0200 Subject: remove a superfluous newline --- src/driver.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/driver.h b/src/driver.h index 4f56a30..06acf3c 100644 --- a/src/driver.h +++ b/src/driver.h @@ -33,5 +33,4 @@ int driver_play(ca_context *c, uint32_t id, ca_proplist *p, ca_finish_callback_t int driver_cancel(ca_context *c, uint32_t id); int driver_cache(ca_context *c, ca_proplist *p); - #endif -- cgit From 2fea8e406bdf975cff8a1b972170cdd3d6b7862a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jun 2008 01:31:46 +0200 Subject: remove a superfluous newline --- src/sound-theme-spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/sound-theme-spec.c b/src/sound-theme-spec.c index 8bea151..485acb3 100644 --- a/src/sound-theme-spec.c +++ b/src/sound-theme-spec.c @@ -638,7 +638,7 @@ static int find_sound_for_theme(ca_sound_file **f, ca_theme_data **t, const char /* First, try in the theme itself, and if that fails the fallback theme */ if ((ret = load_theme_data(t, theme)) == CA_ERROR_NOTFOUND) - if (!streq(theme, FALLBACK_THEME)) + if (!ca_streq(theme, FALLBACK_THEME)) ret = load_theme_data(t, FALLBACK_THEME); if (ret == CA_SUCCESS) -- cgit From da2c352f04de5b9c4f071a0f0ad57cb2cdd51eff Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jun 2008 01:33:14 +0200 Subject: export the driver_order as ca_driver_order --- src/driver-order.c | 39 +++++++++++++++++++++++++++++++++++++++ src/driver-order.h | 26 ++++++++++++++++++++++++++ src/dso.c | 14 ++------------ 3 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 src/driver-order.c create mode 100644 src/driver-order.h (limited to 'src') diff --git a/src/driver-order.c b/src/driver-order.c new file mode 100644 index 0000000..d97c0e1 --- /dev/null +++ b/src/driver-order.c @@ -0,0 +1,39 @@ +/*** + This file is part of libcanberra. + + Copyright 2008 Lennart Poettering + + libcanberra 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.1 of the + License, or (at your option) any later version. + + libcanberra 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with libcanberra. If not, If not, see + . +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "canberra.h" +#include "driver-order.h" + +const char* const ca_driver_order[] = { +#ifdef HAVE_PULSE + "pulse", +#endif +#ifdef HAVE_ALSA + "alsa", +#endif + /* ... */ + NULL +}; diff --git a/src/driver-order.h b/src/driver-order.h new file mode 100644 index 0000000..23e0783 --- /dev/null +++ b/src/driver-order.h @@ -0,0 +1,26 @@ +#ifndef foocanberradriverorderhfoo +#define foocanberradriverorderhfoo + +/*** + This file is part of libcanberra. + + Copyright 2008 Lennart Poettering + + libcanberra 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.1 of the + License, or (at your option) any later version. + + libcanberra 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with libcanberra. If not, If not, see + . +***/ + +extern const char* const ca_driver_order[]; + +#endif diff --git a/src/dso.c b/src/dso.c index 02eb672..aacec71 100644 --- a/src/dso.c +++ b/src/dso.c @@ -29,6 +29,7 @@ #include "driver.h" #include "common.h" #include "malloc.h" +#include "driver-order.h" struct private_dso { lt_dlhandle module; @@ -45,17 +46,6 @@ struct private_dso { #define PRIVATE_DSO(c) ((struct private_dso *) ((c)->private_dso)) -static const char* const driver_order[] = { -#ifdef HAVE_PULSE - "pulse", -#endif -#ifdef HAVE_ALSA - "alsa", -#endif - /* ... */ - NULL -}; - static int ca_error_from_lt_error(int code) { static const int table[] = { @@ -214,7 +204,7 @@ int driver_open(ca_context *c) { } else { const char *const * e; - for (e = driver_order; *e; e++) { + for (e = ca_driver_order; *e; e++) { if ((ret = try_open(c, *e)) == CA_SUCCESS) break; -- cgit From 5da54ef8eac90ae74ff75a23e3189a594b54424d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jun 2008 01:33:36 +0200 Subject: add a few missing asserts --- src/alsa.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/alsa.c b/src/alsa.c index a1dea98..15c34ed 100644 --- a/src/alsa.c +++ b/src/alsa.c @@ -180,6 +180,9 @@ int driver_change_props(ca_context *c, ca_proplist *changed, ca_proplist *merged } int driver_cache(ca_context *c, ca_proplist *proplist) { + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(proplist, CA_ERROR_INVALID); + return CA_ERROR_NOTSUPPORTED; } -- cgit From bf46953169f0882fc97310e1216f516e6df0d230 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jun 2008 01:34:42 +0200 Subject: add new multi driver, which hands of a play request to the first driver that wants to take it --- src/Makefile.am | 21 +++- src/multi.c | 320 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 340 insertions(+), 1 deletion(-) create mode 100644 src/multi.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 0f26587..74bf88c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,11 +64,30 @@ plugin_LTLIBRARIES = if BUILTIN_DSO libcanberra_la_SOURCES += \ - dso.c + dso.c \ + driver-order.c driver-order.h libcanberra_la_CFLAGS += \ $(LTDLINCL) libcanberra_la_LIBADD += \ $(LIBLTDL) + +plugin_LTLIBRARIES += \ + libcanberra-multi.la + +libcanberra_multi_la_SOURCES = \ + multi.c +libcanberra_multi_la_CFLAGS = \ + -Ddriver_open=multi_driver_open \ + -Ddriver_destroy=multi_driver_destroy \ + -Ddriver_change_device=multi_driver_change_device \ + -Ddriver_change_props=multi_driver_change_props \ + -Ddriver_play=multi_driver_play \ + -Ddriver_cancel=multi_driver_cancel \ + -Ddriver_cache=multi_driver_cache +libcanberra_multi_la_LIBADD = \ + libcanberra.la +libcanberra_multi_la_LDFLAGS = \ + -avoid-version -module -export-dynamic endif if HAVE_PULSE diff --git a/src/multi.c b/src/multi.c new file mode 100644 index 0000000..719da5f --- /dev/null +++ b/src/multi.c @@ -0,0 +1,320 @@ +/*** + This file is part of libcanberra. + + Copyright 2008 Lennart Poettering + + libcanberra 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.1 of the + License, or (at your option) any later version. + + libcanberra 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with libcanberra. If not, If not, see + . +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "driver.h" +#include "llist.h" +#include "malloc.h" +#include "common.h" +#include "driver-order.h" + +struct backend { + CA_LLIST_FIELDS(struct backend); + ca_context *context; +}; + +struct private { + ca_context *context; + CA_LLIST_HEAD(struct backend, backends); +}; + +#define PRIVATE(c) ((struct private *) ((c)->private)) + +static int add_backend(struct private *p, const char *name) { + struct backend *b; + int ret; + + ca_assert(p); + ca_assert(b); + + if (!(b = ca_new0(struct backend, 1))) + return CA_ERROR_OOM; + + if ((ret = ca_context_create(&b->context)) < 0) + goto fail; + + if ((ret = ca_context_change_props_full(b->context, p->context->props)) < 0) + goto fail; + + if ((ret = ca_context_set_driver(b->context, name)) < 0) + goto fail; + + if ((ret = ca_context_open(b->context)) < 0) + goto fail; + + CA_LLIST_PREPEND(struct backend, p->backends, b); + + return CA_SUCCESS; + +fail: + + if (b->context) + ca_context_destroy(b->context); + + ca_free(b); + + return ret; +} + +static int remove_backend(struct private *p, struct backend *b) { + int ret; + + ca_assert(p); + ca_assert(b); + + ret = ca_context_destroy(b->context); + CA_LLIST_REMOVE(struct backend, p->backends, b); + ca_free(b); + + return ret; +} + +int driver_open(ca_context *c) { + struct private *p; + int ret = CA_SUCCESS; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(!c->driver || ca_streq(c->driver, "multi"), CA_ERROR_NODRIVER); + ca_return_val_if_fail(!PRIVATE(c), CA_ERROR_STATE); + + if (!(c->private = p = ca_new0(struct private, 1))) + return CA_ERROR_OOM; + + p->context = c; + + if (c->driver) { + char *e, *k; + + if (!(e = ca_strdup(c->driver))) { + driver_destroy(c); + return CA_ERROR_OOM; + } + + k = e; + for (;;) { + size_t n; + ca_bool_t last; + + n = strcspn(k, ":"); + last = k[n] == 0; + k[n] = 0; + + if (n > 0) { + int r; + + r = add_backend(p, k); + + if (ret == CA_SUCCESS) + ret = r; + } + + if (last) + break; + + k += n+1 ; + } + + ca_free(e); + + } else { + + const char *const *e; + + for (e = ca_driver_order; *e; e++) { + int r; + + r = add_backend(p, *e); + + /* We return the error code of the first module that fails only */ + if (ret == CA_SUCCESS) + ret = r; + } + } + + if (!p->backends) { + driver_destroy(c); + return ret == CA_SUCCESS ? CA_ERROR_NODRIVER : ret; + } + + return CA_SUCCESS; +} + + +int driver_destroy(ca_context *c) { + int ret = CA_SUCCESS; + struct private *p; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + + p = PRIVATE(c); + + while (p->backends) { + int r; + + r = remove_backend(p, p->backends); + + if (ret == CA_SUCCESS) + ret = r; + } + + ca_free(p); + + c->private = NULL; + + return ret; +} + +int driver_change_device(ca_context *c, char *device) { + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + + return CA_ERROR_NOTSUPPORTED; +} + +int driver_change_props(ca_context *c, ca_proplist *changed, ca_proplist *merged) { + int ret = CA_SUCCESS; + struct private *p; + struct backend *b; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(changed, CA_ERROR_INVALID); + ca_return_val_if_fail(merged, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + + p = PRIVATE(c); + + for (b = p->backends; b; b = b->next) { + int r; + + r = ca_context_change_props_full(b->context, changed); + + /* We only return the first failure */ + if (ret == CA_SUCCESS) + ret = r; + } + + return ret; +} + +struct closure { + ca_context *context; + ca_finish_callback_t callback; + void *userdata; +}; + +static void call_closure(ca_context *c, uint32_t id, int error_code, void *userdata) { + struct closure *closure = userdata; + + closure->callback(closure->context, id, error_code, closure->userdata); + ca_free(closure); +} + +int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_callback_t cb, void *userdata) { + int ret = CA_SUCCESS; + struct private *p; + struct backend *b; + struct closure *closure; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(proplist, CA_ERROR_INVALID); + ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + + p = PRIVATE(c); + + if (cb) { + if (!(closure = ca_new(struct closure, 1))) + return CA_ERROR_OOM; + + closure->context = c; + closure->callback = cb; + closure->userdata = userdata; + } else + closure = NULL; + + /* The first backend that can play this, takes it */ + for (b = p->backends; b; b = b->next) { + int r; + + if ((r = ca_context_play_full(b->context, id, proplist, call_closure, closure)) == CA_SUCCESS) + return r; + + /* We only return the first failure */ + if (ret == CA_SUCCESS) + ret = r; + } + + ca_free(closure); + + return ret; +} + +int driver_cancel(ca_context *c, uint32_t id) { + int ret = CA_SUCCESS; + struct private *p; + struct backend *b; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + + p = PRIVATE(c); + + for (b = p->backends; b; b = b->next) { + int r; + + r = ca_context_cancel(b->context, id); + + /* We only return the first failure */ + if (ret == CA_SUCCESS) + ret = r; + } + + return ret; +} + +int driver_cache(ca_context *c, ca_proplist *proplist) { + int ret = CA_SUCCESS; + struct private *p; + struct backend *b; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(proplist, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + + p = PRIVATE(c); + + /* The first backend that can cache this, takes it */ + for (b = p->backends; b; b = b->next) { + int r; + + if ((r = ca_context_cache_full(b->context, proplist)) == CA_SUCCESS) + return r; + + /* We only return the first failure */ + if (ret == CA_SUCCESS) + ret = r; + } + + return ret; +} -- cgit From 409210f5b12b64f9cef06275bb5954ec8a261731 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jun 2008 01:38:02 +0200 Subject: only install callback if a cb was passed --- src/multi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/multi.c b/src/multi.c index 719da5f..e7db7f1 100644 --- a/src/multi.c +++ b/src/multi.c @@ -257,7 +257,7 @@ int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_cal for (b = p->backends; b; b = b->next) { int r; - if ((r = ca_context_play_full(b->context, id, proplist, call_closure, closure)) == CA_SUCCESS) + if ((r = ca_context_play_full(b->context, id, proplist, closure ? call_closure : NULL, closure)) == CA_SUCCESS) return r; /* We only return the first failure */ -- cgit From 38d9db9575547ac9354944bd307db752e37601f6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jun 2008 01:48:23 +0200 Subject: filter out recursive 'multi' invocations and duplicate entries in the backend list --- src/multi.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/multi.c b/src/multi.c index e7db7f1..f6448d6 100644 --- a/src/multi.c +++ b/src/multi.c @@ -47,6 +47,13 @@ static int add_backend(struct private *p, const char *name) { ca_assert(p); ca_assert(b); + if (ca_streq(name, "multi")) + return CA_ERROR_NOTAVAILABLE; + + for (b = p->backends; b; b = b->next) + if (ca_streq(b->context->driver, name)) + return CA_ERROR_NOTAVAILABLE; + if (!(b = ca_new0(struct backend, 1))) return CA_ERROR_OOM; -- cgit