| @@ -83,30 +83,30 @@ bool RackGraph::connect(CarlaEngine* const engine, const int groupA, const int p | |||
| switch (carlaPort) | |||
| { | |||
| case RACK_GRAPH_CARLA_PORT_AUDIO_IN1: | |||
| connectLock.enter(); | |||
| connectLock.lock(); | |||
| connectedIn1.append(otherPort); | |||
| connectLock.leave(); | |||
| connectLock.unlock(); | |||
| makeConnection = true; | |||
| break; | |||
| case RACK_GRAPH_CARLA_PORT_AUDIO_IN2: | |||
| connectLock.enter(); | |||
| connectLock.lock(); | |||
| connectedIn2.append(otherPort); | |||
| connectLock.leave(); | |||
| connectLock.unlock(); | |||
| makeConnection = true; | |||
| break; | |||
| case RACK_GRAPH_CARLA_PORT_AUDIO_OUT1: | |||
| connectLock.enter(); | |||
| connectLock.lock(); | |||
| connectedOut1.append(otherPort); | |||
| connectLock.leave(); | |||
| connectLock.unlock(); | |||
| makeConnection = true; | |||
| break; | |||
| case RACK_GRAPH_CARLA_PORT_AUDIO_OUT2: | |||
| connectLock.enter(); | |||
| connectLock.lock(); | |||
| connectedOut2.append(otherPort); | |||
| connectLock.leave(); | |||
| connectLock.unlock(); | |||
| makeConnection = true; | |||
| break; | |||
| @@ -174,27 +174,27 @@ bool RackGraph::disconnect(CarlaEngine* const engine, const uint connectionId) n | |||
| switch (carlaPort) | |||
| { | |||
| case RACK_GRAPH_CARLA_PORT_AUDIO_IN1: | |||
| connectLock.enter(); | |||
| connectLock.lock(); | |||
| connectedIn1.removeAll(otherPort); | |||
| connectLock.leave(); | |||
| connectLock.unlock(); | |||
| break; | |||
| case RACK_GRAPH_CARLA_PORT_AUDIO_IN2: | |||
| connectLock.enter(); | |||
| connectLock.lock(); | |||
| connectedIn2.removeAll(otherPort); | |||
| connectLock.leave(); | |||
| connectLock.unlock(); | |||
| break; | |||
| case RACK_GRAPH_CARLA_PORT_AUDIO_OUT1: | |||
| connectLock.enter(); | |||
| connectLock.lock(); | |||
| connectedOut1.removeAll(otherPort); | |||
| connectLock.leave(); | |||
| connectLock.unlock(); | |||
| break; | |||
| case RACK_GRAPH_CARLA_PORT_AUDIO_OUT2: | |||
| connectLock.enter(); | |||
| connectLock.lock(); | |||
| connectedOut2.removeAll(otherPort); | |||
| connectLock.leave(); | |||
| connectLock.unlock(); | |||
| break; | |||
| case RACK_GRAPH_CARLA_PORT_MIDI_IN: | |||
| @@ -636,7 +636,7 @@ void CarlaEngineProtectedData::processRack(const float* inBufReal[2], float* out | |||
| void CarlaEngineProtectedData::processRackFull(const float* const* const inBuf, const uint32_t inCount, float* const* const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline) | |||
| { | |||
| const CarlaCriticalSectionScope _cs(graph.rack->connectLock); | |||
| const CarlaMutexLocker _crml(graph.rack->connectLock); // Recursive | |||
| if (inBuf != nullptr && inCount > 0) | |||
| { | |||
| @@ -86,7 +86,7 @@ struct ConnectionToId { | |||
| struct RackGraph { | |||
| uint lastConnectionId; | |||
| CarlaCriticalSection connectLock; | |||
| CarlaMutex connectLock; // Recursive | |||
| LinkedList<int> connectedIn1; | |||
| LinkedList<int> connectedIn2; | |||
| @@ -553,7 +553,7 @@ public: | |||
| } | |||
| // Connections | |||
| rack->connectLock.enter(); | |||
| rack->connectLock.lock(); | |||
| for (LinkedList<int>::Itenerator it = rack->connectedIn1.begin(); it.valid(); it.next()) | |||
| { | |||
| @@ -631,7 +631,7 @@ public: | |||
| ++rack->lastConnectionId; | |||
| } | |||
| rack->connectLock.leave(); | |||
| rack->connectLock.unlock(); | |||
| for (LinkedList<MidiPort>::Itenerator it=fMidiIns.begin(); it.valid(); it.next()) | |||
| { | |||
| @@ -148,7 +148,7 @@ struct BridgeAudioPool { | |||
| struct BridgeControl : public RingBufferControl<StackRingBuffer> { | |||
| CarlaString filename; | |||
| CarlaCriticalSection lock; | |||
| CarlaRecursiveMutex lock; | |||
| BridgeShmControl* data; | |||
| shm_t shm; | |||
| @@ -520,7 +520,7 @@ public: | |||
| const float fixedValue(pData->param.getFixedValue(parameterId, value)); | |||
| fParams[parameterId].value = fixedValue; | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| const CarlaRecursiveMutexLocker _crml(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 CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| const CarlaRecursiveMutexLocker _crml(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 CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| const CarlaRecursiveMutexLocker _crml(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeSetMidiProgram); | |||
| fShmControl.writeInt(index); | |||
| @@ -769,7 +769,7 @@ public: | |||
| void activate() noexcept override | |||
| { | |||
| { | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| const CarlaRecursiveMutexLocker _crml(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeSetParameter); | |||
| fShmControl.writeInt(PARAMETER_ACTIVE); | |||
| @@ -790,7 +790,7 @@ public: | |||
| void deactivate() noexcept override | |||
| { | |||
| { | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| const CarlaRecursiveMutexLocker _crml(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 CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| const CarlaRecursiveMutexLocker _crml(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 CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| const CarlaRecursiveMutexLocker _crml(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent); | |||
| fShmControl.writeLong(event.time); | |||
| @@ -1083,7 +1083,7 @@ public: | |||
| data[j] = static_cast<char>(midiEvent.data[j]); | |||
| { | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| const CarlaRecursiveMutexLocker _crml(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent); | |||
| fShmControl.writeLong(event.time); | |||
| @@ -1176,7 +1176,7 @@ public: | |||
| // Run plugin | |||
| { | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| const CarlaRecursiveMutexLocker _crml(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeProcess); | |||
| fShmControl.commitWrite(); | |||
| @@ -1263,7 +1263,7 @@ public: | |||
| void bufferSizeChanged(const uint32_t newBufferSize) override | |||
| { | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| const CarlaRecursiveMutexLocker _crml(fShmControl.lock); | |||
| resizeAudioPool(newBufferSize); | |||
| @@ -1274,7 +1274,7 @@ public: | |||
| void sampleRateChanged(const double newSampleRate) override | |||
| { | |||
| const CarlaCriticalSectionScope _cs(fShmControl.lock); | |||
| const CarlaRecursiveMutexLocker _crml(fShmControl.lock); | |||
| fShmControl.writeOpcode(kPluginBridgeOpcodeSetSampleRate); | |||
| fShmControl.writeFloat(static_cast<float>(newSampleRate)); | |||
| @@ -39,16 +39,14 @@ public: | |||
| try { | |||
| dfilename = carla_strdup(filename); | |||
| } | |||
| catch(...) { | |||
| return nullptr; | |||
| } | |||
| CARLA_SAFE_EXCEPTION_RETURN("LibCounter::open", nullptr); | |||
| const CarlaMutexLocker sl(fMutex); | |||
| for (LinkedList<Lib>::Itenerator it = fLibs.begin(); it.valid(); it.next()) | |||
| { | |||
| Lib& lib(it.getValue()); | |||
| CARLA_ASSERT(lib.count > 0); | |||
| CARLA_SAFE_ASSERT_CONTINUE(lib.count > 0); | |||
| CARLA_SAFE_ASSERT_CONTINUE(lib.filename != nullptr); | |||
| if (std::strcmp(lib.filename, filename) == 0) | |||
| @@ -61,16 +59,21 @@ public: | |||
| void* const libPtr(lib_open(filename)); | |||
| if (libPtr == nullptr) | |||
| { | |||
| delete[] dfilename; | |||
| return nullptr; | |||
| } | |||
| Lib lib; | |||
| lib.lib = libPtr; | |||
| lib.filename = dfilename; | |||
| lib.count = 1; | |||
| fLibs.append(lib); | |||
| if (fLibs.append(lib)) | |||
| return libPtr; | |||
| return libPtr; | |||
| delete[] dfilename; | |||
| return nullptr; | |||
| } | |||
| bool close(void* const libPtr) noexcept | |||
| @@ -82,7 +85,7 @@ public: | |||
| for (LinkedList<Lib>::Itenerator it = fLibs.begin(); it.valid(); it.next()) | |||
| { | |||
| Lib& lib(it.getValue()); | |||
| CARLA_ASSERT(lib.count > 0); | |||
| CARLA_SAFE_ASSERT_CONTINUE(lib.count > 0); | |||
| CARLA_SAFE_ASSERT_CONTINUE(lib.lib != nullptr); | |||
| if (lib.lib != libPtr) | |||
| @@ -90,22 +93,24 @@ public: | |||
| if (--lib.count == 0) | |||
| { | |||
| if (! lib_close(lib.lib)) | |||
| carla_stderr("LibCounter::close() failed, reason:\n%s", lib_error(lib.filename)); | |||
| lib.lib = nullptr; | |||
| if (lib.filename != nullptr) | |||
| { | |||
| delete[] lib.filename; | |||
| lib.filename = nullptr; | |||
| } | |||
| lib_close(lib.lib); | |||
| lib.lib = nullptr; | |||
| fLibs.remove(it); | |||
| } | |||
| return true; | |||
| } | |||
| CARLA_ASSERT(false); // invalid pointer | |||
| carla_safe_assert("invalid lib pointer", __FILE__, __LINE__); | |||
| return false; | |||
| } | |||
| @@ -36,39 +36,31 @@ void* lib_open(const char* const filename) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr); | |||
| void* ret = nullptr; | |||
| try { | |||
| #ifdef CARLA_OS_WIN | |||
| ret = (void*)LoadLibraryA(filename); | |||
| return (void*)LoadLibraryA(filename); | |||
| #else | |||
| ret = dlopen(filename, RTLD_NOW|RTLD_LOCAL); | |||
| return dlopen(filename, RTLD_NOW|RTLD_LOCAL); | |||
| #endif | |||
| } catch(...) {} | |||
| return ret; | |||
| } CARLA_SAFE_EXCEPTION_RETURN("lib_open", nullptr); | |||
| } | |||
| /* | |||
| * Close a previously opened library (must not be null). | |||
| * If false is returned,"lib_error" has the error. | |||
| * If false is returned, "lib_error" has the error. | |||
| */ | |||
| static inline | |||
| bool lib_close(void* const lib) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(lib != nullptr, false); | |||
| bool ret = false; | |||
| try { | |||
| #ifdef CARLA_OS_WIN | |||
| ret = FreeLibrary((HMODULE)lib); | |||
| return FreeLibrary((HMODULE)lib); | |||
| #else | |||
| ret = (dlclose(lib) == 0); | |||
| return (dlclose(lib) == 0); | |||
| #endif | |||
| } catch(...) {} | |||
| return ret; | |||
| } CARLA_SAFE_EXCEPTION_RETURN("lib_close", false); | |||
| } | |||
| /* | |||
| @@ -108,7 +100,7 @@ const char* lib_error(const char* const filename) noexcept | |||
| std::snprintf(libError, 2048, "%s: error code %li: %s", filename, winErrorCode, (const char*)winErrorString); | |||
| LocalFree(winErrorString); | |||
| } catch(...) {} | |||
| } CARLA_SAFE_EXCEPTION("lib_error"); | |||
| return (libError[0] != '\0') ? libError : nullptr; | |||
| #else | |||
| @@ -94,15 +94,15 @@ private: | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // CarlaCriticalSection class | |||
| // CarlaRecursiveMutex class | |||
| class CarlaCriticalSection | |||
| class CarlaRecursiveMutex | |||
| { | |||
| public: | |||
| /* | |||
| * Constructor. | |||
| */ | |||
| CarlaCriticalSection() noexcept | |||
| CarlaRecursiveMutex() noexcept | |||
| { | |||
| #ifdef CARLA_OS_WIN | |||
| InitializeCriticalSection(&fSection); | |||
| @@ -121,7 +121,7 @@ public: | |||
| /* | |||
| * Destructor. | |||
| */ | |||
| ~CarlaCriticalSection() noexcept | |||
| ~CarlaRecursiveMutex() noexcept | |||
| { | |||
| #ifdef CARLA_OS_WIN | |||
| DeleteCriticalSection(&fSection); | |||
| @@ -131,9 +131,9 @@ public: | |||
| } | |||
| /* | |||
| * Enter section. | |||
| * Lock the mutex. | |||
| */ | |||
| void enter() const noexcept | |||
| void lock() const noexcept | |||
| { | |||
| #ifdef CARLA_OS_WIN | |||
| EnterCriticalSection(&fSection); | |||
| @@ -143,9 +143,10 @@ public: | |||
| } | |||
| /* | |||
| * Try-Enter section. | |||
| * Try to lock the mutex. | |||
| * Returns true if successful. | |||
| */ | |||
| bool tryEnter() const noexcept | |||
| bool tryLock() const noexcept | |||
| { | |||
| #ifdef CARLA_OS_WIN | |||
| return (TryEnterCriticalSection(&fSection) != FALSE); | |||
| @@ -155,9 +156,9 @@ public: | |||
| } | |||
| /* | |||
| * Leave section. | |||
| * Unlock the mutex. | |||
| */ | |||
| void leave() const noexcept | |||
| void unlock() const noexcept | |||
| { | |||
| #ifdef CARLA_OS_WIN | |||
| LeaveCriticalSection(&fSection); | |||
| @@ -174,80 +175,67 @@ private: | |||
| #endif | |||
| CARLA_PREVENT_HEAP_ALLOCATION | |||
| CARLA_DECLARE_NON_COPY_CLASS(CarlaCriticalSection) | |||
| CARLA_DECLARE_NON_COPY_CLASS(CarlaRecursiveMutex) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // Helper class to lock&unlock a mutex during a function scope. | |||
| class CarlaMutexLocker | |||
| template <class Mutex> | |||
| class CarlaScopedLocker | |||
| { | |||
| public: | |||
| CarlaMutexLocker(const CarlaMutex& mutex) noexcept | |||
| CarlaScopedLocker(const Mutex& mutex) noexcept | |||
| : fMutex(mutex) | |||
| { | |||
| fMutex.lock(); | |||
| } | |||
| ~CarlaMutexLocker() noexcept | |||
| ~CarlaScopedLocker() noexcept | |||
| { | |||
| fMutex.unlock(); | |||
| } | |||
| private: | |||
| const CarlaMutex& fMutex; | |||
| const Mutex& fMutex; | |||
| CARLA_PREVENT_HEAP_ALLOCATION | |||
| CARLA_DECLARE_NON_COPY_CLASS(CarlaMutexLocker) | |||
| CARLA_DECLARE_NON_COPY_CLASS(CarlaScopedLocker) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // Helper class to unlock&lock a mutex during a function scope. | |||
| class CarlaMutexUnlocker | |||
| template <class Mutex> | |||
| class CarlaScopedUnlocker | |||
| { | |||
| public: | |||
| CarlaMutexUnlocker(const CarlaMutex& mutex) noexcept | |||
| CarlaScopedUnlocker(const Mutex& mutex) noexcept | |||
| : fMutex(mutex) | |||
| { | |||
| fMutex.unlock(); | |||
| } | |||
| ~CarlaMutexUnlocker() noexcept | |||
| ~CarlaScopedUnlocker() noexcept | |||
| { | |||
| fMutex.lock(); | |||
| } | |||
| private: | |||
| const CarlaMutex& fMutex; | |||
| const Mutex& fMutex; | |||
| CARLA_PREVENT_HEAP_ALLOCATION | |||
| CARLA_DECLARE_NON_COPY_CLASS(CarlaMutexUnlocker) | |||
| CARLA_DECLARE_NON_COPY_CLASS(CarlaScopedUnlocker) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // 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(); | |||
| } | |||
| // Define types | |||
| private: | |||
| const CarlaCriticalSection& fSection; | |||
| typedef CarlaScopedLocker<CarlaMutex> CarlaMutexLocker; | |||
| typedef CarlaScopedLocker<CarlaRecursiveMutex> CarlaRecursiveMutexLocker; | |||
| CARLA_PREVENT_HEAP_ALLOCATION | |||
| CARLA_DECLARE_NON_COPY_CLASS(CarlaCriticalSectionScope) | |||
| }; | |||
| typedef CarlaScopedUnlocker<CarlaMutex> CarlaMutexUnlocker; | |||
| typedef CarlaScopedUnlocker<CarlaRecursiveMutex> CarlaRecursiveMutexUnlocker; | |||
| // ----------------------------------------------------------------------- | |||
| @@ -46,7 +46,7 @@ typedef struct list_head k_list_head; | |||
| // Abstract Linked List class | |||
| // _allocate() and _deallocate are virtual calls provided by subclasses | |||
| // NOTE: classes are allowed to throw on creation, but NOT on deletion! | |||
| // NOTE: data-type classes are allowed to throw on creation, but NOT on deletion! | |||
| template<typename T> | |||
| class AbstractLinkedList | |||
| @@ -97,7 +97,6 @@ public: | |||
| T& getValue() noexcept | |||
| { | |||
| fData = list_entry(fEntry, Data, siblings); | |||
| CARLA_SAFE_ASSERT(fData != nullptr); | |||
| return fData->value; | |||
| } | |||