From 8d304b885b38542089fe736abd1ae9a74ad336df Mon Sep 17 00:00:00 2001 From: falkTX Date: Fri, 8 Jan 2016 05:26:49 +0000 Subject: [PATCH] Make zynaddsubfx get/setState more resilient, shouldn't lock now --- source/native-plugins/zynaddsubfx-synth.cpp | 122 +++++++++++++++----- 1 file changed, 91 insertions(+), 31 deletions(-) diff --git a/source/native-plugins/zynaddsubfx-synth.cpp b/source/native-plugins/zynaddsubfx-synth.cpp index dda40bfb9..2c66ca9f4 100644 --- a/source/native-plugins/zynaddsubfx-synth.cpp +++ b/source/native-plugins/zynaddsubfx-synth.cpp @@ -35,6 +35,7 @@ using juce::roundToIntAccurate; using juce::FloatVectorOperations; +using juce::ScopedPointer; // #define ZYN_MSG_ANYWHERE @@ -188,8 +189,80 @@ static ZynAddSubFxPrograms sPrograms; // ----------------------------------------------------------------------- -class ZynAddSubFxPlugin : public NativePluginAndUiClass, - private CarlaThread +class MiddleWareThread : public CarlaThread +{ +public: + class ScopedStopper + { + public: + ScopedStopper(MiddleWareThread& mwt) noexcept + : wasRunning(mwt.isThreadRunning()), + thread(mwt), + middleWare(mwt.fMiddleWare) + { + if (wasRunning) + thread.stop(); + } + + ~ScopedStopper() noexcept + { + if (wasRunning) + thread.start(middleWare); + } + + void updateMiddleWare(MiddleWare* const mw) noexcept + { + middleWare = mw; + } + + private: + const bool wasRunning; + MiddleWareThread& thread; + MiddleWare* middleWare; + + CARLA_PREVENT_HEAP_ALLOCATION + CARLA_DECLARE_NON_COPY_CLASS(ScopedStopper) + }; + + MiddleWareThread() + : CarlaThread("ZynMiddleWare"), + fMiddleWare(nullptr) {} + + void start(MiddleWare* const mw) noexcept + { + fMiddleWare = mw; + startThread(); + } + + void stop() noexcept + { + stopThread(1000); + fMiddleWare = nullptr; + } + +private: + MiddleWare* fMiddleWare; + + void run() noexcept override + { + for (; ! shouldThreadExit();) + { + CARLA_SAFE_ASSERT_RETURN(fMiddleWare != nullptr,); + + try { + fMiddleWare->tick(); + } CARLA_SAFE_EXCEPTION("ZynAddSubFX MiddleWare tick"); + + carla_msleep(1); + } + } + + CARLA_DECLARE_NON_COPY_CLASS(MiddleWareThread) +}; + +// ----------------------------------------------------------------------- + +class ZynAddSubFxPlugin : public NativePluginAndUiClass { public: enum Parameters { @@ -210,12 +283,12 @@ public: ZynAddSubFxPlugin(const NativeHostDescriptor* const host) : NativePluginAndUiClass(host, "zynaddsubfx-ui"), - CarlaThread("ZynAddSubFxPlugin"), fMiddleWare(nullptr), fMaster(nullptr), fSynth(), fIsActive(false), - fMutex() + fMutex(), + fMiddleWareThread(new MiddleWareThread()) { sPrograms.initIfNeeded(); fConfig.init(); @@ -249,10 +322,13 @@ public: _initMaster(); _setMasterParameters(); + + fMiddleWareThread->start(fMiddleWare); } ~ZynAddSubFxPlugin() override { + fMiddleWareThread->stop(); _deleteMaster(); } @@ -687,19 +763,10 @@ protected: char* getState() const override { - char* data = nullptr; - - if (fIsActive) - { - fMiddleWare->doReadOnlyOp([this, &data]{ - fMaster->getalldata(&data); - }); - } - else - { - fMaster->getalldata(&data); - } + const MiddleWareThread::ScopedStopper mwss(*fMiddleWareThread); + char* data = nullptr; + fMaster->getalldata(&data); return data; } @@ -707,6 +774,7 @@ protected: { CARLA_SAFE_ASSERT_RETURN(data != nullptr,); + const MiddleWareThread::ScopedStopper mwss(*fMiddleWareThread); const CarlaMutexLocker cml(fMutex); fMaster->putalldata(data); @@ -723,6 +791,8 @@ protected: void bufferSizeChanged(const uint32_t bufferSize) final { + MiddleWareThread::ScopedStopper mwss(*fMiddleWareThread); + char* const state(getState()); _deleteMaster(); @@ -735,6 +805,7 @@ protected: fSynth.alias(); _initMaster(); + mwss.updateMiddleWare(fMiddleWare); setState(state); std::free(state); @@ -742,6 +813,8 @@ protected: void sampleRateChanged(const double sampleRate) final { + MiddleWareThread::ScopedStopper mwss(*fMiddleWareThread); + char* const state(getState()); _deleteMaster(); @@ -750,6 +823,7 @@ protected: fSynth.alias(); _initMaster(); + mwss.updateMiddleWare(fMiddleWare); setState(state); std::free(state); @@ -767,6 +841,7 @@ private: float fParameters[kParamCount]; CarlaMutex fMutex; + ScopedPointer fMiddleWareThread; static MidiControllers getZynControlFromIndex(const uint index) { @@ -810,18 +885,6 @@ private: } } - void run() noexcept override - { - for (; ! shouldThreadExit();) - { - try { - fMiddleWare->tick(); - } CARLA_SAFE_EXCEPTION("ZynAddSubFX MiddleWare tick"); - - carla_msleep(1); - } - } - // ------------------------------------------------------------------- void _initMaster() @@ -830,7 +893,6 @@ private: fMiddleWare->setUiCallback(__uiCallback, this); fMiddleWare->setIdleCallback(_idleCallback, this); _masterChangedCallback(fMiddleWare->spawnMaster()); - startThread(); } void _setMasterParameters() @@ -887,8 +949,6 @@ private: void _deleteMaster() { - stopThread(1000); - fMaster = nullptr; delete fMiddleWare; fMiddleWare = nullptr;