| @@ -864,7 +864,7 @@ void CarlaEngineProtectedData::processRackFull(float** const inBuf, const uint32 | |||
| { | |||
| EngineRackBuffers* const rack(bufAudio.rack); | |||
| const CarlaCriticalSection::Scope _cs2(rack->connectLock); | |||
| const CarlaCriticalSectionScope _cs2(rack->connectLock); | |||
| // connect input buffers | |||
| if (rack->connectedIn1.count() == 0) | |||
| @@ -520,7 +520,7 @@ public: | |||
| const float fixedValue(pData->param.getFixedValue(parameterId, value)); | |||
| fParams[parameterId].value = fixedValue; | |||
| const CarlaCriticalSection::Scope _cs(fShmControl.lock); | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeSetParameter); | |||
| fShmControl.writeInt(static_cast<int32_t>(parameterId)); | |||
| @@ -534,7 +534,7 @@ public: | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),); | |||
| const CarlaCriticalSection::Scope _cs(fShmControl.lock); | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeSetProgram); | |||
| fShmControl.writeInt(index); | |||
| @@ -547,7 +547,7 @@ public: | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),); | |||
| const CarlaCriticalSection::Scope _cs(fShmControl.lock); | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeSetMidiProgram); | |||
| fShmControl.writeInt(index); | |||
| @@ -769,7 +769,7 @@ public: | |||
| void activate() noexcept override | |||
| { | |||
| { | |||
| const CarlaCriticalSection::Scope _cs(fShmControl.lock); | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeSetParameter); | |||
| fShmControl.writeInt(PARAMETER_ACTIVE); | |||
| @@ -790,7 +790,7 @@ public: | |||
| void deactivate() noexcept override | |||
| { | |||
| { | |||
| const CarlaCriticalSection::Scope _cs(fShmControl.lock); | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeSetParameter); | |||
| fShmControl.writeInt(PARAMETER_ACTIVE); | |||
| @@ -852,7 +852,7 @@ public: | |||
| data2 = static_cast<char>(note.note); | |||
| data3 = static_cast<char>(note.velo); | |||
| const CarlaCriticalSection::Scope _cs(fShmControl.lock); | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent); | |||
| fShmControl.writeLong(0); | |||
| @@ -988,7 +988,7 @@ public: | |||
| if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param <= 0x5F) | |||
| { | |||
| const CarlaCriticalSection::Scope _cs(fShmControl.lock); | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent); | |||
| fShmControl.writeLong(event.time); | |||
| @@ -1083,7 +1083,7 @@ public: | |||
| data[j] = static_cast<char>(midiEvent.data[j]); | |||
| { | |||
| const CarlaCriticalSection::Scope _cs(fShmControl.lock); | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent); | |||
| fShmControl.writeLong(event.time); | |||
| @@ -1176,7 +1176,7 @@ public: | |||
| // Run plugin | |||
| { | |||
| const CarlaCriticalSection::Scope _cs(fShmControl.lock); | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeProcess); | |||
| fShmControl.commitWrite(); | |||
| @@ -1263,7 +1263,7 @@ public: | |||
| void bufferSizeChanged(const uint32_t newBufferSize) override | |||
| { | |||
| const CarlaCriticalSection::Scope _cs(fShmControl.lock); | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| resizeAudioPool(newBufferSize); | |||
| @@ -1274,7 +1274,7 @@ public: | |||
| void sampleRateChanged(const double newSampleRate) override | |||
| { | |||
| const CarlaCriticalSection::Scope _cs(fShmControl.lock); | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeSetSampleRate); | |||
| fShmControl.writeFloat(static_cast<float>(newSampleRate)); | |||
| @@ -1910,7 +1910,7 @@ public: | |||
| // init OSC | |||
| { | |||
| char shmIdStr[16+1] = { 0 }; | |||
| char shmIdStr[18+1] = { 0 }; | |||
| std::strncpy(shmIdStr, &fShmAudioPool.filename[fShmAudioPool.filename.length()-6], 6); | |||
| std::strncat(shmIdStr, &fShmControl.filename[fShmControl.filename.length()-6], 6); | |||
| std::strncat(shmIdStr, &fShmTime.filename[fShmTime.filename.length()-6], 6); | |||
| @@ -1761,7 +1761,7 @@ void CarlaPlugin::sendMidiAllNotesOffToCallback() | |||
| void CarlaPlugin::postRtEventsRun() | |||
| { | |||
| const CarlaMutex::ScopedLocker sl(pData->postRtEvents.mutex); | |||
| const CarlaMutexLocker sl(pData->postRtEvents.mutex); | |||
| #ifndef BUILD_BRIDGE | |||
| const bool sendOsc(pData->engine->isOscControlRegistered()); | |||
| #endif | |||
| @@ -148,7 +148,7 @@ public: | |||
| fNeedsRead = false; | |||
| stopThread(1000); | |||
| const CarlaMutex::ScopedLocker sl(fMutex); | |||
| const CarlaMutexLocker sl(fMutex); | |||
| fPool.reset(); | |||
| } | |||
| @@ -279,7 +279,7 @@ public: | |||
| i = j = 0; | |||
| // lock, and put data asap | |||
| const CarlaMutex::ScopedLocker sl(fMutex); | |||
| const CarlaMutexLocker sl(fMutex); | |||
| for (ssize_t size = (ssize_t)fPool.size; i < size && j < rv; ++j) | |||
| { | |||
| @@ -193,7 +193,7 @@ public: | |||
| void clear() | |||
| { | |||
| const CarlaMutex::ScopedLocker sl(fMutex); | |||
| const CarlaMutexLocker sl(fMutex); | |||
| fData.clear(); | |||
| } | |||
| @@ -210,7 +210,7 @@ private: | |||
| { | |||
| if (fData.isEmpty()) | |||
| { | |||
| const CarlaMutex::ScopedLocker sl(fMutex); | |||
| const CarlaMutexLocker sl(fMutex); | |||
| fData.append(event); | |||
| return; | |||
| } | |||
| @@ -222,12 +222,12 @@ private: | |||
| if (event->time >= oldEvent->time) | |||
| continue; | |||
| const CarlaMutex::ScopedLocker sl(fMutex); | |||
| const CarlaMutexLocker sl(fMutex); | |||
| fData.insertAt(event, it); | |||
| return; | |||
| } | |||
| const CarlaMutex::ScopedLocker sl(fMutex); | |||
| const CarlaMutexLocker sl(fMutex); | |||
| fData.append(event); | |||
| } | |||
| }; | |||
| @@ -33,7 +33,7 @@ public: | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr); | |||
| const CarlaMutex::ScopedLocker sl(fMutex); | |||
| const CarlaMutexLocker sl(fMutex); | |||
| for (LinkedList<Lib>::Itenerator it = fLibs.begin(); it.valid(); it.next()) | |||
| { | |||
| @@ -67,7 +67,7 @@ public: | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(libPtr != nullptr, false); | |||
| const CarlaMutex::ScopedLocker sl(fMutex); | |||
| const CarlaMutexLocker sl(fMutex); | |||
| for (LinkedList<Lib>::Itenerator it = fLibs.begin(); it.valid(); it.next()) | |||
| { | |||
| @@ -85,54 +85,6 @@ public: | |||
| pthread_mutex_unlock(&fMutex); | |||
| } | |||
| /* | |||
| * Helper class to lock&unlock a mutex during a function scope. | |||
| */ | |||
| class ScopedLocker | |||
| { | |||
| public: | |||
| ScopedLocker(CarlaMutex& mutex) noexcept | |||
| : fMutex(mutex) | |||
| { | |||
| fMutex.lock(); | |||
| } | |||
| ~ScopedLocker() noexcept | |||
| { | |||
| fMutex.unlock(); | |||
| } | |||
| private: | |||
| CarlaMutex& fMutex; | |||
| CARLA_PREVENT_HEAP_ALLOCATION | |||
| CARLA_DECLARE_NON_COPY_CLASS(ScopedLocker) | |||
| }; | |||
| /* | |||
| * Helper class to unlock&lock a mutex during a function scope. | |||
| */ | |||
| class ScopedUnlocker | |||
| { | |||
| public: | |||
| ScopedUnlocker(CarlaMutex& mutex) noexcept | |||
| : fMutex(mutex) | |||
| { | |||
| fMutex.unlock(); | |||
| } | |||
| ~ScopedUnlocker() noexcept | |||
| { | |||
| fMutex.lock(); | |||
| } | |||
| private: | |||
| CarlaMutex& fMutex; | |||
| CARLA_PREVENT_HEAP_ALLOCATION | |||
| CARLA_DECLARE_NON_COPY_CLASS(ScopedUnlocker) | |||
| }; | |||
| private: | |||
| mutable pthread_mutex_t fMutex; // The mutex | |||
| mutable volatile bool fTryLockWasCalled; // true if "tryLock()" was called at least once | |||
| @@ -155,9 +107,14 @@ public: | |||
| #ifdef CARLA_OS_WIN | |||
| InitializeCriticalSection(&fSection); | |||
| #else | |||
| fCounter = 0; | |||
| fOwnerThread = 0; | |||
| pthread_mutex_init(&fMutex, nullptr); | |||
| pthread_mutexattr_t atts; | |||
| pthread_mutexattr_init(&atts); | |||
| pthread_mutexattr_settype(&atts, PTHREAD_MUTEX_RECURSIVE); | |||
| # ifndef CARLA_OS_ANDROID | |||
| pthread_mutexattr_setprotocol(&atts, PTHREAD_PRIO_INHERIT); | |||
| # endif | |||
| pthread_mutex_init(&fMutex, &atts); | |||
| pthread_mutexattr_destroy(&atts); | |||
| #endif | |||
| } | |||
| @@ -176,79 +133,122 @@ public: | |||
| /* | |||
| * Enter section. | |||
| */ | |||
| void enter() noexcept | |||
| void enter() const noexcept | |||
| { | |||
| #ifdef CARLA_OS_WIN | |||
| EnterCriticalSection(&fSection); | |||
| #else | |||
| const pthread_t thisThread(pthread_self()); | |||
| if (fOwnerThread == thisThread) | |||
| { | |||
| ++fCounter; | |||
| } | |||
| else | |||
| { | |||
| pthread_mutex_lock(&fMutex); | |||
| fOwnerThread = thisThread; | |||
| fCounter = 0; | |||
| } | |||
| pthread_mutex_lock(&fMutex); | |||
| #endif | |||
| } | |||
| /* | |||
| * Leave section. | |||
| * Try-Enter section. | |||
| */ | |||
| void leave() noexcept | |||
| bool tryEnter() const noexcept | |||
| { | |||
| #ifdef CARLA_OS_WIN | |||
| LeaveCriticalSection(&fSection); | |||
| return (TryEnterCriticalSection(&fSection) != FALSE); | |||
| #else | |||
| if (--fCounter < 0) | |||
| { | |||
| fOwnerThread = 0; | |||
| pthread_mutex_unlock(&fMutex); | |||
| } | |||
| return (pthread_mutex_trylock(&fMutex) == 0); | |||
| #endif | |||
| } | |||
| /* | |||
| * Helper class to enter&leave during a function scope. | |||
| * Leave section. | |||
| */ | |||
| class Scope | |||
| void leave() const noexcept | |||
| { | |||
| public: | |||
| Scope(CarlaCriticalSection& cs) noexcept | |||
| : fSection(cs) | |||
| { | |||
| fSection.enter(); | |||
| } | |||
| ~Scope() noexcept | |||
| { | |||
| fSection.leave(); | |||
| } | |||
| private: | |||
| CarlaCriticalSection& fSection; | |||
| CARLA_PREVENT_HEAP_ALLOCATION | |||
| CARLA_DECLARE_NON_COPY_CLASS(Scope) | |||
| }; | |||
| #ifdef CARLA_OS_WIN | |||
| LeaveCriticalSection(&fSection); | |||
| #else | |||
| pthread_mutex_unlock(&fMutex); | |||
| #endif | |||
| } | |||
| private: | |||
| #ifdef CARLA_OS_WIN | |||
| CRITICAL_SECTION fSection; | |||
| mutable CRITICAL_SECTION fSection; | |||
| #else | |||
| int fCounter; | |||
| pthread_t fOwnerThread; | |||
| pthread_mutex_t fMutex; | |||
| mutable pthread_mutex_t fMutex; | |||
| #endif | |||
| CARLA_PREVENT_HEAP_ALLOCATION | |||
| CARLA_DECLARE_NON_COPY_CLASS(CarlaCriticalSection) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // Helper class to lock&unlock a mutex during a function scope. | |||
| class CarlaMutexLocker | |||
| { | |||
| public: | |||
| CarlaMutexLocker(const CarlaMutex& mutex) noexcept | |||
| : fMutex(mutex) | |||
| { | |||
| fMutex.lock(); | |||
| } | |||
| ~CarlaMutexLocker() noexcept | |||
| { | |||
| fMutex.unlock(); | |||
| } | |||
| private: | |||
| const CarlaMutex& fMutex; | |||
| CARLA_PREVENT_HEAP_ALLOCATION | |||
| CARLA_DECLARE_NON_COPY_CLASS(CarlaMutexLocker) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // Helper class to unlock&lock a mutex during a function scope. | |||
| class CarlaMutexUnlocker | |||
| { | |||
| public: | |||
| CarlaMutexUnlocker(const CarlaMutex& mutex) noexcept | |||
| : fMutex(mutex) | |||
| { | |||
| fMutex.unlock(); | |||
| } | |||
| ~CarlaMutexUnlocker() noexcept | |||
| { | |||
| fMutex.lock(); | |||
| } | |||
| private: | |||
| const CarlaMutex& fMutex; | |||
| CARLA_PREVENT_HEAP_ALLOCATION | |||
| CARLA_DECLARE_NON_COPY_CLASS(CarlaMutexUnlocker) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // Helper class to enter&leave during a function scope. | |||
| class CarlaCriticalSectionScope | |||
| { | |||
| public: | |||
| CarlaCriticalSectionScope(const CarlaCriticalSection& cs) noexcept | |||
| : fSection(cs) | |||
| { | |||
| fSection.enter(); | |||
| } | |||
| ~CarlaCriticalSectionScope() noexcept | |||
| { | |||
| fSection.leave(); | |||
| } | |||
| private: | |||
| const CarlaCriticalSection& fSection; | |||
| CARLA_PREVENT_HEAP_ALLOCATION | |||
| CARLA_DECLARE_NON_COPY_CLASS(CarlaCriticalSectionScope) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| #endif // CARLA_MUTEX_HPP_INCLUDED | |||
| @@ -30,7 +30,7 @@ protected: | |||
| /* | |||
| * Constructor. | |||
| */ | |||
| CarlaThread(const char* const threadName = nullptr) /*noexcept*/ | |||
| CarlaThread(const char* const threadName = nullptr) noexcept | |||
| : fName(threadName), | |||
| fShouldExit(false) | |||
| { | |||
| @@ -80,7 +80,7 @@ public: | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(! isThreadRunning(),); | |||
| const CarlaMutex::ScopedLocker sl(fLock); | |||
| const CarlaMutexLocker sl(fLock); | |||
| fShouldExit = false; | |||
| @@ -114,7 +114,7 @@ public: | |||
| */ | |||
| bool stopThread(const int timeOutMilliseconds) noexcept | |||
| { | |||
| const CarlaMutex::ScopedLocker sl(fLock); | |||
| const CarlaMutexLocker sl(fLock); | |||
| if (isThreadRunning()) | |||
| { | |||
| @@ -172,6 +172,19 @@ private: | |||
| volatile pthread_t fHandle; // Handle for this thread | |||
| volatile bool fShouldExit; // true if thread should exit | |||
| /* | |||
| * Static null thread. | |||
| */ | |||
| static pthread_t& _null() noexcept | |||
| { | |||
| #ifdef CARLA_OS_WIN | |||
| static pthread_t sThread = { nullptr, 0 }; | |||
| #else | |||
| static pthread_t sThread = 0; | |||
| #endif | |||
| return sThread; | |||
| } | |||
| void _init() noexcept | |||
| { | |||
| #ifdef CARLA_OS_WIN | |||
| @@ -198,7 +198,7 @@ public: | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(atom != nullptr && atom->size > 0, false); | |||
| const CarlaMutex::ScopedLocker sl(fMutex); | |||
| const CarlaMutexLocker cml(fMutex); | |||
| return fRingBufferCtrl.writeAtom(atom, static_cast<int32_t>(portIndex)); | |||
| } | |||
| @@ -209,7 +209,7 @@ public: | |||
| CARLA_SAFE_ASSERT_RETURN(atom != nullptr && atom->size > 0, false); | |||
| CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | |||
| const CarlaMutex::ScopedLocker sl(fMutex); | |||
| const CarlaMutexLocker cml(fMutex); | |||
| return fRingBufferCtrl.writeAtomChunk(atom, data, static_cast<int32_t>(portIndex)); | |||
| } | |||
| @@ -236,11 +236,11 @@ public: | |||
| void copyDataFromQueue(Lv2AtomQueue& queue) | |||
| { | |||
| // lock source | |||
| const CarlaMutex::ScopedLocker qsl(queue.fMutex); | |||
| const CarlaMutexLocker qsl(queue.fMutex); | |||
| { | |||
| // copy data from source | |||
| const CarlaMutex::ScopedLocker sl(fMutex); | |||
| const CarlaMutexLocker cml(fMutex); | |||
| fRingBufferCtrl.fBuffer = queue.fRingBufferCtrl.fBuffer; | |||
| } | |||
| @@ -251,11 +251,11 @@ public: | |||
| void copyAndDumpDataFromQueue(Lv2AtomQueue& queue, char dumpBuf[]) | |||
| { | |||
| // lock source | |||
| const CarlaMutex::ScopedLocker qsl(queue.fMutex); | |||
| const CarlaMutexLocker cml1(queue.fMutex); | |||
| { | |||
| // copy data from source | |||
| const CarlaMutex::ScopedLocker sl(fMutex); | |||
| const CarlaMutexLocker cml2(fMutex); | |||
| fRingBufferCtrl.copyDump(queue.fRingBufferCtrl.fBuffer, dumpBuf); | |||
| } | |||