media_cache: Don't lock when curl the remote file

When playing a remote sound file, which is not in cache, first we need
to download it with ast_bucket_file_retrieve.

This can take a while if the remote host is slow. The current CURL
timeout is 180secs, so in extreme situations, it can take 3 minutes to
return.

Because ast_media_cache_retrieve has a lock on all function, while we
are waiting for the delayed download, Asterisk is not able to play any
more files, even the files already cached locally.

ASTERISK-29544 #close

Change-Id: I8d4142b463ae4a1d4c41bff2bf63324821567408
This commit is contained in:
Andre Barbosa 2021-08-05 17:55:33 +01:00 committed by George Joseph
parent b72425b1f0
commit eb486db3af
1 changed files with 25 additions and 2 deletions

View File

@ -157,13 +157,15 @@ int ast_media_cache_retrieve(const char *uri, const char *preferred_file_name,
char *file_path, size_t len)
{
struct ast_bucket_file *bucket_file;
struct ast_bucket_file *tmp_bucket_file;
char *ext;
SCOPED_AO2LOCK(media_lock, media_cache);
if (ast_strlen_zero(uri)) {
return -1;
}
ao2_lock(media_cache);
ast_debug(5, "Looking for media at local cache, file: %s\n", uri);
/* First, retrieve from the ao2 cache here. If we find a bucket_file
* matching the requested URI, ask the appropriate backend if it is
* stale. If not; return it.
@ -179,6 +181,7 @@ int ast_media_cache_retrieve(const char *uri, const char *preferred_file_name,
ao2_ref(bucket_file, -1);
ast_debug(5, "Returning media at local file: %s\n", file_path);
ao2_unlock(media_cache);
return 0;
}
@ -187,6 +190,10 @@ int ast_media_cache_retrieve(const char *uri, const char *preferred_file_name,
ast_bucket_file_delete(bucket_file);
ao2_ref(bucket_file, -1);
}
/* We unlock to retrieve the file, because it can take a long time;
* and we don't want to lock access to cached files while waiting
*/
ao2_unlock(media_cache);
/* Either this is new or the resource is stale; do a full retrieve
* from the appropriate bucket_file backend
@ -197,6 +204,21 @@ int ast_media_cache_retrieve(const char *uri, const char *preferred_file_name,
return -1;
}
/* we lock again, before updating cache */
ao2_lock(media_cache);
/* We can have duplicated buckets here, we check if already exists
* before saving
*/
tmp_bucket_file = ao2_find(media_cache, uri, OBJ_SEARCH_KEY | OBJ_NOLOCK);
if (tmp_bucket_file) {
ao2_ref(tmp_bucket_file, -1);
ast_bucket_file_delete(bucket_file);
ao2_ref(bucket_file, -1);
ao2_unlock(media_cache);
return 0;
}
/* We can manipulate the 'immutable' bucket_file here, as we haven't
* let anyone know of its existence yet
*/
@ -210,6 +232,7 @@ int ast_media_cache_retrieve(const char *uri, const char *preferred_file_name,
ao2_ref(bucket_file, -1);
ast_debug(5, "Returning media at local file: %s\n", file_path);
ao2_unlock(media_cache);
return 0;
}