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:
parent
e01a6c026d
commit
2451dfd89f
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue