| @@ -698,8 +698,7 @@ bool CarlaEngine::removePlugin(const uint id) | |||||
| if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | ||||
| pData->graph.removePlugin(plugin); | 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) | for (uint i=id; i < pData->curPluginCount; ++i) | ||||
| @@ -755,8 +754,7 @@ bool CarlaEngine::removeAllPlugins() | |||||
| # endif | # endif | ||||
| #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); | 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) | if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | ||||
| pData->graph.replacePlugin(pluginA, pluginB); | 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 | // TODO | ||||
| /* | /* | ||||
| @@ -93,6 +93,7 @@ public: | |||||
| fBaseNameRtClientControl(rtClientBaseName), | fBaseNameRtClientControl(rtClientBaseName), | ||||
| fBaseNameNonRtClientControl(nonRtClientBaseName), | fBaseNameNonRtClientControl(nonRtClientBaseName), | ||||
| fBaseNameNonRtServerControl(nonRtServerBaseName), | fBaseNameNonRtServerControl(nonRtServerBaseName), | ||||
| fClosingDown(false), | |||||
| fIsOffline(false), | fIsOffline(false), | ||||
| fFirstIdle(true), | fFirstIdle(true), | ||||
| fLastPingTime(-1) | fLastPingTime(-1) | ||||
| @@ -234,6 +235,9 @@ public: | |||||
| bool isRunning() const noexcept override | bool isRunning() const noexcept override | ||||
| { | { | ||||
| if (fClosingDown) | |||||
| return false; | |||||
| return isThreadRunning() || ! fFirstIdle; | return isThreadRunning() || ! fFirstIdle; | ||||
| } | } | ||||
| @@ -981,6 +985,7 @@ public: | |||||
| } | } | ||||
| case kPluginBridgeNonRtClientQuit: | case kPluginBridgeNonRtClientQuit: | ||||
| fClosingDown = true; | |||||
| signalThreadShouldExit(); | signalThreadShouldExit(); | ||||
| callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr); | callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr); | ||||
| break; | break; | ||||
| @@ -1320,6 +1325,7 @@ protected: | |||||
| case kPluginBridgeRtClientQuit: { | case kPluginBridgeRtClientQuit: { | ||||
| quitReceived = true; | quitReceived = true; | ||||
| fClosingDown = true; | |||||
| signalThreadShouldExit(); | signalThreadShouldExit(); | ||||
| } break; | } break; | ||||
| } | } | ||||
| @@ -1376,6 +1382,7 @@ private: | |||||
| CarlaString fBaseNameNonRtClientControl; | CarlaString fBaseNameNonRtClientControl; | ||||
| CarlaString fBaseNameNonRtServerControl; | CarlaString fBaseNameNonRtServerControl; | ||||
| bool fClosingDown; | |||||
| bool fIsOffline; | bool fIsOffline; | ||||
| bool fFirstIdle; | bool fFirstIdle; | ||||
| int64_t fLastPingTime; | int64_t fLastPingTime; | ||||
| @@ -712,8 +712,7 @@ PendingRtEventsRunner::~PendingRtEventsRunner() noexcept | |||||
| ScopedActionLock::ScopedActionLock(CarlaEngine* const engine, | ScopedActionLock::ScopedActionLock(CarlaEngine* const engine, | ||||
| const EnginePostAction action, | const EnginePostAction action, | ||||
| const uint pluginId, | const uint pluginId, | ||||
| const uint value, | |||||
| const bool lockWait) noexcept | |||||
| const uint value) noexcept | |||||
| : pData(engine->pData) | : pData(engine->pData) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(action != kEnginePostActionNull,); | CARLA_SAFE_ASSERT_RETURN(action != kEnginePostActionNull,); | ||||
| @@ -726,24 +725,41 @@ ScopedActionLock::ScopedActionLock(CarlaEngine* const engine, | |||||
| pData->nextAction.opcode = action; | pData->nextAction.opcode = action; | ||||
| pData->nextAction.pluginId = pluginId; | pData->nextAction.pluginId = pluginId; | ||||
| pData->nextAction.value = value; | pData->nextAction.value = value; | ||||
| pData->nextAction.needsPost = lockWait; | |||||
| pData->nextAction.needsPost = engine->isRunning(); | |||||
| pData->nextAction.postDone = false; | 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 | // 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.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... | // check if anything went wrong... | ||||
| if (! pData->nextAction.postDone) | if (! pData->nextAction.postDone) | ||||
| @@ -763,7 +779,9 @@ ScopedActionLock::ScopedActionLock(CarlaEngine* const engine, | |||||
| if (needsCorrection) | if (needsCorrection) | ||||
| { | { | ||||
| pData->doNextPluginAction(); | 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 | class ScopedActionLock | ||||
| { | { | ||||
| public: | 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; | ~ScopedActionLock() noexcept; | ||||
| private: | private: | ||||
| @@ -3,7 +3,7 @@ | |||||
| This file is part of the Water library. | This file is part of the Water library. | ||||
| Copyright (c) 2016 ROLI Ltd. | 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 | Permission is granted to use this software under the terms of the ISC license | ||||
| http://www.isc.org/downloads/software-support-policy/isc-license/ | http://www.isc.org/downloads/software-support-policy/isc-license/ | ||||