movies: fix crash on simultaneous threaded audio/video load

This commit is contained in:
rdb 2018-09-23 14:22:41 +02:00
parent a3a7c0cf9d
commit 3ac50a2347
2 changed files with 18 additions and 0 deletions

View File

@ -29,6 +29,8 @@ PT(MovieAudio) MovieTypeRegistry::
make_audio(const Filename &name) { make_audio(const Filename &name) {
string ext = downcase(name.get_extension()); string ext = downcase(name.get_extension());
_audio_lock.lock();
// Make sure that the list of audio types has been read in. // Make sure that the list of audio types has been read in.
load_audio_types(); load_audio_types();
@ -41,6 +43,7 @@ make_audio(const Filename &name) {
// Explicit extension is preferred over catch-all. // Explicit extension is preferred over catch-all.
if (_audio_type_registry.count(ext)) { if (_audio_type_registry.count(ext)) {
MakeAudioFunc func = _audio_type_registry[ext]; MakeAudioFunc func = _audio_type_registry[ext];
_audio_lock.unlock();
return (*func)(name); return (*func)(name);
} }
@ -53,12 +56,14 @@ make_audio(const Filename &name) {
if (_audio_type_registry.count("*")) { if (_audio_type_registry.count("*")) {
MakeAudioFunc func = _audio_type_registry["*"]; MakeAudioFunc func = _audio_type_registry["*"];
_audio_lock.unlock();
return (*func)(name); return (*func)(name);
} }
movies_cat.error() movies_cat.error()
<< "Support for audio files with extension ." << ext << " was not enabled.\n"; << "Support for audio files with extension ." << ext << " was not enabled.\n";
_audio_lock.unlock();
return new MovieAudio("Load-Failure Stub"); return new MovieAudio("Load-Failure Stub");
} }
@ -68,6 +73,7 @@ make_audio(const Filename &name) {
*/ */
void MovieTypeRegistry:: void MovieTypeRegistry::
register_audio_type(MakeAudioFunc func, const string &extensions) { register_audio_type(MakeAudioFunc func, const string &extensions) {
ReMutexHolder holder(_audio_lock);
vector_string words; vector_string words;
extract_words(downcase(extensions), words); extract_words(downcase(extensions), words);
@ -89,6 +95,7 @@ register_audio_type(MakeAudioFunc func, const string &extensions) {
*/ */
void MovieTypeRegistry:: void MovieTypeRegistry::
load_audio_types() { load_audio_types() {
ReMutexHolder holder(_audio_lock);
static bool audio_types_loaded = false; static bool audio_types_loaded = false;
if (!audio_types_loaded) { if (!audio_types_loaded) {
@ -145,6 +152,8 @@ PT(MovieVideo) MovieTypeRegistry::
make_video(const Filename &name) { make_video(const Filename &name) {
string ext = downcase(name.get_extension()); string ext = downcase(name.get_extension());
_video_lock.lock();
// Make sure that the list of video types has been read in. // Make sure that the list of video types has been read in.
load_video_types(); load_video_types();
@ -157,6 +166,7 @@ make_video(const Filename &name) {
// Explicit extension is preferred over catch-all. // Explicit extension is preferred over catch-all.
if (_video_type_registry.count(ext)) { if (_video_type_registry.count(ext)) {
MakeVideoFunc func = _video_type_registry[ext]; MakeVideoFunc func = _video_type_registry[ext];
_video_lock.unlock();
return (*func)(name); return (*func)(name);
} }
@ -169,12 +179,14 @@ make_video(const Filename &name) {
if (_video_type_registry.count("*")) { if (_video_type_registry.count("*")) {
MakeVideoFunc func = _video_type_registry["*"]; MakeVideoFunc func = _video_type_registry["*"];
_video_lock.unlock();
return (*func)(name); return (*func)(name);
} }
movies_cat.error() movies_cat.error()
<< "Support for video files with extension ." << ext << " was not enabled.\n"; << "Support for video files with extension ." << ext << " was not enabled.\n";
_video_lock.unlock();
return new MovieVideo("Load-Failure Stub"); return new MovieVideo("Load-Failure Stub");
} }
@ -184,6 +196,7 @@ make_video(const Filename &name) {
*/ */
void MovieTypeRegistry:: void MovieTypeRegistry::
register_video_type(MakeVideoFunc func, const string &extensions) { register_video_type(MakeVideoFunc func, const string &extensions) {
ReMutexHolder holder(_video_lock);
vector_string words; vector_string words;
extract_words(downcase(extensions), words); extract_words(downcase(extensions), words);
@ -205,6 +218,7 @@ register_video_type(MakeVideoFunc func, const string &extensions) {
*/ */
void MovieTypeRegistry:: void MovieTypeRegistry::
load_video_types() { load_video_types() {
ReMutexHolder holder(_video_lock);
static bool video_types_loaded = false; static bool video_types_loaded = false;
if (!video_types_loaded) { if (!video_types_loaded) {
@ -259,6 +273,7 @@ load_video_types() {
*/ */
void MovieTypeRegistry:: void MovieTypeRegistry::
load_movie_library(const string &name) { load_movie_library(const string &name) {
ReMutexHolder holder(_video_lock);
Filename dlname = Filename::dso_filename("lib" + name + ".so"); Filename dlname = Filename::dso_filename("lib" + name + ".so");
movies_cat.info() movies_cat.info()
<< "loading video type module: " << name << endl; << "loading video type module: " << name << endl;

View File

@ -19,6 +19,7 @@
#include "movieVideo.h" #include "movieVideo.h"
#include "filename.h" #include "filename.h"
#include "pmap.h" #include "pmap.h"
#include "reMutex.h"
/** /**
* This class records the different types of MovieAudio and MovieVideo that * This class records the different types of MovieAudio and MovieVideo that
@ -43,9 +44,11 @@ public:
private: private:
static MovieTypeRegistry *_global_ptr; static MovieTypeRegistry *_global_ptr;
ReMutex _audio_lock;
pmap<std::string, MakeAudioFunc> _audio_type_registry; pmap<std::string, MakeAudioFunc> _audio_type_registry;
pmap<std::string, std::string> _deferred_audio_types; pmap<std::string, std::string> _deferred_audio_types;
ReMutex _video_lock;
pmap<std::string, MakeVideoFunc> _video_type_registry; pmap<std::string, MakeVideoFunc> _video_type_registry;
pmap<std::string, std::string> _deferred_video_types; pmap<std::string, std::string> _deferred_video_types;
}; };