From 5ccf4145bcf1760d30962c32f0f4749047c6cae8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 16 Feb 2006 23:13:27 +0000 Subject: * rename polypcore/subscribe.[ch] to polypcore/core-subscribe.[ch] to avoid confusion with polyp/subscribe.[ch] * same for scache.[ch] git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@496 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 4 +- src/modules/module-match.c | 2 +- src/modules/module-tunnel.c | 2 +- src/modules/module-x11-bell.c | 2 +- src/modules/module-x11-publish.c | 2 +- src/polypcore/autoload.c | 4 +- src/polypcore/cli-command.c | 2 +- src/polypcore/cli-text.c | 2 +- src/polypcore/client.c | 2 +- src/polypcore/core-scache.c | 392 +++++++++++++++++++++++++++++++++++++++ src/polypcore/core-scache.h | 62 +++++++ src/polypcore/core-subscribe.c | 230 +++++++++++++++++++++++ src/polypcore/core-subscribe.h | 37 ++++ src/polypcore/core.c | 4 +- src/polypcore/core.h | 2 +- src/polypcore/module.c | 2 +- src/polypcore/namereg.c | 2 +- src/polypcore/protocol-esound.c | 2 +- src/polypcore/protocol-native.c | 4 +- src/polypcore/scache.c | 392 --------------------------------------- src/polypcore/scache.h | 62 ------- src/polypcore/sink-input.c | 2 +- src/polypcore/sink.c | 2 +- src/polypcore/source-output.c | 2 +- src/polypcore/source.c | 2 +- src/polypcore/subscribe.c | 230 ----------------------- src/polypcore/subscribe.h | 37 ---- 27 files changed, 744 insertions(+), 744 deletions(-) create mode 100644 src/polypcore/core-scache.c create mode 100644 src/polypcore/core-scache.h create mode 100644 src/polypcore/core-subscribe.c create mode 100644 src/polypcore/core-subscribe.h delete mode 100644 src/polypcore/scache.c delete mode 100644 src/polypcore/scache.h delete mode 100644 src/polypcore/subscribe.c delete mode 100644 src/polypcore/subscribe.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index cfd4b751..7d87a119 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -479,7 +479,7 @@ libpolypcore_la_SOURCES += \ polypcore/random.c polypcore/random.h \ polypcore/resampler.c polypcore/resampler.h \ polypcore/sample-util.c polypcore/sample-util.h \ - polypcore/scache.c polypcore/scache.h \ + polypcore/core-scache.c polypcore/core-scache.h \ polypcore/sconv.c polypcore/sconv.h \ polypcore/sconv-s16be.c polypcore/sconv-s16be.h \ polypcore/sconv-s16le.c polypcore/sconv-s16le.h \ @@ -491,7 +491,7 @@ libpolypcore_la_SOURCES += \ polypcore/source.c polypcore/source.h \ polypcore/source-output.c polypcore/source-output.h \ polypcore/strbuf.c polypcore/strbuf.h \ - polypcore/subscribe.c polypcore/subscribe.h \ + polypcore/core-subscribe.c polypcore/core-subscribe.h \ polypcore/tokenizer.c polypcore/tokenizer.h \ polypcore/util.c polypcore/util.h \ polypcore/winsock.h \ diff --git a/src/modules/module-match.c b/src/modules/module-match.c index 10ceb75e..1fb7233c 100644 --- a/src/modules/module-match.c +++ b/src/modules/module-match.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c index 5ee10fda..61b9bb3b 100644 --- a/src/modules/module-tunnel.c +++ b/src/modules/module-tunnel.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/modules/module-x11-bell.c b/src/modules/module-x11-bell.c index d722b732..d59f3f59 100644 --- a/src/modules/module-x11-bell.c +++ b/src/modules/module-x11-bell.c @@ -33,7 +33,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/modules/module-x11-publish.c b/src/modules/module-x11-publish.c index dca5d049..6d9036f5 100644 --- a/src/modules/module-x11-publish.c +++ b/src/modules/module-x11-publish.c @@ -34,7 +34,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/polypcore/autoload.c b/src/polypcore/autoload.c index ff2916cb..83df8ef7 100644 --- a/src/polypcore/autoload.c +++ b/src/polypcore/autoload.c @@ -33,8 +33,8 @@ #include "memchunk.h" #include "sound-file.h" #include "log.h" -#include "scache.h" -#include "subscribe.h" +#include "core-scache.h" +#include "core-subscribe.h" static void entry_free(pa_autoload_entry *e) { assert(e); diff --git a/src/polypcore/cli-command.c b/src/polypcore/cli-command.c index f6192bf8..dd4cbe46 100644 --- a/src/polypcore/cli-command.c +++ b/src/polypcore/cli-command.c @@ -40,7 +40,7 @@ #include "strbuf.h" #include "namereg.h" #include "cli-text.h" -#include "scache.h" +#include "core-scache.h" #include "sample-util.h" #include "sound-file.h" #include "play-memchunk.h" diff --git a/src/polypcore/cli-text.c b/src/polypcore/cli-text.c index 58248d8e..d8446b06 100644 --- a/src/polypcore/cli-text.c +++ b/src/polypcore/cli-text.c @@ -35,7 +35,7 @@ #include "source-output.h" #include "strbuf.h" #include "sample-util.h" -#include "scache.h" +#include "core-scache.h" #include "autoload.h" #include "xmalloc.h" #include diff --git a/src/polypcore/client.c b/src/polypcore/client.c index 3c2084bf..9b256794 100644 --- a/src/polypcore/client.c +++ b/src/polypcore/client.c @@ -30,7 +30,7 @@ #include "client.h" #include "xmalloc.h" -#include "subscribe.h" +#include "core-subscribe.h" #include "log.h" pa_client *pa_client_new(pa_core *core, const char *name, const char *driver) { diff --git a/src/polypcore/core-scache.c b/src/polypcore/core-scache.c new file mode 100644 index 00000000..0d926aba --- /dev/null +++ b/src/polypcore/core-scache.c @@ -0,0 +1,392 @@ +/* $Id$ */ + +/*** + This file is part of polypaudio. + + polypaudio 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. + + polypaudio 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 polypaudio; 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 +#include +#include + +#ifdef HAVE_GLOB_H +#include +#endif + +#ifdef HAVE_WINDOWS_H +#include +#endif + +#include "core-scache.h" +#include "sink-input.h" +#include +#include "sample-util.h" +#include "play-memchunk.h" +#include "xmalloc.h" +#include "core-subscribe.h" +#include "namereg.h" +#include "sound-file.h" +#include "util.h" +#include "log.h" +#include +#include + +#define UNLOAD_POLL_TIME 2 + +static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { + pa_core *c = userdata; + struct timeval ntv; + assert(c && c->mainloop == m && c->scache_auto_unload_event == e); + + pa_scache_unload_unused(c); + + pa_gettimeofday(&ntv); + ntv.tv_sec += UNLOAD_POLL_TIME; + m->time_restart(e, &ntv); +} + +static void free_entry(pa_scache_entry *e) { + assert(e); + pa_namereg_unregister(e->core, e->name); + pa_subscription_post(e->core, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_REMOVE, e->index); + pa_xfree(e->name); + pa_xfree(e->filename); + if (e->memchunk.memblock) + pa_memblock_unref(e->memchunk.memblock); + pa_xfree(e); +} + +static pa_scache_entry* scache_add_item(pa_core *c, const char *name) { + pa_scache_entry *e; + assert(c && name); + + if ((e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 0))) { + if (e->memchunk.memblock) + pa_memblock_unref(e->memchunk.memblock); + + pa_xfree(e->filename); + + assert(e->core == c); + + pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index); + } else { + e = pa_xmalloc(sizeof(pa_scache_entry)); + + if (!pa_namereg_register(c, name, PA_NAMEREG_SAMPLE, e, 1)) { + pa_xfree(e); + return NULL; + } + + e->name = pa_xstrdup(name); + e->core = c; + + if (!c->scache) { + c->scache = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + assert(c->scache); + } + + pa_idxset_put(c->scache, e, &e->index); + + pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_NEW, e->index); + } + + pa_cvolume_reset(&e->volume, PA_CHANNELS_MAX); + e->last_used_time = 0; + e->memchunk.memblock = NULL; + e->memchunk.index = e->memchunk.length = 0; + e->filename = NULL; + e->lazy = 0; + e->last_used_time = 0; + + memset(&e->sample_spec, 0, sizeof(pa_sample_spec)); + + return e; +} + +int pa_scache_add_item(pa_core *c, const char *name, const pa_sample_spec *ss, const pa_channel_map *map, const pa_memchunk *chunk, uint32_t *idx) { + pa_scache_entry *e; + assert(c && name); + + if (!(e = scache_add_item(c, name))) + return -1; + + if (ss) { + e->sample_spec = *ss; + pa_channel_map_init_auto(&e->channel_map, ss->channels); + } + + if (map) + e->channel_map = *map; + + if (chunk) { + e->memchunk = *chunk; + pa_memblock_ref(e->memchunk.memblock); + } + + if (idx) + *idx = e->index; + + return 0; +} + +int pa_scache_add_file(pa_core *c, const char *name, const char *filename, uint32_t *idx) { + pa_sample_spec ss; + pa_memchunk chunk; + int r; + +#ifdef OS_IS_WIN32 + char buf[MAX_PATH]; + + if (ExpandEnvironmentStrings(filename, buf, MAX_PATH)) + filename = buf; +#endif + + if (pa_sound_file_load(filename, &ss, &chunk, c->memblock_stat) < 0) + return -1; + + r = pa_scache_add_item(c, name, &ss, NULL, &chunk, idx); + pa_memblock_unref(chunk.memblock); + + return r; +} + +int pa_scache_add_file_lazy(pa_core *c, const char *name, const char *filename, uint32_t *idx) { + pa_scache_entry *e; + +#ifdef OS_IS_WIN32 + char buf[MAX_PATH]; + + if (ExpandEnvironmentStrings(filename, buf, MAX_PATH)) + filename = buf; +#endif + + assert(c && name); + + if (!(e = scache_add_item(c, name))) + return -1; + + e->lazy = 1; + e->filename = pa_xstrdup(filename); + + if (!c->scache_auto_unload_event) { + struct timeval ntv; + pa_gettimeofday(&ntv); + ntv.tv_sec += UNLOAD_POLL_TIME; + c->scache_auto_unload_event = c->mainloop->time_new(c->mainloop, &ntv, timeout_callback, c); + } + + if (idx) + *idx = e->index; + + return 0; +} + +int pa_scache_remove_item(pa_core *c, const char *name) { + pa_scache_entry *e; + assert(c && name); + + if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 0))) + return -1; + + if (pa_idxset_remove_by_data(c->scache, e, NULL) != e) + assert(0); + + free_entry(e); + return 0; +} + +static void free_cb(void *p, PA_GCC_UNUSED void *userdata) { + pa_scache_entry *e = p; + assert(e); + free_entry(e); +} + +void pa_scache_free(pa_core *c) { + assert(c); + + if (c->scache) { + pa_idxset_free(c->scache, free_cb, NULL); + c->scache = NULL; + } + + if (c->scache_auto_unload_event) + c->mainloop->time_free(c->scache_auto_unload_event); +} + +int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, const pa_cvolume *volume) { + pa_scache_entry *e; + char *t; + pa_cvolume r; + assert(c && name && sink); + + if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 1))) + return -1; + + if (e->lazy && !e->memchunk.memblock) { + if (pa_sound_file_load(e->filename, &e->sample_spec, &e->memchunk, c->memblock_stat) < 0) + return -1; + + pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index); + } + + if (!e->memchunk.memblock) + return -1; + + t = pa_sprintf_malloc("sample:%s", name); + + if (pa_play_memchunk(sink, t, &e->sample_spec, &e->channel_map, &e->memchunk, pa_sw_cvolume_multiply(&r, volume, &e->volume)) < 0) { + free(t); + return -1; + } + + free(t); + + if (e->lazy) + time(&e->last_used_time); + + return 0; +} + +const char * pa_scache_get_name_by_id(pa_core *c, uint32_t id) { + pa_scache_entry *e; + assert(c && id != PA_IDXSET_INVALID); + + if (!c->scache || !(e = pa_idxset_get_by_index(c->scache, id))) + return NULL; + + return e->name; +} + +uint32_t pa_scache_get_id_by_name(pa_core *c, const char *name) { + pa_scache_entry *e; + assert(c && name); + + if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 0))) + return PA_IDXSET_INVALID; + + return e->index; +} + +uint32_t pa_scache_total_size(pa_core *c) { + pa_scache_entry *e; + uint32_t idx, sum = 0; + assert(c); + + if (!c->scache || !pa_idxset_size(c->scache)) + return 0; + + for (e = pa_idxset_first(c->scache, &idx); e; e = pa_idxset_next(c->scache, &idx)) + if (e->memchunk.memblock) + sum += e->memchunk.length; + + return sum; +} + +void pa_scache_unload_unused(pa_core *c) { + pa_scache_entry *e; + time_t now; + uint32_t idx; + assert(c); + + if (!c->scache || !pa_idxset_size(c->scache)) + return; + + time(&now); + + for (e = pa_idxset_first(c->scache, &idx); e; e = pa_idxset_next(c->scache, &idx)) { + + if (!e->lazy || !e->memchunk.memblock) + continue; + + if (e->last_used_time + c->scache_idle_time > now) + continue; + + pa_memblock_unref(e->memchunk.memblock); + e->memchunk.memblock = NULL; + e->memchunk.index = e->memchunk.length = 0; + + pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index); + } +} + +static void add_file(pa_core *c, const char *pathname) { + struct stat st; + const char *e; + + e = pa_path_get_filename(pathname); + + if (stat(pathname, &st) < 0) { + pa_log(__FILE__": stat('%s') failed: %s\n", pathname, strerror(errno)); + return; + } + +#if defined(S_ISREG) && defined(S_ISLNK) + if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) +#endif + pa_scache_add_file_lazy(c, e, pathname, NULL); +} + +int pa_scache_add_directory_lazy(pa_core *c, const char *pathname) { + DIR *dir; + assert(c && pathname); + + /* First try to open this as directory */ + if (!(dir = opendir(pathname))) { +#ifdef HAVE_GLOB_H + glob_t p; + unsigned int i; + /* If that fails, try to open it as shell glob */ + + if (glob(pathname, GLOB_ERR|GLOB_NOSORT, NULL, &p) < 0) { + pa_log(__FILE__": Failed to open directory: %s\n", strerror(errno)); + return -1; + } + + for (i = 0; i < p.gl_pathc; i++) + add_file(c, p.gl_pathv[i]); + + globfree(&p); +#else + return -1; +#endif + } else { + struct dirent *e; + + while ((e = readdir(dir))) { + char p[PATH_MAX]; + + if (e->d_name[0] == '.') + continue; + + snprintf(p, sizeof(p), "%s/%s", pathname, e->d_name); + add_file(c, p); + } + } + + closedir(dir); + return 0; +} diff --git a/src/polypcore/core-scache.h b/src/polypcore/core-scache.h new file mode 100644 index 00000000..0918ebe4 --- /dev/null +++ b/src/polypcore/core-scache.h @@ -0,0 +1,62 @@ +#ifndef foocorescachehfoo +#define foocorescachehfoo + +/* $Id$ */ + +/*** + This file is part of polypaudio. + + polypaudio 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. + + polypaudio 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 polypaudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include "core.h" +#include "memchunk.h" +#include "sink.h" + +typedef struct pa_scache_entry { + pa_core *core; + uint32_t index; + char *name; + + pa_cvolume volume; + pa_sample_spec sample_spec; + pa_channel_map channel_map; + pa_memchunk memchunk; + + char *filename; + + int lazy; + time_t last_used_time; +} pa_scache_entry; + +int pa_scache_add_item(pa_core *c, const char *name, const pa_sample_spec *ss, const pa_channel_map *map, const pa_memchunk *chunk, uint32_t *idx); +int pa_scache_add_file(pa_core *c, const char *name, const char *filename, uint32_t *idx); +int pa_scache_add_file_lazy(pa_core *c, const char *name, const char *filename, uint32_t *idx); + +int pa_scache_add_directory_lazy(pa_core *c, const char *pathname); + +int pa_scache_remove_item(pa_core *c, const char *name); +int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, const pa_cvolume *cvolume); +void pa_scache_free(pa_core *c); + +const char *pa_scache_get_name_by_id(pa_core *c, uint32_t id); +uint32_t pa_scache_get_id_by_name(pa_core *c, const char *name); + +uint32_t pa_scache_total_size(pa_core *c); + +void pa_scache_unload_unused(pa_core *c); + +#endif diff --git a/src/polypcore/core-subscribe.c b/src/polypcore/core-subscribe.c new file mode 100644 index 00000000..2a258604 --- /dev/null +++ b/src/polypcore/core-subscribe.c @@ -0,0 +1,230 @@ +/* $Id$ */ + +/*** + This file is part of polypaudio. + + polypaudio 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. + + polypaudio 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 polypaudio; 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 "queue.h" +#include "core-subscribe.h" +#include "xmalloc.h" +#include "log.h" + +/* The subscription subsystem may be used to be notified whenever an + * entity (sink, source, ...) is created or deleted. Modules may + * register a callback function that is called whenever an event + * matching a subscription mask happens. The execution of the callback + * function is postponed to the next main loop iteration, i.e. is not + * called from within the stack frame the entity was created in. */ + +struct pa_subscription { + pa_core *core; + int dead; + void (*callback)(pa_core *c, pa_subscription_event_type_t t, uint32_t index, void *userdata); + void *userdata; + pa_subscription_mask_t mask; + + pa_subscription *prev, *next; +}; + +struct pa_subscription_event { + pa_subscription_event_type_t type; + uint32_t index; +}; + +static void sched_event(pa_core *c); + +/* Allocate a new subscription object for the given subscription mask. Use the specified callback function and user data */ +pa_subscription* pa_subscription_new(pa_core *c, pa_subscription_mask_t m, void (*callback)(pa_core *c, pa_subscription_event_type_t t, uint32_t index, void *userdata), void *userdata) { + pa_subscription *s; + assert(c); + + s = pa_xmalloc(sizeof(pa_subscription)); + s->core = c; + s->dead = 0; + s->callback = callback; + s->userdata = userdata; + s->mask = m; + + if ((s->next = c->subscriptions)) + s->next->prev = s; + s->prev = NULL; + c->subscriptions = s; + return s; +} + +/* Free a subscription object, effectively marking it for deletion */ +void pa_subscription_free(pa_subscription*s) { + assert(s && !s->dead); + s->dead = 1; + sched_event(s->core); +} + +static void free_item(pa_subscription *s) { + assert(s && s->core); + + if (s->prev) + s->prev->next = s->next; + else + s->core->subscriptions = s->next; + + if (s->next) + s->next->prev = s->prev; + + pa_xfree(s); +} + +/* Free all subscription objects */ +void pa_subscription_free_all(pa_core *c) { + pa_subscription_event *e; + assert(c); + + while (c->subscriptions) + free_item(c->subscriptions); + + if (c->subscription_event_queue) { + while ((e = pa_queue_pop(c->subscription_event_queue))) + pa_xfree(e); + + pa_queue_free(c->subscription_event_queue, NULL, NULL); + c->subscription_event_queue = NULL; + } + + if (c->subscription_defer_event) { + c->mainloop->defer_free(c->subscription_defer_event); + c->subscription_defer_event = NULL; + } +} + +/*static void dump_event(pa_subscription_event*e) { + switch (e->type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { + case PA_SUBSCRIPTION_EVENT_SINK: + pa_log(__FILE__": SINK_EVENT"); + break; + case PA_SUBSCRIPTION_EVENT_SOURCE: + pa_log(__FILE__": SOURCE_EVENT"); + break; + case PA_SUBSCRIPTION_EVENT_SINK_INPUT: + pa_log(__FILE__": SINK_INPUT_EVENT"); + break; + case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: + pa_log(__FILE__": SOURCE_OUTPUT_EVENT"); + break; + case PA_SUBSCRIPTION_EVENT_MODULE: + pa_log(__FILE__": MODULE_EVENT"); + break; + case PA_SUBSCRIPTION_EVENT_CLIENT: + pa_log(__FILE__": CLIENT_EVENT"); + break; + default: + pa_log(__FILE__": OTHER"); + break; + } + + switch (e->type & PA_SUBSCRIPTION_EVENT_TYPE_MASK) { + case PA_SUBSCRIPTION_EVENT_NEW: + pa_log(__FILE__": NEW"); + break; + case PA_SUBSCRIPTION_EVENT_CHANGE: + pa_log(__FILE__": CHANGE"); + break; + case PA_SUBSCRIPTION_EVENT_REMOVE: + pa_log(__FILE__": REMOVE"); + break; + default: + pa_log(__FILE__": OTHER"); + break; + } + + pa_log(__FILE__": %u\n", e->index); +}*/ + +/* Deferred callback for dispatching subscirption events */ +static void defer_cb(pa_mainloop_api *m, pa_defer_event *de, void *userdata) { + pa_core *c = userdata; + pa_subscription *s; + assert(c && c->subscription_defer_event == de && c->mainloop == m); + + c->mainloop->defer_enable(c->subscription_defer_event, 0); + + + /* Dispatch queued events */ + + if (c->subscription_event_queue) { + pa_subscription_event *e; + + while ((e = pa_queue_pop(c->subscription_event_queue))) { + + for (s = c->subscriptions; s; s = s->next) { + + if (!s->dead && pa_subscription_match_flags(s->mask, e->type)) + s->callback(c, e->type, e->index, s->userdata); + } + + pa_xfree(e); + } + } + + /* Remove dead subscriptions */ + + s = c->subscriptions; + while (s) { + pa_subscription *n = s->next; + if (s->dead) + free_item(s); + s = n; + } +} + +/* Schedule an mainloop event so that a pending subscription event is dispatched */ +static void sched_event(pa_core *c) { + assert(c); + + if (!c->subscription_defer_event) { + c->subscription_defer_event = c->mainloop->defer_new(c->mainloop, defer_cb, c); + assert(c->subscription_defer_event); + } + + c->mainloop->defer_enable(c->subscription_defer_event, 1); +} + +/* Append a new subscription event to the subscription event queue and schedule a main loop event */ +void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t index) { + pa_subscription_event *e; + assert(c); + + e = pa_xmalloc(sizeof(pa_subscription_event)); + e->type = t; + e->index = index; + + if (!c->subscription_event_queue) { + c->subscription_event_queue = pa_queue_new(); + assert(c->subscription_event_queue); + } + + pa_queue_push(c->subscription_event_queue, e); + sched_event(c); +} + + diff --git a/src/polypcore/core-subscribe.h b/src/polypcore/core-subscribe.h new file mode 100644 index 00000000..bc9dcba3 --- /dev/null +++ b/src/polypcore/core-subscribe.h @@ -0,0 +1,37 @@ +#ifndef foocoresubscribehfoo +#define foocoresubscribehfoo + +/* $Id$ */ + +/*** + This file is part of polypaudio. + + polypaudio 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. + + polypaudio 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 polypaudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +typedef struct pa_subscription pa_subscription; +typedef struct pa_subscription_event pa_subscription_event; + +#include "core.h" +#include "native-common.h" + +pa_subscription* pa_subscription_new(pa_core *c, pa_subscription_mask_t m, void (*callback)(pa_core *c, pa_subscription_event_type_t t, uint32_t index, void *userdata), void *userdata); +void pa_subscription_free(pa_subscription*s); +void pa_subscription_free_all(pa_core *c); + +void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t idx); + +#endif diff --git a/src/polypcore/core.c b/src/polypcore/core.c index 678e8212..9d040e68 100644 --- a/src/polypcore/core.c +++ b/src/polypcore/core.c @@ -34,10 +34,10 @@ #include "source.h" #include "namereg.h" #include "util.h" -#include "scache.h" +#include "core-scache.h" #include "autoload.h" #include "xmalloc.h" -#include "subscribe.h" +#include "core-subscribe.h" #include "props.h" #include "random.h" diff --git a/src/polypcore/core.h b/src/polypcore/core.h index f7a90169..29329025 100644 --- a/src/polypcore/core.h +++ b/src/polypcore/core.h @@ -31,7 +31,7 @@ typedef struct pa_core pa_core; #include "memblock.h" #include "resampler.h" #include "queue.h" -#include "subscribe.h" +#include "core-subscribe.h" /* The core structure of polypaudio. Every polypaudio daemon contains * exactly one of these. It is used for storing kind of global diff --git a/src/polypcore/module.c b/src/polypcore/module.c index 499ea299..73ec5bd4 100644 --- a/src/polypcore/module.c +++ b/src/polypcore/module.c @@ -32,7 +32,7 @@ #include "module.h" #include "xmalloc.h" -#include "subscribe.h" +#include "core-subscribe.h" #include "log.h" #include "util.h" diff --git a/src/polypcore/namereg.c b/src/polypcore/namereg.c index 07fb485c..ca03c455 100644 --- a/src/polypcore/namereg.c +++ b/src/polypcore/namereg.c @@ -34,7 +34,7 @@ #include "source.h" #include "sink.h" #include "xmalloc.h" -#include "subscribe.h" +#include "core-subscribe.h" #include "util.h" struct namereg_entry { diff --git a/src/polypcore/protocol-esound.c b/src/polypcore/protocol-esound.c index 14f237c7..d2c0f354 100644 --- a/src/polypcore/protocol-esound.c +++ b/src/polypcore/protocol-esound.c @@ -39,7 +39,7 @@ #include "source-output.h" #include "source.h" #include -#include "scache.h" +#include "core-scache.h" #include "sample-util.h" #include "authkey.h" #include "namereg.h" diff --git a/src/polypcore/protocol-native.c b/src/polypcore/protocol-native.c index b94903d9..31983bc2 100644 --- a/src/polypcore/protocol-native.c +++ b/src/polypcore/protocol-native.c @@ -40,10 +40,10 @@ #include "pstream-util.h" #include "authkey.h" #include "namereg.h" -#include "scache.h" +#include "core-scache.h" #include "xmalloc.h" #include "util.h" -#include "subscribe.h" +#include "core-subscribe.h" #include "log.h" #include "autoload.h" #include "authkey-prop.h" diff --git a/src/polypcore/scache.c b/src/polypcore/scache.c deleted file mode 100644 index 02c7d34f..00000000 --- a/src/polypcore/scache.c +++ /dev/null @@ -1,392 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio 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. - - polypaudio 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 polypaudio; 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 -#include -#include - -#ifdef HAVE_GLOB_H -#include -#endif - -#ifdef HAVE_WINDOWS_H -#include -#endif - -#include "scache.h" -#include "sink-input.h" -#include -#include "sample-util.h" -#include "play-memchunk.h" -#include "xmalloc.h" -#include "subscribe.h" -#include "namereg.h" -#include "sound-file.h" -#include "util.h" -#include "log.h" -#include -#include - -#define UNLOAD_POLL_TIME 2 - -static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { - pa_core *c = userdata; - struct timeval ntv; - assert(c && c->mainloop == m && c->scache_auto_unload_event == e); - - pa_scache_unload_unused(c); - - pa_gettimeofday(&ntv); - ntv.tv_sec += UNLOAD_POLL_TIME; - m->time_restart(e, &ntv); -} - -static void free_entry(pa_scache_entry *e) { - assert(e); - pa_namereg_unregister(e->core, e->name); - pa_subscription_post(e->core, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_REMOVE, e->index); - pa_xfree(e->name); - pa_xfree(e->filename); - if (e->memchunk.memblock) - pa_memblock_unref(e->memchunk.memblock); - pa_xfree(e); -} - -static pa_scache_entry* scache_add_item(pa_core *c, const char *name) { - pa_scache_entry *e; - assert(c && name); - - if ((e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 0))) { - if (e->memchunk.memblock) - pa_memblock_unref(e->memchunk.memblock); - - pa_xfree(e->filename); - - assert(e->core == c); - - pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index); - } else { - e = pa_xmalloc(sizeof(pa_scache_entry)); - - if (!pa_namereg_register(c, name, PA_NAMEREG_SAMPLE, e, 1)) { - pa_xfree(e); - return NULL; - } - - e->name = pa_xstrdup(name); - e->core = c; - - if (!c->scache) { - c->scache = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - assert(c->scache); - } - - pa_idxset_put(c->scache, e, &e->index); - - pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_NEW, e->index); - } - - pa_cvolume_reset(&e->volume, PA_CHANNELS_MAX); - e->last_used_time = 0; - e->memchunk.memblock = NULL; - e->memchunk.index = e->memchunk.length = 0; - e->filename = NULL; - e->lazy = 0; - e->last_used_time = 0; - - memset(&e->sample_spec, 0, sizeof(pa_sample_spec)); - - return e; -} - -int pa_scache_add_item(pa_core *c, const char *name, const pa_sample_spec *ss, const pa_channel_map *map, const pa_memchunk *chunk, uint32_t *idx) { - pa_scache_entry *e; - assert(c && name); - - if (!(e = scache_add_item(c, name))) - return -1; - - if (ss) { - e->sample_spec = *ss; - pa_channel_map_init_auto(&e->channel_map, ss->channels); - } - - if (map) - e->channel_map = *map; - - if (chunk) { - e->memchunk = *chunk; - pa_memblock_ref(e->memchunk.memblock); - } - - if (idx) - *idx = e->index; - - return 0; -} - -int pa_scache_add_file(pa_core *c, const char *name, const char *filename, uint32_t *idx) { - pa_sample_spec ss; - pa_memchunk chunk; - int r; - -#ifdef OS_IS_WIN32 - char buf[MAX_PATH]; - - if (ExpandEnvironmentStrings(filename, buf, MAX_PATH)) - filename = buf; -#endif - - if (pa_sound_file_load(filename, &ss, &chunk, c->memblock_stat) < 0) - return -1; - - r = pa_scache_add_item(c, name, &ss, NULL, &chunk, idx); - pa_memblock_unref(chunk.memblock); - - return r; -} - -int pa_scache_add_file_lazy(pa_core *c, const char *name, const char *filename, uint32_t *idx) { - pa_scache_entry *e; - -#ifdef OS_IS_WIN32 - char buf[MAX_PATH]; - - if (ExpandEnvironmentStrings(filename, buf, MAX_PATH)) - filename = buf; -#endif - - assert(c && name); - - if (!(e = scache_add_item(c, name))) - return -1; - - e->lazy = 1; - e->filename = pa_xstrdup(filename); - - if (!c->scache_auto_unload_event) { - struct timeval ntv; - pa_gettimeofday(&ntv); - ntv.tv_sec += UNLOAD_POLL_TIME; - c->scache_auto_unload_event = c->mainloop->time_new(c->mainloop, &ntv, timeout_callback, c); - } - - if (idx) - *idx = e->index; - - return 0; -} - -int pa_scache_remove_item(pa_core *c, const char *name) { - pa_scache_entry *e; - assert(c && name); - - if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 0))) - return -1; - - if (pa_idxset_remove_by_data(c->scache, e, NULL) != e) - assert(0); - - free_entry(e); - return 0; -} - -static void free_cb(void *p, PA_GCC_UNUSED void *userdata) { - pa_scache_entry *e = p; - assert(e); - free_entry(e); -} - -void pa_scache_free(pa_core *c) { - assert(c); - - if (c->scache) { - pa_idxset_free(c->scache, free_cb, NULL); - c->scache = NULL; - } - - if (c->scache_auto_unload_event) - c->mainloop->time_free(c->scache_auto_unload_event); -} - -int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, const pa_cvolume *volume) { - pa_scache_entry *e; - char *t; - pa_cvolume r; - assert(c && name && sink); - - if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 1))) - return -1; - - if (e->lazy && !e->memchunk.memblock) { - if (pa_sound_file_load(e->filename, &e->sample_spec, &e->memchunk, c->memblock_stat) < 0) - return -1; - - pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index); - } - - if (!e->memchunk.memblock) - return -1; - - t = pa_sprintf_malloc("sample:%s", name); - - if (pa_play_memchunk(sink, t, &e->sample_spec, &e->channel_map, &e->memchunk, pa_sw_cvolume_multiply(&r, volume, &e->volume)) < 0) { - free(t); - return -1; - } - - free(t); - - if (e->lazy) - time(&e->last_used_time); - - return 0; -} - -const char * pa_scache_get_name_by_id(pa_core *c, uint32_t id) { - pa_scache_entry *e; - assert(c && id != PA_IDXSET_INVALID); - - if (!c->scache || !(e = pa_idxset_get_by_index(c->scache, id))) - return NULL; - - return e->name; -} - -uint32_t pa_scache_get_id_by_name(pa_core *c, const char *name) { - pa_scache_entry *e; - assert(c && name); - - if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 0))) - return PA_IDXSET_INVALID; - - return e->index; -} - -uint32_t pa_scache_total_size(pa_core *c) { - pa_scache_entry *e; - uint32_t idx, sum = 0; - assert(c); - - if (!c->scache || !pa_idxset_size(c->scache)) - return 0; - - for (e = pa_idxset_first(c->scache, &idx); e; e = pa_idxset_next(c->scache, &idx)) - if (e->memchunk.memblock) - sum += e->memchunk.length; - - return sum; -} - -void pa_scache_unload_unused(pa_core *c) { - pa_scache_entry *e; - time_t now; - uint32_t idx; - assert(c); - - if (!c->scache || !pa_idxset_size(c->scache)) - return; - - time(&now); - - for (e = pa_idxset_first(c->scache, &idx); e; e = pa_idxset_next(c->scache, &idx)) { - - if (!e->lazy || !e->memchunk.memblock) - continue; - - if (e->last_used_time + c->scache_idle_time > now) - continue; - - pa_memblock_unref(e->memchunk.memblock); - e->memchunk.memblock = NULL; - e->memchunk.index = e->memchunk.length = 0; - - pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index); - } -} - -static void add_file(pa_core *c, const char *pathname) { - struct stat st; - const char *e; - - e = pa_path_get_filename(pathname); - - if (stat(pathname, &st) < 0) { - pa_log(__FILE__": stat('%s') failed: %s\n", pathname, strerror(errno)); - return; - } - -#if defined(S_ISREG) && defined(S_ISLNK) - if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) -#endif - pa_scache_add_file_lazy(c, e, pathname, NULL); -} - -int pa_scache_add_directory_lazy(pa_core *c, const char *pathname) { - DIR *dir; - assert(c && pathname); - - /* First try to open this as directory */ - if (!(dir = opendir(pathname))) { -#ifdef HAVE_GLOB_H - glob_t p; - unsigned int i; - /* If that fails, try to open it as shell glob */ - - if (glob(pathname, GLOB_ERR|GLOB_NOSORT, NULL, &p) < 0) { - pa_log(__FILE__": Failed to open directory: %s\n", strerror(errno)); - return -1; - } - - for (i = 0; i < p.gl_pathc; i++) - add_file(c, p.gl_pathv[i]); - - globfree(&p); -#else - return -1; -#endif - } else { - struct dirent *e; - - while ((e = readdir(dir))) { - char p[PATH_MAX]; - - if (e->d_name[0] == '.') - continue; - - snprintf(p, sizeof(p), "%s/%s", pathname, e->d_name); - add_file(c, p); - } - } - - closedir(dir); - return 0; -} diff --git a/src/polypcore/scache.h b/src/polypcore/scache.h deleted file mode 100644 index d667ae60..00000000 --- a/src/polypcore/scache.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef fooscachehfoo -#define fooscachehfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio 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. - - polypaudio 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 polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include "core.h" -#include "memchunk.h" -#include "sink.h" - -typedef struct pa_scache_entry { - pa_core *core; - uint32_t index; - char *name; - - pa_cvolume volume; - pa_sample_spec sample_spec; - pa_channel_map channel_map; - pa_memchunk memchunk; - - char *filename; - - int lazy; - time_t last_used_time; -} pa_scache_entry; - -int pa_scache_add_item(pa_core *c, const char *name, const pa_sample_spec *ss, const pa_channel_map *map, const pa_memchunk *chunk, uint32_t *idx); -int pa_scache_add_file(pa_core *c, const char *name, const char *filename, uint32_t *idx); -int pa_scache_add_file_lazy(pa_core *c, const char *name, const char *filename, uint32_t *idx); - -int pa_scache_add_directory_lazy(pa_core *c, const char *pathname); - -int pa_scache_remove_item(pa_core *c, const char *name); -int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, const pa_cvolume *cvolume); -void pa_scache_free(pa_core *c); - -const char *pa_scache_get_name_by_id(pa_core *c, uint32_t id); -uint32_t pa_scache_get_id_by_name(pa_core *c, const char *name); - -uint32_t pa_scache_total_size(pa_core *c); - -void pa_scache_unload_unused(pa_core *c); - -#endif diff --git a/src/polypcore/sink-input.c b/src/polypcore/sink-input.c index f447b8cf..696c47a4 100644 --- a/src/polypcore/sink-input.c +++ b/src/polypcore/sink-input.c @@ -31,7 +31,7 @@ #include "sink-input.h" #include "sample-util.h" #include "xmalloc.h" -#include "subscribe.h" +#include "core-subscribe.h" #include "log.h" #define CONVERT_BUFFER_LENGTH 4096 diff --git a/src/polypcore/sink.c b/src/polypcore/sink.c index f29afba7..6c143463 100644 --- a/src/polypcore/sink.c +++ b/src/polypcore/sink.c @@ -34,7 +34,7 @@ #include "util.h" #include "sample-util.h" #include "xmalloc.h" -#include "subscribe.h" +#include "core-subscribe.h" #include "log.h" #include diff --git a/src/polypcore/source-output.c b/src/polypcore/source-output.c index e1d8ccf7..9b75a8b0 100644 --- a/src/polypcore/source-output.c +++ b/src/polypcore/source-output.c @@ -30,7 +30,7 @@ #include "source-output.h" #include "xmalloc.h" -#include "subscribe.h" +#include "core-subscribe.h" #include "log.h" pa_source_output* pa_source_output_new( diff --git a/src/polypcore/source.c b/src/polypcore/source.c index 6e377b20..c64f7b99 100644 --- a/src/polypcore/source.c +++ b/src/polypcore/source.c @@ -32,7 +32,7 @@ #include "source-output.h" #include "namereg.h" #include "xmalloc.h" -#include "subscribe.h" +#include "core-subscribe.h" #include "log.h" pa_source* pa_source_new( diff --git a/src/polypcore/subscribe.c b/src/polypcore/subscribe.c deleted file mode 100644 index e8b3c841..00000000 --- a/src/polypcore/subscribe.c +++ /dev/null @@ -1,230 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio 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. - - polypaudio 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 polypaudio; 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 "queue.h" -#include "subscribe.h" -#include "xmalloc.h" -#include "log.h" - -/* The subscription subsystem may be used to be notified whenever an - * entity (sink, source, ...) is created or deleted. Modules may - * register a callback function that is called whenever an event - * matching a subscription mask happens. The execution of the callback - * function is postponed to the next main loop iteration, i.e. is not - * called from within the stack frame the entity was created in. */ - -struct pa_subscription { - pa_core *core; - int dead; - void (*callback)(pa_core *c, pa_subscription_event_type_t t, uint32_t index, void *userdata); - void *userdata; - pa_subscription_mask_t mask; - - pa_subscription *prev, *next; -}; - -struct pa_subscription_event { - pa_subscription_event_type_t type; - uint32_t index; -}; - -static void sched_event(pa_core *c); - -/* Allocate a new subscription object for the given subscription mask. Use the specified callback function and user data */ -pa_subscription* pa_subscription_new(pa_core *c, pa_subscription_mask_t m, void (*callback)(pa_core *c, pa_subscription_event_type_t t, uint32_t index, void *userdata), void *userdata) { - pa_subscription *s; - assert(c); - - s = pa_xmalloc(sizeof(pa_subscription)); - s->core = c; - s->dead = 0; - s->callback = callback; - s->userdata = userdata; - s->mask = m; - - if ((s->next = c->subscriptions)) - s->next->prev = s; - s->prev = NULL; - c->subscriptions = s; - return s; -} - -/* Free a subscription object, effectively marking it for deletion */ -void pa_subscription_free(pa_subscription*s) { - assert(s && !s->dead); - s->dead = 1; - sched_event(s->core); -} - -static void free_item(pa_subscription *s) { - assert(s && s->core); - - if (s->prev) - s->prev->next = s->next; - else - s->core->subscriptions = s->next; - - if (s->next) - s->next->prev = s->prev; - - pa_xfree(s); -} - -/* Free all subscription objects */ -void pa_subscription_free_all(pa_core *c) { - pa_subscription_event *e; - assert(c); - - while (c->subscriptions) - free_item(c->subscriptions); - - if (c->subscription_event_queue) { - while ((e = pa_queue_pop(c->subscription_event_queue))) - pa_xfree(e); - - pa_queue_free(c->subscription_event_queue, NULL, NULL); - c->subscription_event_queue = NULL; - } - - if (c->subscription_defer_event) { - c->mainloop->defer_free(c->subscription_defer_event); - c->subscription_defer_event = NULL; - } -} - -/*static void dump_event(pa_subscription_event*e) { - switch (e->type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { - case PA_SUBSCRIPTION_EVENT_SINK: - pa_log(__FILE__": SINK_EVENT"); - break; - case PA_SUBSCRIPTION_EVENT_SOURCE: - pa_log(__FILE__": SOURCE_EVENT"); - break; - case PA_SUBSCRIPTION_EVENT_SINK_INPUT: - pa_log(__FILE__": SINK_INPUT_EVENT"); - break; - case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: - pa_log(__FILE__": SOURCE_OUTPUT_EVENT"); - break; - case PA_SUBSCRIPTION_EVENT_MODULE: - pa_log(__FILE__": MODULE_EVENT"); - break; - case PA_SUBSCRIPTION_EVENT_CLIENT: - pa_log(__FILE__": CLIENT_EVENT"); - break; - default: - pa_log(__FILE__": OTHER"); - break; - } - - switch (e->type & PA_SUBSCRIPTION_EVENT_TYPE_MASK) { - case PA_SUBSCRIPTION_EVENT_NEW: - pa_log(__FILE__": NEW"); - break; - case PA_SUBSCRIPTION_EVENT_CHANGE: - pa_log(__FILE__": CHANGE"); - break; - case PA_SUBSCRIPTION_EVENT_REMOVE: - pa_log(__FILE__": REMOVE"); - break; - default: - pa_log(__FILE__": OTHER"); - break; - } - - pa_log(__FILE__": %u\n", e->index); -}*/ - -/* Deferred callback for dispatching subscirption events */ -static void defer_cb(pa_mainloop_api *m, pa_defer_event *de, void *userdata) { - pa_core *c = userdata; - pa_subscription *s; - assert(c && c->subscription_defer_event == de && c->mainloop == m); - - c->mainloop->defer_enable(c->subscription_defer_event, 0); - - - /* Dispatch queued events */ - - if (c->subscription_event_queue) { - pa_subscription_event *e; - - while ((e = pa_queue_pop(c->subscription_event_queue))) { - - for (s = c->subscriptions; s; s = s->next) { - - if (!s->dead && pa_subscription_match_flags(s->mask, e->type)) - s->callback(c, e->type, e->index, s->userdata); - } - - pa_xfree(e); - } - } - - /* Remove dead subscriptions */ - - s = c->subscriptions; - while (s) { - pa_subscription *n = s->next; - if (s->dead) - free_item(s); - s = n; - } -} - -/* Schedule an mainloop event so that a pending subscription event is dispatched */ -static void sched_event(pa_core *c) { - assert(c); - - if (!c->subscription_defer_event) { - c->subscription_defer_event = c->mainloop->defer_new(c->mainloop, defer_cb, c); - assert(c->subscription_defer_event); - } - - c->mainloop->defer_enable(c->subscription_defer_event, 1); -} - -/* Append a new subscription event to the subscription event queue and schedule a main loop event */ -void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t index) { - pa_subscription_event *e; - assert(c); - - e = pa_xmalloc(sizeof(pa_subscription_event)); - e->type = t; - e->index = index; - - if (!c->subscription_event_queue) { - c->subscription_event_queue = pa_queue_new(); - assert(c->subscription_event_queue); - } - - pa_queue_push(c->subscription_event_queue, e); - sched_event(c); -} - - diff --git a/src/polypcore/subscribe.h b/src/polypcore/subscribe.h deleted file mode 100644 index 625159e3..00000000 --- a/src/polypcore/subscribe.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef foosubscribehfoo -#define foosubscribehfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio 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. - - polypaudio 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 polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -typedef struct pa_subscription pa_subscription; -typedef struct pa_subscription_event pa_subscription_event; - -#include "core.h" -#include "native-common.h" - -pa_subscription* pa_subscription_new(pa_core *c, pa_subscription_mask_t m, void (*callback)(pa_core *c, pa_subscription_event_type_t t, uint32_t index, void *userdata), void *userdata); -void pa_subscription_free(pa_subscription*s); -void pa_subscription_free_all(pa_core *c); - -void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t idx); - -#endif -- cgit