| @@ -698,8 +698,7 @@ bool CarlaEngine::removePlugin(const uint id) | |||
| if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | |||
| pData->graph.removePlugin(plugin); | |||
| const bool lockWait(isRunning() /*&& pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS*/); | |||
| const ScopedActionLock sal(this, kEnginePostActionRemovePlugin, id, 0, lockWait); | |||
| const ScopedActionLock sal(this, kEnginePostActionRemovePlugin, id, 0); | |||
| /* | |||
| for (uint i=id; i < pData->curPluginCount; ++i) | |||
| @@ -755,8 +754,7 @@ bool CarlaEngine::removeAllPlugins() | |||
| # endif | |||
| #endif | |||
| const bool lockWait(isRunning()); | |||
| const ScopedActionLock sal(this, kEnginePostActionZeroCount, 0, 0, lockWait); | |||
| const ScopedActionLock sal(this, kEnginePostActionZeroCount, 0, 0); | |||
| callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr); | |||
| @@ -892,8 +890,7 @@ bool CarlaEngine::switchPlugins(const uint idA, const uint idB) noexcept | |||
| if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | |||
| pData->graph.replacePlugin(pluginA, pluginB); | |||
| const bool lockWait(isRunning() /*&& pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS*/); | |||
| const ScopedActionLock sal(this, kEnginePostActionSwitchPlugins, idA, idB, lockWait); | |||
| const ScopedActionLock sal(this, kEnginePostActionSwitchPlugins, idA, idB); | |||
| // TODO | |||
| /* | |||
| @@ -93,6 +93,7 @@ public: | |||
| fBaseNameRtClientControl(rtClientBaseName), | |||
| fBaseNameNonRtClientControl(nonRtClientBaseName), | |||
| fBaseNameNonRtServerControl(nonRtServerBaseName), | |||
| fClosingDown(false), | |||
| fIsOffline(false), | |||
| fFirstIdle(true), | |||
| fLastPingTime(-1) | |||
| @@ -234,6 +235,9 @@ public: | |||
| bool isRunning() const noexcept override | |||
| { | |||
| if (fClosingDown) | |||
| return false; | |||
| return isThreadRunning() || ! fFirstIdle; | |||
| } | |||
| @@ -981,6 +985,7 @@ public: | |||
| } | |||
| case kPluginBridgeNonRtClientQuit: | |||
| fClosingDown = true; | |||
| signalThreadShouldExit(); | |||
| callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr); | |||
| break; | |||
| @@ -1320,6 +1325,7 @@ protected: | |||
| case kPluginBridgeRtClientQuit: { | |||
| quitReceived = true; | |||
| fClosingDown = true; | |||
| signalThreadShouldExit(); | |||
| } break; | |||
| } | |||
| @@ -1376,6 +1382,7 @@ private: | |||
| CarlaString fBaseNameNonRtClientControl; | |||
| CarlaString fBaseNameNonRtServerControl; | |||
| bool fClosingDown; | |||
| bool fIsOffline; | |||
| bool fFirstIdle; | |||
| int64_t fLastPingTime; | |||
| @@ -712,8 +712,7 @@ PendingRtEventsRunner::~PendingRtEventsRunner() noexcept | |||
| ScopedActionLock::ScopedActionLock(CarlaEngine* const engine, | |||
| const EnginePostAction action, | |||
| const uint pluginId, | |||
| const uint value, | |||
| const bool lockWait) noexcept | |||
| const uint value) noexcept | |||
| : pData(engine->pData) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(action != kEnginePostActionNull,); | |||
| @@ -726,24 +725,41 @@ ScopedActionLock::ScopedActionLock(CarlaEngine* const engine, | |||
| pData->nextAction.opcode = action; | |||
| pData->nextAction.pluginId = pluginId; | |||
| pData->nextAction.value = value; | |||
| pData->nextAction.needsPost = lockWait; | |||
| pData->nextAction.needsPost = engine->isRunning(); | |||
| pData->nextAction.postDone = false; | |||
| } | |||
| if (lockWait) | |||
| #ifdef BUILD_BRIDGE | |||
| #define ACTION_MSG_PREFIX "Bridge: " | |||
| #else | |||
| #define ACTION_MSG_PREFIX "" | |||
| #endif | |||
| if (pData->nextAction.needsPost) | |||
| { | |||
| // block wait for unlock on processing side | |||
| carla_stdout("ScopedPluginAction(%i) - blocking START", pluginId); | |||
| carla_stdout(ACTION_MSG_PREFIX "ScopedPluginAction(%i) - blocking START", pluginId); | |||
| bool engineStoppedWhileWaiting = false; | |||
| if (! pData->nextAction.postDone) | |||
| { | |||
| if (pData->nextAction.sem != nullptr) | |||
| carla_sem_timedwait(*pData->nextAction.sem, 2000); | |||
| else | |||
| carla_sleep(2); | |||
| for (int i = 10; --i >= 0;) | |||
| { | |||
| if (pData->nextAction.sem != nullptr) | |||
| carla_sem_timedwait(*pData->nextAction.sem, 200); | |||
| else | |||
| carla_msleep(200); | |||
| if (! engine->isRunning()) | |||
| { | |||
| engineStoppedWhileWaiting = true; | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| carla_stdout("ScopedPluginAction(%i) - blocking DONE", pluginId); | |||
| carla_stdout(ACTION_MSG_PREFIX "ScopedPluginAction(%i) - blocking DONE", pluginId); | |||
| // check if anything went wrong... | |||
| if (! pData->nextAction.postDone) | |||
| @@ -763,7 +779,9 @@ ScopedActionLock::ScopedActionLock(CarlaEngine* const engine, | |||
| if (needsCorrection) | |||
| { | |||
| pData->doNextPluginAction(); | |||
| carla_stderr2("Failed to wait for engine, is audio not running?"); | |||
| if (! engineStoppedWhileWaiting) | |||
| carla_stderr2(ACTION_MSG_PREFIX "Failed to wait for engine, is audio not running?"); | |||
| } | |||
| } | |||
| } | |||
| @@ -303,7 +303,7 @@ private: | |||
| class ScopedActionLock | |||
| { | |||
| public: | |||
| ScopedActionLock(CarlaEngine* const engine, const EnginePostAction action, const uint pluginId, const uint value, const bool lockWait) noexcept; | |||
| ScopedActionLock(CarlaEngine* const engine, const EnginePostAction action, const uint pluginId, const uint value) noexcept; | |||
| ~ScopedActionLock() noexcept; | |||
| private: | |||
| @@ -3,7 +3,7 @@ | |||
| This file is part of the Water library. | |||
| Copyright (c) 2016 ROLI Ltd. | |||
| Copyright (C) 2017 Filipe Coelho <falktx@falktx.com> | |||
| Copyright (C) 2017-2018 Filipe Coelho <falktx@falktx.com> | |||
| Permission is granted to use this software under the terms of the ISC license | |||
| http://www.isc.org/downloads/software-support-policy/isc-license/ | |||