diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index f05069d10..c114cf187 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -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 /* diff --git a/source/backend/engine/CarlaEngineBridge.cpp b/source/backend/engine/CarlaEngineBridge.cpp index 2975d17c0..035acdf76 100644 --- a/source/backend/engine/CarlaEngineBridge.cpp +++ b/source/backend/engine/CarlaEngineBridge.cpp @@ -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; diff --git a/source/backend/engine/CarlaEngineInternal.cpp b/source/backend/engine/CarlaEngineInternal.cpp index 29ff73149..3e71e3f72 100644 --- a/source/backend/engine/CarlaEngineInternal.cpp +++ b/source/backend/engine/CarlaEngineInternal.cpp @@ -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?"); } } } diff --git a/source/backend/engine/CarlaEngineInternal.hpp b/source/backend/engine/CarlaEngineInternal.hpp index 32c6d1a1a..2fa9a6da9 100644 --- a/source/backend/engine/CarlaEngineInternal.hpp +++ b/source/backend/engine/CarlaEngineInternal.hpp @@ -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: diff --git a/source/modules/water/threads/ChildProcess.cpp b/source/modules/water/threads/ChildProcess.cpp index 87f961165..f98875be9 100644 --- a/source/modules/water/threads/ChildProcess.cpp +++ b/source/modules/water/threads/ChildProcess.cpp @@ -3,7 +3,7 @@ This file is part of the Water library. Copyright (c) 2016 ROLI Ltd. - Copyright (C) 2017 Filipe Coelho + Copyright (C) 2017-2018 Filipe Coelho Permission is granted to use this software under the terms of the ISC license http://www.isc.org/downloads/software-support-policy/isc-license/