<p>George Joseph has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/10922">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">media_index.c: Refactored so it doesn't cache the index<br><br>Testing revealed that the cache added no benefit but that it could<br>consume excessive memory.<br><br>Two new index related functions were created:<br>ast_sounds_get_index_for_file() and ast_media_index_update_for_file()<br>which restrict index updating to specific sound files.<br><br>The original ast_sounds_get_index() and ast_media_index_update()<br>calls are still available but since they no longer cache the results<br>internally, developers should re-use an index they may already have<br>instead of calling ast_sounds_get_index() repeatedly. If information<br>for only a single file is needed, ast_sounds_get_index_for_file()<br>should be called instead of ast_sounds_get_index().<br><br>The media_index directory scan code was elimininated in favor of<br>using the existing ast_file_read_dirs() function.<br><br>Since there's no more cache, ast_sounds_index_init now only<br>registers the sounds cli commands instead of generating the<br>initial index and subscribing to stasis format register/unregister<br>messages.<br><br>ast_sounds_reindex() is now a no-op but left for backwards<br>compatibility.<br><br>loader.c no longer registers "sounds" as a special reload target.<br><br>Both the sounds cli commands and the sounds ari resources were<br>refactored to only call ast_sounds_get_index() once per invocation<br>and to use ast_sounds_get_index_for_file() when a specific sound<br>file is requested.<br><br>Change-Id: I1cef327ba1b0648d85d218b70ce469ad07f4aa8d<br>---<br>M CHANGES<br>M include/asterisk/media_index.h<br>M include/asterisk/sounds_index.h<br>M main/loader.c<br>M main/media_index.c<br>M main/sounds.c<br>M res/ari/resource_sounds.c<br>7 files changed, 279 insertions(+), 207 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/22/10922/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/CHANGES b/CHANGES</span><br><span>index da58f29..5cd3d4c 100644</span><br><span>--- a/CHANGES</span><br><span>+++ b/CHANGES</span><br><span>@@ -17,6 +17,19 @@</span><br><span> * Added "send_contact_status_on_update_registration" global configuration option</span><br><span> to enable sending AMI ContactStatus event when a device refreshes its registration.</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+Core</span><br><span style="color: hsl(120, 100%, 40%);">+------------------</span><br><span style="color: hsl(120, 100%, 40%);">+ * Reworked the media indexer so it doesn't cache the index. Testing revealed</span><br><span style="color: hsl(120, 100%, 40%);">+ that the cache added no benefit but that it could consume excessive memory.</span><br><span style="color: hsl(120, 100%, 40%);">+ Two new index related functions were created: ast_sounds_get_index_for_file()</span><br><span style="color: hsl(120, 100%, 40%);">+ and ast_media_index_update_for_file() which restrict index updating to</span><br><span style="color: hsl(120, 100%, 40%);">+ specific sound files. The original ast_sounds_get_index() and</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_media_index_update() calls are still available but since they no longer</span><br><span style="color: hsl(120, 100%, 40%);">+ cache the results internally, developers should re-use an index they may</span><br><span style="color: hsl(120, 100%, 40%);">+ already have instead of calling ast_sounds_get_index() repeatedly. If</span><br><span style="color: hsl(120, 100%, 40%);">+ information for only a single file is needed, ast_sounds_get_index_for_file()</span><br><span style="color: hsl(120, 100%, 40%);">+ should be called instead of ast_sounds_get_index().</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> Features</span><br><span> ------------------</span><br><span> * Before Asterisk 12, when using the automon or automixmon features defined</span><br><span>diff --git a/include/asterisk/media_index.h b/include/asterisk/media_index.h</span><br><span>index 40fb721..f3a95a6 100644</span><br><span>--- a/include/asterisk/media_index.h</span><br><span>+++ b/include/asterisk/media_index.h</span><br><span>@@ -101,6 +101,26 @@</span><br><span> */</span><br><span> int ast_media_index_update(struct ast_media_index *index,</span><br><span> const char *variant);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Update a media index for a specific sound file</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 13.25.0</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 16.2.0</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param index Media index in which to query information</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param variant Media variant for which to get the description</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param filename Sound file name without extension</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \note If filename is NULL, this function will act as</span><br><span style="color: hsl(120, 100%, 40%);">+ * \ref ast_media_index_update and add all sound files to the index.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval non-zero on error</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return zero on success</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_media_index_update_for_file(struct ast_media_index *index,</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *variant, const char *filename);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #if defined(__cplusplus) || defined(c_plusplus)</span><br><span> }</span><br><span> #endif</span><br><span>diff --git a/include/asterisk/sounds_index.h b/include/asterisk/sounds_index.h</span><br><span>index d7eb053..dad54a0 100644</span><br><span>--- a/include/asterisk/sounds_index.h</span><br><span>+++ b/include/asterisk/sounds_index.h</span><br><span>@@ -34,9 +34,11 @@</span><br><span> </span><br><span> /*!</span><br><span> * \brief Reload the sounds index</span><br><span style="color: hsl(120, 100%, 40%);">+ * \deprecated</span><br><span> *</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval zero on success</span><br><span style="color: hsl(0, 100%, 40%);">- * \retval non-zero on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is a NoOp and will be removed in a future release.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval zero</span><br><span> */</span><br><span> int ast_sounds_reindex(void);</span><br><span> </span><br><span>@@ -48,6 +50,19 @@</span><br><span> */</span><br><span> struct ast_media_index *ast_sounds_get_index(void);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Get the index for a specific sound file</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 13.25.0</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 16.2.0</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param filename Sound file name without extension</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval sounds index (must be ao2_cleanup()'ed)</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval NULL on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+struct ast_media_index *ast_sounds_get_index_for_file(const char *filename);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #if defined(__cplusplus) || defined(c_plusplus)</span><br><span> }</span><br><span> #endif</span><br><span>diff --git a/main/loader.c b/main/loader.c</span><br><span>index ff6b282..da8fcf2 100644</span><br><span>--- a/main/loader.c</span><br><span>+++ b/main/loader.c</span><br><span>@@ -56,7 +56,6 @@</span><br><span> #include "asterisk/vector.h"</span><br><span> #include "asterisk/app.h"</span><br><span> #include "asterisk/test.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/sounds_index.h"</span><br><span> #include "asterisk/cli.h"</span><br><span> </span><br><span> #include <dlfcn.h></span><br><span>@@ -376,7 +375,6 @@</span><br><span> { "logger", logger_reload },</span><br><span> { "manager", reload_manager },</span><br><span> { "plc", ast_plc_reload },</span><br><span style="color: hsl(0, 100%, 40%);">- { "sounds", ast_sounds_reindex },</span><br><span> { "udptl", ast_udptl_reload },</span><br><span> { NULL, NULL }</span><br><span> };</span><br><span>diff --git a/main/media_index.c b/main/media_index.c</span><br><span>index 2d1bc6b..67396e7 100644</span><br><span>--- a/main/media_index.c</span><br><span>+++ b/main/media_index.c</span><br><span>@@ -380,7 +380,8 @@</span><br><span> static int process_description_file(struct ast_media_index *index,</span><br><span> const char *subdir,</span><br><span> const char *variant_str,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *filename)</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *filename,</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *match_filename)</span><br><span> {</span><br><span> RAII_VAR(struct ast_str *, description_file_path, ast_str_create(64), ast_free);</span><br><span> RAII_VAR(struct ast_str *, cumulative_description, ast_str_create(64), ast_free);</span><br><span>@@ -450,16 +451,21 @@</span><br><span> if (file_id_persist && !ast_strlen_zero(ast_str_buffer(cumulative_description))) {</span><br><span> struct media_variant *variant;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- variant = alloc_variant(index, file_id_persist, variant_str);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!variant) {</span><br><span style="color: hsl(0, 100%, 40%);">- res = -1;</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * If we were only searching for a specific sound filename</span><br><span style="color: hsl(120, 100%, 40%);">+ * don't include others.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_strlen_zero(match_filename) || strcmp(match_filename, file_id_persist) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ variant = alloc_variant(index, file_id_persist, variant_str);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!variant) {</span><br><span style="color: hsl(120, 100%, 40%);">+ res = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_string_field_set(variant, description, ast_str_buffer(cumulative_description));</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(variant, -1);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ast_string_field_set(variant, description, ast_str_buffer(cumulative_description));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> ast_str_reset(cumulative_description);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_ref(variant, -1);</span><br><span> }</span><br><span> </span><br><span> ast_free(file_id_persist);</span><br><span>@@ -473,12 +479,18 @@</span><br><span> if (file_id_persist && !ast_strlen_zero(ast_str_buffer(cumulative_description))) {</span><br><span> struct media_variant *variant;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- variant = alloc_variant(index, file_id_persist, variant_str);</span><br><span style="color: hsl(0, 100%, 40%);">- if (variant) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_string_field_set(variant, description, ast_str_buffer(cumulative_description));</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_ref(variant, -1);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- res = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * If we were only searching for a specific sound filename</span><br><span style="color: hsl(120, 100%, 40%);">+ * don't include others.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_strlen_zero(match_filename) || strcmp(match_filename, file_id_persist) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ variant = alloc_variant(index, file_id_persist, variant_str);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (variant) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_string_field_set(variant, description, ast_str_buffer(cumulative_description));</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(variant, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ res = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> }</span><br><span> }</span><br><span> </span><br><span>@@ -487,110 +499,121 @@</span><br><span> return res;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/*! \brief process an individual file listing */</span><br><span style="color: hsl(0, 100%, 40%);">-static int process_file(struct ast_media_index *index, const char *variant_str, const char *subdir, const char *filename)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- RAII_VAR(char *, filename_stripped, ast_strdup(filename), ast_free);</span><br><span style="color: hsl(0, 100%, 40%);">- char *ext;</span><br><span style="color: hsl(120, 100%, 40%);">+struct read_dirs_data {</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *search_filename;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t search_filename_len;</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *search_variant;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_media_index *index;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t dirname_len;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (!filename_stripped) {</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+static int read_dirs_cb(const char *dir_name, const char *filename, void *obj)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct read_dirs_data *data = obj;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *ext;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t match_len;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *match;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t match_base_len;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *subdirs = (char *)dir_name + data->dirname_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Example:</span><br><span style="color: hsl(120, 100%, 40%);">+ * From the filesystem:</span><br><span style="color: hsl(120, 100%, 40%);">+ * index's base_dir = "/var/lib/asterisk/sounds"</span><br><span style="color: hsl(120, 100%, 40%);">+ * search_variant = "en"</span><br><span style="color: hsl(120, 100%, 40%);">+ * search directory base = "/var/lib/asterisk/sounds/en"</span><br><span style="color: hsl(120, 100%, 40%);">+ * dirname_len = 27</span><br><span style="color: hsl(120, 100%, 40%);">+ * current dir_name = "/var/lib/asterisk/sounds/en/digits"</span><br><span style="color: hsl(120, 100%, 40%);">+ * subdirs = "/digits"</span><br><span style="color: hsl(120, 100%, 40%);">+ * filename = "1.ulaw"</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * From the search criteria:</span><br><span style="color: hsl(120, 100%, 40%);">+ * search_filename = "digits/1"</span><br><span style="color: hsl(120, 100%, 40%);">+ * search_filename_len = 8</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (*subdirs == '/') {</span><br><span style="color: hsl(120, 100%, 40%);">+ subdirs++;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ext = strrchr(filename_stripped, '.');</span><br><span style="color: hsl(120, 100%, 40%);">+ /* subdirs = "digits" */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ match_len = strlen(subdirs) + strlen(filename) + 2;</span><br><span style="color: hsl(120, 100%, 40%);">+ match = ast_alloca(match_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ snprintf(match, match_len, "%s%s%s", subdirs,</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_strlen_zero(subdirs) ? "" : "/", filename);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* match = discovered filename relative to language = "digits/1.ulaw" */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ext = strrchr(match, '.');</span><br><span> if (!ext) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* file has no extension */</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- *ext++ = '\0';</span><br><span style="color: hsl(0, 100%, 40%);">- if (!strcmp(ext, "txt")) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (process_description_file(index, subdir, variant_str, filename)) {</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- if (process_media_file(index, variant_str, subdir, filename_stripped, ext)) {</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* ext = ".ulaw" */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (data->search_filename_len > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ match_base_len = ext - match;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * match_base_len = length of "digits/1" = 8 which</span><br><span style="color: hsl(120, 100%, 40%);">+ * happens to match the length of search_filename.</span><br><span style="color: hsl(120, 100%, 40%);">+ * However if the discovered filename was 11.ulaw</span><br><span style="color: hsl(120, 100%, 40%);">+ * it would be length of "digits/11" = 9.</span><br><span style="color: hsl(120, 100%, 40%);">+ * We need to use the larger during the compare to</span><br><span style="color: hsl(120, 100%, 40%);">+ * make sure we don't match just search_filename</span><br><span style="color: hsl(120, 100%, 40%);">+ * as a substring of the discovered filename.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (data->search_filename_len > match_base_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+ match_base_len = data->search_filename_len;</span><br><span> }</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* We always process txt files because they should contain description. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (strcmp(ext, ".txt") == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (process_description_file(data->index, NULL, data->search_variant,</span><br><span style="color: hsl(120, 100%, 40%);">+ match, data->search_filename)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (data->search_filename_len == 0</span><br><span style="color: hsl(120, 100%, 40%);">+ || strncmp(data->search_filename, match, match_base_len ) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ *ext = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+ ext++;</span><br><span style="color: hsl(120, 100%, 40%);">+ process_media_file(data->index, data->search_variant, NULL, match, ext);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/*! \brief internal function for updating the index, recursive */</span><br><span style="color: hsl(0, 100%, 40%);">-static int media_index_update(struct ast_media_index *index,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *variant,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *subdir)</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_media_index_update_for_file(struct ast_media_index *index,</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *variant, const char *filename)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- struct dirent* dent;</span><br><span style="color: hsl(0, 100%, 40%);">- DIR* srcdir;</span><br><span style="color: hsl(0, 100%, 40%);">- RAII_VAR(struct ast_str *, index_dir, ast_str_create(64), ast_free);</span><br><span style="color: hsl(0, 100%, 40%);">- RAII_VAR(struct ast_str *, statfile, ast_str_create(64), ast_free);</span><br><span style="color: hsl(0, 100%, 40%);">- int res = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct timeval start;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct timeval end;</span><br><span style="color: hsl(120, 100%, 40%);">+ int64_t elapsed;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t dirname_len = strlen(index->base_dir) + strlen(S_OR(variant, "")) + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct read_dirs_data data = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .search_filename = S_OR(filename, ""),</span><br><span style="color: hsl(120, 100%, 40%);">+ .search_filename_len = strlen(S_OR(filename, "")),</span><br><span style="color: hsl(120, 100%, 40%);">+ .search_variant = S_OR(variant, ""),</span><br><span style="color: hsl(120, 100%, 40%);">+ .index = index,</span><br><span style="color: hsl(120, 100%, 40%);">+ .dirname_len = dirname_len,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+ char *search_dir = ast_alloca(dirname_len + 1);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (!index_dir) {</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(120, 100%, 40%);">+ sprintf(search_dir, "%s%s%s", index->base_dir, ast_strlen_zero(variant) ? "" : "/",</span><br><span style="color: hsl(120, 100%, 40%);">+ data.search_variant);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_set(&index_dir, 0, "%s", index->base_dir);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_strlen_zero(variant)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_append(&index_dir, 0, "/%s", variant);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_strlen_zero(subdir)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_append(&index_dir, 0, "/%s", subdir);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(120, 100%, 40%);">+ gettimeofday(&start, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = ast_file_read_dirs(search_dir, read_dirs_cb, &data, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ gettimeofday(&end, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ elapsed = ast_tvdiff_us(end, start);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(1, "Media for language '%s' indexed in %8.6f seconds\n", data.search_variant, elapsed / 1E6);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- srcdir = opendir(ast_str_buffer(index_dir));</span><br><span style="color: hsl(0, 100%, 40%);">- if (srcdir == NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Failed to open %s: %s\n", ast_str_buffer(index_dir), strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- while((dent = readdir(srcdir)) != NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">- struct stat st;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) {</span><br><span style="color: hsl(0, 100%, 40%);">- continue;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_reset(statfile);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_set(&statfile, 0, "%s/%s", ast_str_buffer(index_dir), dent->d_name);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (stat(ast_str_buffer(statfile), &st) < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Failed to stat %s: %s\n", ast_str_buffer(statfile), strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">- continue;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (S_ISDIR(st.st_mode)) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_strlen_zero(subdir)) {</span><br><span style="color: hsl(0, 100%, 40%);">- res = media_index_update(index, variant, dent->d_name);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- RAII_VAR(struct ast_str *, new_subdir, ast_str_create(64), ast_free);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_set(&new_subdir, 0, "%s/%s", subdir, dent->d_name);</span><br><span style="color: hsl(0, 100%, 40%);">- res = media_index_update(index, variant, ast_str_buffer(new_subdir));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (res) {</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- continue;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!S_ISREG(st.st_mode)) {</span><br><span style="color: hsl(0, 100%, 40%);">- continue;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (process_file(index, variant, subdir, dent->d_name)) {</span><br><span style="color: hsl(0, 100%, 40%);">- res = -1;</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- closedir(srcdir);</span><br><span style="color: hsl(0, 100%, 40%);">- return res;</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int ast_media_index_update(struct ast_media_index *index,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *variant)</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_media_index_update(struct ast_media_index *index, const char *variant)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return media_index_update(index, variant, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ return ast_media_index_update_for_file(index, variant, NULL);</span><br><span> }</span><br><span>diff --git a/main/sounds.c b/main/sounds.c</span><br><span>index 6fec48e..c3666ed 100644</span><br><span>--- a/main/sounds.c</span><br><span>+++ b/main/sounds.c</span><br><span>@@ -45,10 +45,6 @@</span><br><span> /*! \brief The number of buckets to be used for storing language-keyed objects */</span><br><span> #define LANGUAGE_BUCKETS 7</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_media_index *sounds_index;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct stasis_message_router *sounds_system_router;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /*! \brief Get the languages in which sound files are available */</span><br><span> static struct ao2_container *get_languages(void)</span><br><span> {</span><br><span>@@ -97,52 +93,8 @@</span><br><span> return lang_dirs;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/*! \brief Callback to process an individual language directory or subdirectory */</span><br><span style="color: hsl(0, 100%, 40%);">-static int update_index_cb(void *obj, void *arg, int flags)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- char *lang = obj;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_media_index *index = arg;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_media_index_update(index, lang)) {</span><br><span style="color: hsl(0, 100%, 40%);">- return CMP_MATCH;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-AST_MUTEX_DEFINE_STATIC(reload_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> int ast_sounds_reindex(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- RAII_VAR(struct ast_str *, sounds_dir, NULL, ast_free);</span><br><span style="color: hsl(0, 100%, 40%);">- RAII_VAR(struct ao2_container *, languages, NULL, ao2_cleanup);</span><br><span style="color: hsl(0, 100%, 40%);">- RAII_VAR(char *, failed_index, NULL, ao2_cleanup);</span><br><span style="color: hsl(0, 100%, 40%);">- RAII_VAR(struct ast_media_index *, new_index, NULL, ao2_cleanup);</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_media_index *old_index;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- SCOPED_MUTEX(lock, &reload_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- old_index = sounds_index;</span><br><span style="color: hsl(0, 100%, 40%);">- languages = get_languages();</span><br><span style="color: hsl(0, 100%, 40%);">- sounds_dir = ast_str_create(64);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!languages || !sounds_dir) {</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_set(&sounds_dir, 0, "%s/sounds", ast_config_AST_DATA_DIR);</span><br><span style="color: hsl(0, 100%, 40%);">- new_index = ast_media_index_create(ast_str_buffer(sounds_dir));</span><br><span style="color: hsl(0, 100%, 40%);">- if (!new_index) {</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- failed_index = ao2_callback(languages, 0, update_index_cb, new_index);</span><br><span style="color: hsl(0, 100%, 40%);">- if (failed_index) {</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_ref(new_index, +1);</span><br><span style="color: hsl(0, 100%, 40%);">- sounds_index = new_index;</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_cleanup(old_index);</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span>@@ -154,13 +106,13 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int show_sound_info_cb(void *obj, void *arg, int flags)</span><br><span style="color: hsl(120, 100%, 40%);">+static int show_sound_info_cb(void *obj, void *arg, void *data, int flags)</span><br><span> {</span><br><span> char *language = obj;</span><br><span> struct ast_cli_args *a = arg;</span><br><span> struct ast_format *format;</span><br><span> int formats_shown = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- RAII_VAR(struct ast_media_index *, local_index, ast_sounds_get_index(), ao2_cleanup);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_media_index *local_index = data;</span><br><span> struct ast_format_cap *cap;</span><br><span> const char *description = ast_media_get_description(local_index, a->argv[3], language);</span><br><span> </span><br><span>@@ -203,13 +155,23 @@</span><br><span> }</span><br><span> </span><br><span> if (a->argc == 3) {</span><br><span style="color: hsl(0, 100%, 40%);">- RAII_VAR(struct ao2_container *, sound_files, ast_media_get_media(sounds_index), ao2_cleanup);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_media_index *sounds_index = ast_sounds_get_index();</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ao2_container *sound_files;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!sounds_index) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return CLI_FAILURE;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ sound_files = ast_media_get_media(sounds_index);</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(sounds_index, -1);</span><br><span> if (!sound_files) {</span><br><span> return CLI_FAILURE;</span><br><span> }</span><br><span> </span><br><span> ast_cli(a->fd, "Available audio files:\n");</span><br><span> ao2_callback(sound_files, OBJ_MULTIPLE | OBJ_NODATA, show_sounds_cb, a);</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(sound_files, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> return CLI_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -222,6 +184,7 @@</span><br><span> int length;</span><br><span> struct ao2_iterator it_sounds;</span><br><span> char *filename;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_media_index *sounds_index;</span><br><span> struct ao2_container *sound_files;</span><br><span> </span><br><span> switch (cmd) {</span><br><span>@@ -236,7 +199,13 @@</span><br><span> return NULL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ sounds_index = ast_sounds_get_index();</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!sounds_index) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> sound_files = ast_media_get_media(sounds_index);</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(sounds_index, -1);</span><br><span> if (!sound_files) {</span><br><span> return NULL;</span><br><span> }</span><br><span>@@ -259,14 +228,26 @@</span><br><span> }</span><br><span> </span><br><span> if (a->argc == 4) {</span><br><span style="color: hsl(0, 100%, 40%);">- RAII_VAR(struct ao2_container *, variants, ast_media_get_variants(sounds_index, a->argv[3]), ao2_cleanup);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ao2_container *variants;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ sounds_index = ast_sounds_get_index_for_file(a->argv[3]);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!sounds_index) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ variants = ast_media_get_variants(sounds_index, a->argv[3]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if (!variants || !ao2_container_count(variants)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(sounds_index, -1);</span><br><span> ast_cli(a->fd, "ERROR: File %s not found in index\n", a->argv[3]);</span><br><span> return CLI_FAILURE;</span><br><span> }</span><br><span> </span><br><span> ast_cli(a->fd, "Indexed Information for %s:\n", a->argv[3]);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_callback(variants, OBJ_MULTIPLE | OBJ_NODATA, show_sound_info_cb, a);</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_callback_data(variants, OBJ_MULTIPLE | OBJ_NODATA, show_sound_info_cb, a, sounds_index);</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(sounds_index, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(variants, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> return CLI_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -281,60 +262,72 @@</span><br><span> </span><br><span> static void sounds_cleanup(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- stasis_message_router_unsubscribe_and_join(sounds_system_router);</span><br><span style="color: hsl(0, 100%, 40%);">- sounds_system_router = NULL;</span><br><span> ast_cli_unregister_multiple(cli_sounds, ARRAY_LEN(cli_sounds));</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_cleanup(sounds_index);</span><br><span style="color: hsl(0, 100%, 40%);">- sounds_index = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void format_update_cb(void *data, struct stasis_subscription *sub,</span><br><span style="color: hsl(0, 100%, 40%);">- struct stasis_message *message)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- /* Reindexing during shutdown is pointless. */</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_shutting_down()) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_sounds_reindex();</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span> }</span><br><span> </span><br><span> int ast_sounds_index_init(void)</span><br><span> {</span><br><span> int res = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_sounds_reindex()) {</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- res |= ast_cli_register_multiple(cli_sounds, ARRAY_LEN(cli_sounds));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- sounds_system_router = stasis_message_router_create(ast_system_topic());</span><br><span style="color: hsl(0, 100%, 40%);">- if (!sounds_system_router) {</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_format_register_type()) {</span><br><span style="color: hsl(0, 100%, 40%);">- res |= stasis_message_router_add(</span><br><span style="color: hsl(0, 100%, 40%);">- sounds_system_router,</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_register_type(),</span><br><span style="color: hsl(0, 100%, 40%);">- format_update_cb,</span><br><span style="color: hsl(0, 100%, 40%);">- NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_format_unregister_type()) {</span><br><span style="color: hsl(0, 100%, 40%);">- res |= stasis_message_router_add(</span><br><span style="color: hsl(0, 100%, 40%);">- sounds_system_router,</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_unregister_type(),</span><br><span style="color: hsl(0, 100%, 40%);">- format_update_cb,</span><br><span style="color: hsl(0, 100%, 40%);">- NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+ res = ast_cli_register_multiple(cli_sounds, ARRAY_LEN(cli_sounds));</span><br><span> if (res) {</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span> }</span><br><span> </span><br><span> ast_register_cleanup(sounds_cleanup);</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief Callback to process an individual language directory or subdirectory */</span><br><span style="color: hsl(120, 100%, 40%);">+static int update_index_cb(void *obj, void *arg, void *data, int flags)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char *lang = obj;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *filename = data;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_media_index *index = arg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_media_index_update_for_file(index, lang, filename)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMP_MATCH;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct ast_media_index *ast_sounds_get_index(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return ao2_bump(sounds_index);</span><br><span style="color: hsl(120, 100%, 40%);">+ return ast_sounds_get_index_for_file(NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct ast_media_index *ast_sounds_get_index_for_file(const char *filename)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_str *sounds_dir = ast_str_create(64);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ao2_container *languages;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *failed_index;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_media_index *new_index;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!sounds_dir) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_str_set(&sounds_dir, 0, "%s/sounds", ast_config_AST_DATA_DIR);</span><br><span style="color: hsl(120, 100%, 40%);">+ new_index = ast_media_index_create(ast_str_buffer(sounds_dir));</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_free(sounds_dir);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!new_index) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ languages = get_languages();</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!languages) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(new_index, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ failed_index = ao2_callback_data(languages, 0, update_index_cb, new_index, (void *)filename);</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(languages, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (failed_index) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_ref(new_index, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ new_index = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_cleanup(failed_index);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return new_index;</span><br><span> }</span><br><span>diff --git a/res/ari/resource_sounds.c b/res/ari/resource_sounds.c</span><br><span>index 76a4d94..0f52a22 100644</span><br><span>--- a/res/ari/resource_sounds.c</span><br><span>+++ b/res/ari/resource_sounds.c</span><br><span>@@ -42,13 +42,13 @@</span><br><span> };</span><br><span> </span><br><span> /*! \brief Add format/lang pairs to the array embedded in the sound object */</span><br><span style="color: hsl(0, 100%, 40%);">-static int add_format_information_cb(void *obj, void *arg, int flags)</span><br><span style="color: hsl(120, 100%, 40%);">+static int add_format_information_cb(void *obj, void *arg, void *data, int flags)</span><br><span> {</span><br><span> char *language = obj;</span><br><span> struct lang_format_info *args = arg;</span><br><span> int idx;</span><br><span> RAII_VAR(struct ast_format_cap *, cap, NULL, ao2_cleanup);</span><br><span style="color: hsl(0, 100%, 40%);">- RAII_VAR(struct ast_media_index *, sounds_index, ast_sounds_get_index(), ao2_cleanup);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_media_index *sounds_index = data;</span><br><span> </span><br><span> if (!sounds_index) {</span><br><span> return CMP_STOP;</span><br><span>@@ -97,14 +97,13 @@</span><br><span> </span><br><span> /*! \brief Generate a Sound structure as documented in sounds.json for the specified filename */</span><br><span> static struct ast_json *create_sound_blob(const char *filename,</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_ari_sounds_list_args *args)</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_ari_sounds_list_args *args, struct ast_media_index *sounds_index)</span><br><span> {</span><br><span> RAII_VAR(struct ast_json *, sound, NULL, ast_json_unref);</span><br><span> RAII_VAR(struct ao2_container *, languages, NULL, ao2_cleanup);</span><br><span> const char *description;</span><br><span> struct ast_json *format_lang_list;</span><br><span> struct lang_format_info info;</span><br><span style="color: hsl(0, 100%, 40%);">- RAII_VAR(struct ast_media_index *, sounds_index, ast_sounds_get_index(), ao2_cleanup);</span><br><span> </span><br><span> if (!sounds_index) {</span><br><span> return NULL;</span><br><span>@@ -150,7 +149,7 @@</span><br><span> if (args) {</span><br><span> info.format_filter = args->format;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_callback(languages, OBJ_NODATA, add_format_information_cb, &info);</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_callback_data(languages, OBJ_NODATA, add_format_information_cb, &info, sounds_index);</span><br><span> </span><br><span> /* no format/lang pairs for this sound so nothing to return */</span><br><span> if (!ast_json_array_size(format_lang_list)) {</span><br><span>@@ -160,13 +159,18 @@</span><br><span> return ast_json_ref(sound);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct sounds_cb_data {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_ari_sounds_list_args *args;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_media_index *index;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! \brief Generate a Sound structure and append it to the output blob */</span><br><span> static int append_sound_cb(void *obj, void *arg, void *data, int flags)</span><br><span> {</span><br><span> struct ast_json *sounds_array = arg;</span><br><span> char *filename = obj;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_ari_sounds_list_args *args = data;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_json *sound_blob = create_sound_blob(filename, args);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sounds_cb_data *cb_data = data;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_json *sound_blob = create_sound_blob(filename, cb_data->args, cb_data->index);</span><br><span> if (!sound_blob) {</span><br><span> return 0;</span><br><span> }</span><br><span>@@ -182,6 +186,10 @@</span><br><span> RAII_VAR(struct ao2_container *, sound_files, NULL, ao2_cleanup);</span><br><span> struct ast_json *sounds_blob;</span><br><span> RAII_VAR(struct ast_media_index *, sounds_index, ast_sounds_get_index(), ao2_cleanup);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sounds_cb_data cb_data = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .args = args,</span><br><span style="color: hsl(120, 100%, 40%);">+ .index = sounds_index,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span> </span><br><span> if (!sounds_index) {</span><br><span> ast_ari_response_error(response, 500, "Internal Error", "Sounds index not available");</span><br><span>@@ -200,7 +208,7 @@</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ao2_callback_data(sound_files, OBJ_NODATA, append_sound_cb, sounds_blob, args);</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_callback_data(sound_files, OBJ_NODATA, append_sound_cb, sounds_blob, &cb_data);</span><br><span> </span><br><span> if (!ast_json_array_size(sounds_blob)) {</span><br><span> ast_ari_response_error(response, 404, "Not Found", "No sounds found that matched the query");</span><br><span>@@ -216,8 +224,10 @@</span><br><span> struct ast_ari_response *response)</span><br><span> {</span><br><span> struct ast_json *sound_blob;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_media_index *sounds_index = ast_sounds_get_index_for_file(args->sound_id);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- sound_blob = create_sound_blob(args->sound_id, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ sound_blob = create_sound_blob(args->sound_id, NULL, sounds_index);</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_cleanup(sounds_index);</span><br><span> if (!sound_blob) {</span><br><span> ast_ari_response_error(response, 404, "Not Found", "Sound not found");</span><br><span> return;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/10922">change 10922</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/10922"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I1cef327ba1b0648d85d218b70ce469ad07f4aa8d </div>
<div style="display:none"> Gerrit-Change-Number: 10922 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: George Joseph <gjoseph@digium.com> </div>