Browse Source

Revert part of 10c0e75f8adf735a6e6924af5ad2ecdd9e1604cd, may have been causing lockups when removing plugins

tags/1.9.5
falkTX 10 years ago
parent
commit
81e436f520
4 changed files with 37 additions and 27 deletions
  1. +16
    -4
      source/backend/engine/CarlaEngine.cpp
  2. +17
    -14
      source/backend/engine/CarlaEngineInternal.cpp
  3. +2
    -6
      source/backend/engine/CarlaEngineInternal.hpp
  4. +2
    -3
      source/backend/engine/CarlaEngineJack.cpp

+ 16
- 4
source/backend/engine/CarlaEngine.cpp View File

@@ -293,7 +293,7 @@ bool CarlaEngine::close()


void CarlaEngine::idle() noexcept void CarlaEngine::idle() noexcept
{ {
CARLA_SAFE_ASSERT_RETURN(pData->nextAction.opcode.get() == kEnginePostActionNull,); // FIXME REMOVE
CARLA_SAFE_ASSERT_RETURN(pData->nextAction.opcode == kEnginePostActionNull,); // FIXME REMOVE
CARLA_SAFE_ASSERT_RETURN(pData->nextPluginId == pData->maxPluginNumber,); CARLA_SAFE_ASSERT_RETURN(pData->nextPluginId == pData->maxPluginNumber,);


for (uint i=0; i < pData->curPluginCount; ++i) for (uint i=0; i < pData->curPluginCount; ++i)
@@ -324,6 +324,7 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, cons
CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextPluginId <= pData->maxPluginNumber, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextPluginId <= pData->maxPluginNumber, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(btype != BINARY_NONE, "Invalid plugin binary mode"); CARLA_SAFE_ASSERT_RETURN_ERR(btype != BINARY_NONE, "Invalid plugin binary mode");
CARLA_SAFE_ASSERT_RETURN_ERR(ptype != PLUGIN_NONE, "Invalid plugin type"); CARLA_SAFE_ASSERT_RETURN_ERR(ptype != PLUGIN_NONE, "Invalid plugin type");
CARLA_SAFE_ASSERT_RETURN_ERR((filename != nullptr && filename[0] != '\0') || (label != nullptr && label[0] != '\0'), "Invalid plugin filename and label"); CARLA_SAFE_ASSERT_RETURN_ERR((filename != nullptr && filename[0] != '\0') || (label != nullptr && label[0] != '\0'), "Invalid plugin filename and label");
@@ -575,6 +576,7 @@ bool CarlaEngine::removePlugin(const uint id)
CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(id < pData->curPluginCount, "Invalid plugin Id"); CARLA_SAFE_ASSERT_RETURN_ERR(id < pData->curPluginCount, "Invalid plugin Id");
carla_debug("CarlaEngine::removePlugin(%i)", id); carla_debug("CarlaEngine::removePlugin(%i)", id);


@@ -586,7 +588,8 @@ bool CarlaEngine::removePlugin(const uint id)
pData->thread.stopThread(500); pData->thread.stopThread(500);


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
const ScopedActionLock sal(pData, kEnginePostActionRemovePlugin, id, 0, isRunning());
const bool lockWait(isRunning() && pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS);
const ScopedActionLock sal(pData, kEnginePostActionRemovePlugin, id, 0, lockWait);


for (uint i=id; i < pData->curPluginCount; ++i) for (uint i=id; i < pData->curPluginCount; ++i)
{ {
@@ -616,6 +619,7 @@ bool CarlaEngine::removeAllPlugins()
CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextPluginId == pData->maxPluginNumber, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextPluginId == pData->maxPluginNumber, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
carla_debug("CarlaEngine::removeAllPlugins()"); carla_debug("CarlaEngine::removeAllPlugins()");


if (pData->curPluginCount == 0) if (pData->curPluginCount == 0)
@@ -625,7 +629,8 @@ bool CarlaEngine::removeAllPlugins()


const uint32_t curPluginCount(pData->curPluginCount); const uint32_t curPluginCount(pData->curPluginCount);


const ScopedActionLock sal(pData, kEnginePostActionZeroCount, 0, 0, isRunning());
const bool lockWait(isRunning());
const ScopedActionLock sal(pData, kEnginePostActionZeroCount, 0, 0, lockWait);


callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr); callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);


@@ -659,6 +664,7 @@ const char* CarlaEngine::renamePlugin(const uint id, const char* const newName)
CARLA_SAFE_ASSERT_RETURN_ERRN(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish"); CARLA_SAFE_ASSERT_RETURN_ERRN(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
CARLA_SAFE_ASSERT_RETURN_ERRN(pData->plugins != nullptr, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERRN(pData->plugins != nullptr, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERRN(pData->curPluginCount != 0, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERRN(pData->curPluginCount != 0, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERRN(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERRN(id < pData->curPluginCount, "Invalid plugin Id"); CARLA_SAFE_ASSERT_RETURN_ERRN(id < pData->curPluginCount, "Invalid plugin Id");
CARLA_SAFE_ASSERT_RETURN_ERRN(newName != nullptr && newName[0] != '\0', "Invalid plugin name"); CARLA_SAFE_ASSERT_RETURN_ERRN(newName != nullptr && newName[0] != '\0', "Invalid plugin name");
carla_debug("CarlaEngine::renamePlugin(%i, \"%s\")", id, newName); carla_debug("CarlaEngine::renamePlugin(%i, \"%s\")", id, newName);
@@ -683,6 +689,7 @@ bool CarlaEngine::clonePlugin(const uint id)
CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(id < pData->curPluginCount, "Invalid plugin Id"); CARLA_SAFE_ASSERT_RETURN_ERR(id < pData->curPluginCount, "Invalid plugin Id");
carla_debug("CarlaEngine::clonePlugin(%i)", id); carla_debug("CarlaEngine::clonePlugin(%i)", id);


@@ -713,6 +720,7 @@ bool CarlaEngine::replacePlugin(const uint id) noexcept
CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
carla_debug("CarlaEngine::replacePlugin(%i)", id); carla_debug("CarlaEngine::replacePlugin(%i)", id);


// might use this to reset // might use this to reset
@@ -739,6 +747,7 @@ bool CarlaEngine::switchPlugins(const uint idA, const uint idB) noexcept
CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount >= 2, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount >= 2, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERR(idA != idB, "Invalid operation, cannot switch plugin with itself"); CARLA_SAFE_ASSERT_RETURN_ERR(idA != idB, "Invalid operation, cannot switch plugin with itself");
CARLA_SAFE_ASSERT_RETURN_ERR(idA < pData->curPluginCount, "Invalid plugin Id"); CARLA_SAFE_ASSERT_RETURN_ERR(idA < pData->curPluginCount, "Invalid plugin Id");
CARLA_SAFE_ASSERT_RETURN_ERR(idB < pData->curPluginCount, "Invalid plugin Id"); CARLA_SAFE_ASSERT_RETURN_ERR(idB < pData->curPluginCount, "Invalid plugin Id");
@@ -754,7 +763,8 @@ bool CarlaEngine::switchPlugins(const uint idA, const uint idB) noexcept


pData->thread.stopThread(500); pData->thread.stopThread(500);


const ScopedActionLock sal(pData, kEnginePostActionSwitchPlugins, idA, idB, isRunning());
const bool lockWait(isRunning() && pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS);
const ScopedActionLock sal(pData, kEnginePostActionSwitchPlugins, idA, idB, lockWait);


if (CarlaPlugin* const plugin = pData->plugins[idA].plugin) if (CarlaPlugin* const plugin = pData->plugins[idA].plugin)
plugin->updateOscURL(); plugin->updateOscURL();
@@ -777,6 +787,7 @@ CarlaPlugin* CarlaEngine::getPlugin(const uint id) const noexcept
{ {
CARLA_SAFE_ASSERT_RETURN_ERRN(pData->plugins != nullptr, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERRN(pData->plugins != nullptr, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERRN(pData->curPluginCount != 0, "Invalid engine internal data"); CARLA_SAFE_ASSERT_RETURN_ERRN(pData->curPluginCount != 0, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERRN(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
CARLA_SAFE_ASSERT_RETURN_ERRN(id < pData->curPluginCount, "Invalid plugin Id"); CARLA_SAFE_ASSERT_RETURN_ERRN(id < pData->curPluginCount, "Invalid plugin Id");


return pData->plugins[id].plugin; return pData->plugins[id].plugin;
@@ -789,6 +800,7 @@ CarlaPlugin* CarlaEngine::getPluginUnchecked(const uint id) const noexcept


const char* CarlaEngine::getUniquePluginName(const char* const name) const const char* CarlaEngine::getUniquePluginName(const char* const name) const
{ {
CARLA_SAFE_ASSERT_RETURN(pData->nextAction.opcode == kEnginePostActionNull, nullptr);
CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', nullptr); CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', nullptr);
carla_debug("CarlaEngine::getUniquePluginName(\"%s\")", name); carla_debug("CarlaEngine::getUniquePluginName(\"%s\")", name);




+ 17
- 14
source/backend/engine/CarlaEngineInternal.cpp View File

@@ -68,24 +68,26 @@ EngineNextAction::EngineNextAction() noexcept
: opcode(kEnginePostActionNull), : opcode(kEnginePostActionNull),
pluginId(0), pluginId(0),
value(0), value(0),
waitEvent() {}
mutex() {}


EngineNextAction::~EngineNextAction() noexcept EngineNextAction::~EngineNextAction() noexcept
{ {
CARLA_SAFE_ASSERT(opcode.get() == kEnginePostActionNull);
CARLA_SAFE_ASSERT(opcode == kEnginePostActionNull);
} }


void EngineNextAction::ready() const noexcept void EngineNextAction::ready() const noexcept
{ {
waitEvent.reset();
mutex.lock();
mutex.unlock();
} }


void EngineNextAction::clearAndReset() noexcept void EngineNextAction::clearAndReset() noexcept
{ {
mutex.lock();
opcode = kEnginePostActionNull; opcode = kEnginePostActionNull;
pluginId = 0; pluginId = 0;
value = 0; value = 0;
waitEvent.reset();
mutex.unlock();
} }


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -208,7 +210,7 @@ void CarlaEngine::ProtectedData::close()
CARLA_SAFE_ASSERT(name.isNotEmpty()); CARLA_SAFE_ASSERT(name.isNotEmpty());
CARLA_SAFE_ASSERT(plugins != nullptr); CARLA_SAFE_ASSERT(plugins != nullptr);
CARLA_SAFE_ASSERT(nextPluginId == maxPluginNumber); CARLA_SAFE_ASSERT(nextPluginId == maxPluginNumber);
CARLA_SAFE_ASSERT(nextAction.opcode.get() == kEnginePostActionNull);
CARLA_SAFE_ASSERT(nextAction.opcode == kEnginePostActionNull);


aboutToClose = true; aboutToClose = true;


@@ -295,9 +297,7 @@ void CarlaEngine::ProtectedData::doPluginsSwitch() noexcept


void CarlaEngine::ProtectedData::doNextPluginAction(const bool unlock) noexcept void CarlaEngine::ProtectedData::doNextPluginAction(const bool unlock) noexcept
{ {
const EnginePostAction action(nextAction.opcode.exchange(kEnginePostActionNull));

switch (action)
switch (nextAction.opcode)
{ {
case kEnginePostActionNull: case kEnginePostActionNull:
break; break;
@@ -318,8 +318,11 @@ void CarlaEngine::ProtectedData::doNextPluginAction(const bool unlock) noexcept
nextAction.pluginId = 0; nextAction.pluginId = 0;
nextAction.value = 0; nextAction.value = 0;


if (unlock && action != kEnginePostActionNull)
nextAction.waitEvent.signal();
if (unlock)
{
nextAction.mutex.tryLock();
nextAction.mutex.unlock();
}
} }


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -328,18 +331,18 @@ void CarlaEngine::ProtectedData::doNextPluginAction(const bool unlock) noexcept
ScopedActionLock::ScopedActionLock(CarlaEngine::ProtectedData* const data, const EnginePostAction action, const uint pluginId, const uint value, const bool lockWait) noexcept ScopedActionLock::ScopedActionLock(CarlaEngine::ProtectedData* const data, const EnginePostAction action, const uint pluginId, const uint value, const bool lockWait) noexcept
: fData(data) : fData(data)
{ {
CARLA_SAFE_ASSERT_RETURN(fData->nextAction.opcode == kEnginePostActionNull,);
CARLA_SAFE_ASSERT_RETURN(action != kEnginePostActionNull,); CARLA_SAFE_ASSERT_RETURN(action != kEnginePostActionNull,);
CARLA_SAFE_ASSERT_RETURN(fData->nextAction.opcode.get() == kEnginePostActionNull,);


fData->nextAction.opcode = action;
fData->nextAction.pluginId = pluginId; fData->nextAction.pluginId = pluginId;
fData->nextAction.value = value; fData->nextAction.value = value;
fData->nextAction.opcode = action;


if (lockWait) if (lockWait)
{ {
// block wait for unlock on processing side // block wait for unlock on processing side
carla_stdout("ScopedPluginAction(%i) - blocking START", pluginId); carla_stdout("ScopedPluginAction(%i) - blocking START", pluginId);
fData->nextAction.waitEvent.wait(2000);
fData->nextAction.mutex.lock();
carla_stdout("ScopedPluginAction(%i) - blocking DONE", pluginId); carla_stdout("ScopedPluginAction(%i) - blocking DONE", pluginId);
} }
else else
@@ -350,7 +353,7 @@ ScopedActionLock::ScopedActionLock(CarlaEngine::ProtectedData* const data, const


ScopedActionLock::~ScopedActionLock() noexcept ScopedActionLock::~ScopedActionLock() noexcept
{ {
//fData->nextAction.mutex.unlock();
fData->nextAction.mutex.unlock();
} }


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


+ 2
- 6
source/backend/engine/CarlaEngineInternal.hpp View File

@@ -22,10 +22,6 @@
#include "CarlaEngineThread.hpp" #include "CarlaEngineThread.hpp"
#include "CarlaEngineUtils.hpp" #include "CarlaEngineUtils.hpp"


#include "juce_core.h"
using juce::Atomic;
using juce::WaitableEvent;

// FIXME only use CARLA_PREVENT_HEAP_ALLOCATION for structs // FIXME only use CARLA_PREVENT_HEAP_ALLOCATION for structs
// maybe separate macro // maybe separate macro


@@ -120,10 +116,10 @@ enum EnginePostAction {
}; };


struct EngineNextAction { struct EngineNextAction {
Atomic<EnginePostAction> opcode;
EnginePostAction opcode;
uint pluginId; uint pluginId;
uint value; uint value;
WaitableEvent waitEvent;
CarlaMutex mutex;


EngineNextAction() noexcept; EngineNextAction() noexcept;
~EngineNextAction() noexcept; ~EngineNextAction() noexcept;


+ 2
- 3
source/backend/engine/CarlaEngineJack.cpp View File

@@ -1618,13 +1618,12 @@ protected:
} }
} }


pData->nextAction.waitEvent.reset();

fClient = nullptr;
#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
carla_fill<jack_port_t*>(fRackPorts, nullptr, kRackPortCount); carla_fill<jack_port_t*>(fRackPorts, nullptr, kRackPortCount);
#endif #endif
runPendingRtEvents();


fClient = nullptr;
callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr); callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr);
} }




Loading…
Cancel
Save