]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/core-scache.c
Use pa_hashmap_remove_and_free() where appropriate
[pulseaudio] / src / pulsecore / core-scache.c
index e5489415ff6c778bf02d49f91c7c68c9bb67a380..a622616c2af5655f8d107b1537abfbf65d8fd0a4 100644 (file)
@@ -6,7 +6,7 @@
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
 
   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,
+  by the Free Software Foundation; either version 2.1 of the License,
   or (at your option) any later version.
 
   PulseAudio is distributed in the hope that it will be useful, but
   or (at your option) any later version.
 
   PulseAudio is distributed in the hope that it will be useful, but
 #endif
 
 #include <stdlib.h>
 #endif
 
 #include <stdlib.h>
-#include <string.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <dirent.h>
 #include <sys/stat.h>
 #include <errno.h>
 #include <limits.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <dirent.h>
 #include <sys/stat.h>
 #include <errno.h>
 #include <limits.h>
+#include <time.h>
 
 #ifdef HAVE_GLOB_H
 #include <glob.h>
 
 #ifdef HAVE_GLOB_H
 #include <glob.h>
 #include <pulse/util.h>
 #include <pulse/volume.h>
 #include <pulse/xmalloc.h>
 #include <pulse/util.h>
 #include <pulse/volume.h>
 #include <pulse/xmalloc.h>
+#include <pulse/rtclock.h>
 
 #include <pulsecore/sink-input.h>
 
 #include <pulsecore/sink-input.h>
-#include <pulsecore/sample-util.h>
 #include <pulsecore/play-memchunk.h>
 #include <pulsecore/core-subscribe.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/sound-file.h>
 #include <pulsecore/play-memchunk.h>
 #include <pulsecore/core-subscribe.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/sound-file.h>
+#include <pulsecore/core-rtclock.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/core-error.h>
 
 #include "core-scache.h"
 
 
 #include "core-scache.h"
 
-#define UNLOAD_POLL_TIME 60
+#define UNLOAD_POLL_TIME (60 * PA_USEC_PER_SEC)
 
 
-static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, const struct timeval *tv, void *userdata) {
+static void timeout_callback(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) {
     pa_core *c = userdata;
     pa_core *c = userdata;
-    struct timeval ntv;
 
     pa_assert(c);
     pa_assert(c->mainloop == m);
 
     pa_assert(c);
     pa_assert(c->mainloop == m);
@@ -73,9 +73,7 @@ static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, const struct t
 
     pa_scache_unload_unused(c);
 
 
     pa_scache_unload_unused(c);
 
-    pa_gettimeofday(&ntv);
-    ntv.tv_sec += UNLOAD_POLL_TIME;
-    m->time_restart(e, &ntv);
+    pa_core_rttime_restart(c, e, pa_rtclock_now() + UNLOAD_POLL_TIME);
 }
 
 static void free_entry(pa_scache_entry *e) {
 }
 
 static void free_entry(pa_scache_entry *e) {
@@ -111,7 +109,7 @@ static pa_scache_entry* scache_add_item(pa_core *c, const char *name) {
     } else {
         e = pa_xnew(pa_scache_entry, 1);
 
     } else {
         e = pa_xnew(pa_scache_entry, 1);
 
-        if (!pa_namereg_register(c, name, PA_NAMEREG_SAMPLE, e, TRUE)) {
+        if (!pa_namereg_register(c, name, PA_NAMEREG_SAMPLE, e, true)) {
             pa_xfree(e);
             return NULL;
         }
             pa_xfree(e);
             return NULL;
         }
@@ -128,13 +126,13 @@ static pa_scache_entry* scache_add_item(pa_core *c, const char *name) {
     e->last_used_time = 0;
     pa_memchunk_reset(&e->memchunk);
     e->filename = NULL;
     e->last_used_time = 0;
     pa_memchunk_reset(&e->memchunk);
     e->filename = NULL;
-    e->lazy = FALSE;
+    e->lazy = false;
     e->last_used_time = 0;
 
     pa_sample_spec_init(&e->sample_spec);
     pa_channel_map_init(&e->channel_map);
     pa_cvolume_init(&e->volume);
     e->last_used_time = 0;
 
     pa_sample_spec_init(&e->sample_spec);
     pa_channel_map_init(&e->channel_map);
     pa_cvolume_init(&e->volume);
-    e->volume_is_set = FALSE;
+    e->volume_is_set = false;
 
     pa_proplist_sets(e->proplist, PA_PROP_MEDIA_ROLE, "event");
 
 
     pa_proplist_sets(e->proplist, PA_PROP_MEDIA_ROLE, "event");
 
@@ -173,7 +171,7 @@ int pa_scache_add_item(
     pa_sample_spec_init(&e->sample_spec);
     pa_channel_map_init(&e->channel_map);
     pa_cvolume_init(&e->volume);
     pa_sample_spec_init(&e->sample_spec);
     pa_channel_map_init(&e->channel_map);
     pa_cvolume_init(&e->volume);
-    e->volume_is_set = FALSE;
+    e->volume_is_set = false;
 
     if (ss) {
         e->sample_spec = *ss;
 
     if (ss) {
         e->sample_spec = *ss;
@@ -219,11 +217,14 @@ int pa_scache_add_file(pa_core *c, const char *name, const char *filename, uint3
     pa_assert(name);
     pa_assert(filename);
 
     pa_assert(name);
     pa_assert(filename);
 
-    if (pa_sound_file_load(c->mempool, filename, &ss, &map, &chunk) < 0)
-        return -1;
-
     p = pa_proplist_new();
     pa_proplist_sets(p, PA_PROP_MEDIA_FILENAME, filename);
     p = pa_proplist_new();
     pa_proplist_sets(p, PA_PROP_MEDIA_FILENAME, filename);
+
+    if (pa_sound_file_load(c->mempool, filename, &ss, &map, &chunk, p) < 0) {
+        pa_proplist_free(p);
+        return -1;
+    }
+
     r = pa_scache_add_item(c, name, &ss, &map, &chunk, p, idx);
     pa_memblock_unref(chunk.memblock);
     pa_proplist_free(p);
     r = pa_scache_add_item(c, name, &ss, &map, &chunk, p, idx);
     pa_memblock_unref(chunk.memblock);
     pa_proplist_free(p);
@@ -248,17 +249,13 @@ int pa_scache_add_file_lazy(pa_core *c, const char *name, const char *filename,
     if (!(e = scache_add_item(c, name)))
         return -1;
 
     if (!(e = scache_add_item(c, name)))
         return -1;
 
-    e->lazy = TRUE;
+    e->lazy = true;
     e->filename = pa_xstrdup(filename);
 
     pa_proplist_sets(e->proplist, PA_PROP_MEDIA_FILENAME, filename);
 
     e->filename = pa_xstrdup(filename);
 
     pa_proplist_sets(e->proplist, PA_PROP_MEDIA_FILENAME, 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 (!c->scache_auto_unload_event)
+        c->scache_auto_unload_event = pa_core_rttime_new(c, pa_rtclock_now() + UNLOAD_POLL_TIME, timeout_callback, c);
 
     if (idx)
         *idx = e->index;
 
     if (idx)
         *idx = e->index;
@@ -285,12 +282,9 @@ int pa_scache_remove_item(pa_core *c, const char *name) {
 }
 
 void pa_scache_free_all(pa_core *c) {
 }
 
 void pa_scache_free_all(pa_core *c) {
-    pa_scache_entry *e;
-
     pa_assert(c);
 
     pa_assert(c);
 
-    while ((e = pa_idxset_steal_first(c->scache, NULL)))
-        free_entry(e);
+    pa_idxset_remove_all(c->scache, (pa_free_cb_t) free_entry);
 
     if (c->scache_auto_unload_event) {
         c->mainloop->time_free(c->scache_auto_unload_event);
 
     if (c->scache_auto_unload_event) {
         c->mainloop->time_free(c->scache_auto_unload_event);
@@ -302,7 +296,7 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t
     pa_scache_entry *e;
     pa_cvolume r;
     pa_proplist *merged;
     pa_scache_entry *e;
     pa_cvolume r;
     pa_proplist *merged;
-    pa_bool_t pass_volume;
+    bool pass_volume;
 
     pa_assert(c);
     pa_assert(name);
 
     pa_assert(c);
     pa_assert(name);
@@ -311,11 +305,15 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t
     if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE)))
         return -1;
 
     if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE)))
         return -1;
 
+    merged = pa_proplist_new();
+    pa_proplist_sets(merged, PA_PROP_MEDIA_NAME, name);
+    pa_proplist_sets(merged, PA_PROP_EVENT_ID, name);
+
     if (e->lazy && !e->memchunk.memblock) {
         pa_channel_map old_channel_map = e->channel_map;
 
     if (e->lazy && !e->memchunk.memblock) {
         pa_channel_map old_channel_map = e->channel_map;
 
-        if (pa_sound_file_load(c->mempool, e->filename, &e->sample_spec, &e->channel_map, &e->memchunk) < 0)
-            return -1;
+        if (pa_sound_file_load(c->mempool, e->filename, &e->sample_spec, &e->channel_map, &e->memchunk, merged) < 0)
+            goto fail;
 
         pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index);
 
 
         pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index);
 
@@ -328,33 +326,34 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t
     }
 
     if (!e->memchunk.memblock)
     }
 
     if (!e->memchunk.memblock)
-        return -1;
+        goto fail;
 
     pa_log_debug("Playing sample \"%s\" on \"%s\"", name, sink->name);
 
 
     pa_log_debug("Playing sample \"%s\" on \"%s\"", name, sink->name);
 
-    pass_volume = TRUE;
+    pass_volume = true;
 
 
-    if (e->volume_is_set && volume != (pa_volume_t) -1) {
+    if (e->volume_is_set && PA_VOLUME_IS_VALID(volume)) {
         pa_cvolume_set(&r, e->sample_spec.channels, volume);
         pa_sw_cvolume_multiply(&r, &r, &e->volume);
     } else if (e->volume_is_set)
         r = e->volume;
         pa_cvolume_set(&r, e->sample_spec.channels, volume);
         pa_sw_cvolume_multiply(&r, &r, &e->volume);
     } else if (e->volume_is_set)
         r = e->volume;
-    else if (volume != (pa_volume_t) -1)
+    else if (PA_VOLUME_IS_VALID(volume))
         pa_cvolume_set(&r, e->sample_spec.channels, volume);
     else
         pa_cvolume_set(&r, e->sample_spec.channels, volume);
     else
-        pass_volume = FALSE;
+        pass_volume = false;
 
 
-    merged = pa_proplist_new();
-    pa_proplist_setf(merged, PA_PROP_MEDIA_NAME, "Sample %s", name);
     pa_proplist_update(merged, PA_UPDATE_REPLACE, e->proplist);
 
     if (p)
         pa_proplist_update(merged, PA_UPDATE_REPLACE, p);
 
     pa_proplist_update(merged, PA_UPDATE_REPLACE, e->proplist);
 
     if (p)
         pa_proplist_update(merged, PA_UPDATE_REPLACE, p);
 
-    if (pa_play_memchunk(sink, &e->sample_spec, &e->channel_map, &e->memchunk, pass_volume ? &r : NULL, merged, sink_input_idx) < 0) {
-        pa_proplist_free(merged);
-        return -1;
-    }
+    if (pa_play_memchunk(sink,
+                         &e->sample_spec, &e->channel_map,
+                         &e->memchunk,
+                         pass_volume ? &r : NULL,
+                         merged,
+                         PA_SINK_INPUT_NO_CREATE_ON_SUSPEND|PA_SINK_INPUT_KILL_ON_SUSPEND, sink_input_idx) < 0)
+        goto fail;
 
     pa_proplist_free(merged);
 
 
     pa_proplist_free(merged);
 
@@ -362,6 +361,10 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t
         time(&e->last_used_time);
 
     return 0;
         time(&e->last_used_time);
 
     return 0;
+
+fail:
+    pa_proplist_free(merged);
+    return -1;
 }
 
 int pa_scache_play_item_by_name(pa_core *c, const char *name, const char*sink_name, pa_volume_t volume, pa_proplist *p, uint32_t *sink_input_idx) {
 }
 
 int pa_scache_play_item_by_name(pa_core *c, const char *name, const char*sink_name, pa_volume_t volume, pa_proplist *p, uint32_t *sink_input_idx) {
@@ -410,7 +413,7 @@ size_t pa_scache_total_size(pa_core *c) {
     if (!c->scache || !pa_idxset_size(c->scache))
         return 0;
 
     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))
+    PA_IDXSET_FOREACH(e, c->scache, idx)
         if (e->memchunk.memblock)
             sum += e->memchunk.length;
 
         if (e->memchunk.memblock)
             sum += e->memchunk.length;
 
@@ -429,7 +432,7 @@ void pa_scache_unload_unused(pa_core *c) {
 
     time(&now);
 
 
     time(&now);
 
-    for (e = pa_idxset_first(c->scache, &idx); e; e = pa_idxset_next(c->scache, &idx)) {
+    PA_IDXSET_FOREACH(e, c->scache, idx) {
 
         if (!e->lazy || !e->memchunk.memblock)
             continue;
 
         if (!e->lazy || !e->memchunk.memblock)
             continue;
@@ -493,13 +496,14 @@ int pa_scache_add_directory_lazy(pa_core *c, const char *pathname) {
         struct dirent *e;
 
         while ((e = readdir(dir))) {
         struct dirent *e;
 
         while ((e = readdir(dir))) {
-            char p[PATH_MAX];
+            char *p;
 
             if (e->d_name[0] == '.')
                 continue;
 
 
             if (e->d_name[0] == '.')
                 continue;
 
-            pa_snprintf(p, sizeof(p), "%s/%s", pathname, e->d_name);
+            p = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", pathname, e->d_name);
             add_file(c, p);
             add_file(c, p);
+            pa_xfree(p);
         }
 
         closedir(dir);
         }
 
         closedir(dir);