diff options
author | JP Cimalando <jpcima@users.noreply.github.com> | 2019-02-24 11:02:33 +0100 |
---|---|---|
committer | JP Cimalando <jpcima@users.noreply.github.com> | 2019-02-24 11:02:33 +0100 |
commit | 2e61743ff0092032c2f2590b8333cea55758fd13 (patch) | |
tree | 152c59035a986baa5488c23b6ac4844ff9eb95d5 /src/chips | |
parent | 48751ca040600d80e92deecbabe61804e01a8ae7 (diff) | |
download | libADLMIDI-2e61743ff0092032c2f2590b8333cea55758fd13.tar.gz libADLMIDI-2e61743ff0092032c2f2590b8333cea55758fd13.tar.bz2 libADLMIDI-2e61743ff0092032c2f2590b8333cea55758fd13.zip |
javaopl3: thread safe initialization and cleanup
Diffstat (limited to 'src/chips')
-rw-r--r-- | src/chips/common/mutex.hpp | 96 | ||||
-rw-r--r-- | src/chips/dosbox/dbopl.cpp | 44 | ||||
-rw-r--r-- | src/chips/java/JavaOPL3.hpp | 26 |
3 files changed, 123 insertions, 43 deletions
diff --git a/src/chips/common/mutex.hpp b/src/chips/common/mutex.hpp new file mode 100644 index 0000000..53d7b72 --- /dev/null +++ b/src/chips/common/mutex.hpp @@ -0,0 +1,96 @@ +/* + * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation + * + * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi> + * ADLMIDI Library API: Copyright (c) 2015-2019 Vitaly Novichkov <admin@wohlnet.ru> + * + * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: + * http://iki.fi/bisqwit/source/adlmidi.html + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#if !defined(_WIN32) +#include <pthread.h> +typedef pthread_mutex_t MutexNativeObject; +#else +#include <windows.h> +typedef CRITICAL_SECTION MutexNativeObject; +#endif + +class Mutex +{ +public: + Mutex(); + ~Mutex(); + void lock(); + void unlock(); +private: + MutexNativeObject m; + Mutex(const Mutex &); + Mutex &operator=(const Mutex &); +}; + +class MutexHolder +{ +public: + explicit MutexHolder(Mutex &m) : m(m) { m.lock(); } + ~MutexHolder() { m.unlock(); } +private: + Mutex &m; + MutexHolder(const MutexHolder &); + MutexHolder &operator=(const MutexHolder &); +}; + +#if !defined(_WIN32) +inline Mutex::Mutex() +{ + pthread_mutex_init(&m, NULL); +} + +inline Mutex::~Mutex() +{ + pthread_mutex_destroy(&m); +} + +inline void Mutex::lock() +{ + pthread_mutex_lock(&m); +} + +inline void Mutex::unlock() +{ + pthread_mutex_unlock(&m); +} +#else +inline Mutex::Mutex() +{ + InitializeCriticalSection(&m); +} + +inline Mutex::~Mutex() +{ + DeleteCriticalSection(&m); +} + +inline void Mutex::lock() +{ + EnterCriticalSection(&m); +} + +inline void Mutex::unlock() +{ + LeaveCriticalSection(&m); +} +#endif diff --git a/src/chips/dosbox/dbopl.cpp b/src/chips/dosbox/dbopl.cpp index 5260c37..d1ab82f 100644 --- a/src/chips/dosbox/dbopl.cpp +++ b/src/chips/dosbox/dbopl.cpp @@ -40,6 +40,7 @@ #include <vector> #include <memory> #include "dbopl.h" +#include "../common/mutex.hpp" #if defined(__GNUC__) && __GNUC__ > 3 #define INLINE inline __attribute__((__always_inline__)) @@ -83,37 +84,6 @@ #endif -struct NoCopy { - NoCopy() {} -private: - NoCopy(const NoCopy &); - NoCopy &operator=(const NoCopy &); -}; -#if !defined(_WIN32) -#include <pthread.h> -struct Mutex : NoCopy { - Mutex() { pthread_mutex_init(&m, NULL);} - ~Mutex() { pthread_mutex_destroy(&m); } - void lock() { pthread_mutex_lock(&m); } - void unlock() { pthread_mutex_unlock(&m); } - pthread_mutex_t m; -}; -#else -#include <windows.h> -struct Mutex : NoCopy { - Mutex() { InitializeCriticalSection(&m); } - ~Mutex() { DeleteCriticalSection(&m); } - void lock() { EnterCriticalSection(&m); } - void unlock() { LeaveCriticalSection(&m); } - CRITICAL_SECTION m; -}; -#endif -struct MutexHolder : NoCopy { - explicit MutexHolder(Mutex &m) : m(m) { m.lock(); } - ~MutexHolder() { m.unlock(); } - Mutex &m; -}; - namespace DBOPL { #define OPLRATE ((double)(14318180.0 / 288.0)) @@ -1344,10 +1314,14 @@ struct CacheEntry { Bit32u linearRates[76]; Bit32u attackRates[76]; }; -struct Cache : NoCopy { - ~Cache(); - Mutex mutex; - std::vector<CacheEntry *> entries; +struct Cache { + Cache() {} + ~Cache(); + Mutex mutex; + std::vector<CacheEntry *> entries; +private: + Cache(const Cache &); + Cache &operator=(const Cache &); }; static Cache cache; diff --git a/src/chips/java/JavaOPL3.hpp b/src/chips/java/JavaOPL3.hpp index a18266a..df71cab 100644 --- a/src/chips/java/JavaOPL3.hpp +++ b/src/chips/java/JavaOPL3.hpp @@ -47,6 +47,7 @@ #include <stdint.h> #include <string.h> #include <limits> +#include "../common/mutex.hpp" #ifndef UINT32_MAX #define UINT32_MAX 0xffffffffU @@ -602,6 +603,7 @@ private: void setRhythmMode(); static int InstanceCount; + static Mutex InstanceMutex; // OPLEmul interface public: @@ -614,6 +616,7 @@ public: OperatorDataStruct *OPL3::OperatorData; OPL3DataStruct *OPL3::OPL3Data; int OPL3::InstanceCount; +Mutex OPL3::InstanceMutex; void OPL3::Update(float *output, int numsamples) { while (numsamples--) { @@ -735,10 +738,13 @@ OPL3::OPL3(bool fullpan) nts = dam = dvb = ryt = bd = sd = tom = tc = hh = _new = connectionsel = 0; vibratoIndex = tremoloIndex = 0; - if (InstanceCount++ == 0) { - OPL3Data = new struct OPL3DataStruct; - OperatorData = new struct OperatorDataStruct; + MutexHolder lock(InstanceMutex); + if (InstanceCount++ == 0) + { + OPL3Data = new struct OPL3DataStruct; + OperatorData = new struct OperatorDataStruct; + } } initOperators(); @@ -770,12 +776,16 @@ OPL3::~OPL3() delete channels4op[array][channelNumber]; } } - if (--InstanceCount == 0) + { - delete OPL3Data; - OPL3Data = NULL; - delete OperatorData; - OperatorData = NULL; + MutexHolder lock(InstanceMutex); + if (--InstanceCount == 0) + { + delete OPL3Data; + OPL3Data = NULL; + delete OperatorData; + OperatorData = NULL; + } } } |