@@ -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); | |||
} | |||