Browse Source

More plugin-bridge work

tags/1.9.6
falkTX 10 years ago
parent
commit
c8756dfa0b
4 changed files with 182 additions and 158 deletions
  1. +4
    -4
      source/backend/engine/CarlaEngineBridge.cpp
  2. +172
    -153
      source/backend/plugin/CarlaPluginBridge.cpp
  3. +5
    -0
      source/utils/CarlaBridgeUtils.hpp
  4. +1
    -1
      source/utils/CarlaShmUtils.hpp

+ 4
- 4
source/backend/engine/CarlaEngineBridge.cpp View File

@@ -334,16 +334,16 @@ public:
{ {
carla_stdout("CarlaEngineBridge::CarlaEngineBridge(\"%s\", \"%s\", \"%s\", \"%s\")", audioPoolBaseName, rtClientBaseName, nonRtClientBaseName, nonRtServerBaseName); carla_stdout("CarlaEngineBridge::CarlaEngineBridge(\"%s\", \"%s\", \"%s\", \"%s\")", audioPoolBaseName, rtClientBaseName, nonRtClientBaseName, nonRtServerBaseName);


fShmAudioPool.filename = "/carla-bridge_shm_ap_";
fShmAudioPool.filename = PLUGIN_BRIDGE_NAMEPREFIX_AUDIO_POOL;
fShmAudioPool.filename += audioPoolBaseName; fShmAudioPool.filename += audioPoolBaseName;


fShmRtClientControl.filename = "/carla-bridge_shm_rtC_";
fShmRtClientControl.filename = PLUGIN_BRIDGE_NAMEPREFIX_RT_CLIENT;
fShmRtClientControl.filename += rtClientBaseName; fShmRtClientControl.filename += rtClientBaseName;


fShmNonRtClientControl.filename = "/carla-bridge_shm_nonrtC_";
fShmNonRtClientControl.filename = PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_CLIENT;
fShmNonRtClientControl.filename += nonRtClientBaseName; fShmNonRtClientControl.filename += nonRtClientBaseName;


fShmNonRtServerControl.filename = "/carla-bridge_shm_nonrtS_";
fShmNonRtServerControl.filename = PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_SERVER;
fShmNonRtServerControl.filename += nonRtServerBaseName; fShmNonRtServerControl.filename += nonRtServerBaseName;
} }




+ 172
- 153
source/backend/plugin/CarlaPluginBridge.cpp View File

@@ -15,11 +15,13 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/ */


#ifdef BUILD_BRIDGE
# error This file should be used under bridge mode
#endif

#include "CarlaPluginInternal.hpp" #include "CarlaPluginInternal.hpp"
#include "CarlaEngine.hpp" #include "CarlaEngine.hpp"


#ifndef BUILD_BRIDGE

#include "CarlaBackendUtils.hpp" #include "CarlaBackendUtils.hpp"
#include "CarlaBase64Utils.hpp" #include "CarlaBase64Utils.hpp"
#include "CarlaBridgeUtils.hpp" #include "CarlaBridgeUtils.hpp"
@@ -29,8 +31,6 @@


#include "jackbridge/JackBridge.hpp" #include "jackbridge/JackBridge.hpp"


#include <cerrno>
#include <cmath>
#include <ctime> #include <ctime>


// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------
@@ -71,6 +71,21 @@ struct BridgeAudioPool {
clear(); clear();
} }


bool initialize() noexcept
{
char tmpFileBase[64];

std::sprintf(tmpFileBase, PLUGIN_BRIDGE_NAMEPREFIX_AUDIO_POOL "XXXXXX");

shm = carla_shm_create_temp(tmpFileBase);

if (! carla_is_shm_valid(shm))
return false;

filename = tmpFileBase;
return true;
}

void clear() noexcept void clear() noexcept
{ {
filename.clear(); filename.clear();
@@ -113,15 +128,17 @@ struct BridgeAudioPool {
// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------


struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> { struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> {
CarlaString filename;
BridgeRtClientData* data; BridgeRtClientData* data;
CarlaString filename;
bool needsSemDestroy;
shm_t shm; shm_t shm;


BridgeRtClientControl() BridgeRtClientControl()
: filename(),
data(nullptr)
: data(nullptr),
filename(),
needsSemDestroy(false),
#ifdef CARLA_PROPER_CPP11_SUPPORT #ifdef CARLA_PROPER_CPP11_SUPPORT
, shm(shm_t_INIT) {}
shm(shm_t_INIT) {}
#else #else
{ {
shm = shm_t_INIT; shm = shm_t_INIT;
@@ -136,20 +153,66 @@ struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> {
clear(); clear();
} }


bool initialize() noexcept
{
char tmpFileBase[64];

std::sprintf(tmpFileBase, PLUGIN_BRIDGE_NAMEPREFIX_RT_CLIENT "XXXXXX");

shm = carla_shm_create_temp(tmpFileBase);

if (! carla_is_shm_valid(shm))
return false;

if (! mapData())
{
carla_shm_close(shm);
carla_shm_init(shm);
return false;
}

CARLA_SAFE_ASSERT(data != nullptr);

if (! jackbridge_sem_init(&data->sem.server))
{
unmapData();
carla_shm_close(shm);
carla_shm_init(shm);
return false;
}

if (! jackbridge_sem_init(&data->sem.client))
{
jackbridge_sem_destroy(&data->sem.server);
unmapData();
carla_shm_close(shm);
carla_shm_init(shm);
return false;
}

filename = tmpFileBase;
needsSemDestroy = true;
return true;
}

void clear() noexcept void clear() noexcept
{ {
filename.clear(); filename.clear();


if (! carla_is_shm_valid(shm))
if (needsSemDestroy)
{ {
CARLA_SAFE_ASSERT(data == nullptr);
return;
jackbridge_sem_destroy(&data->sem.client);
jackbridge_sem_destroy(&data->sem.server);
needsSemDestroy = false;
} }


if (data != nullptr) if (data != nullptr)
unmapData();

if (! carla_is_shm_valid(shm))
{ {
carla_shm_unmap(shm, data);
data = nullptr;
CARLA_SAFE_ASSERT(data == nullptr);
return;
} }


carla_shm_close(shm); carla_shm_close(shm);
@@ -202,15 +265,15 @@ struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> {
// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------


struct BridgeNonRtClientControl : public CarlaRingBufferControl<BigStackBuffer> { struct BridgeNonRtClientControl : public CarlaRingBufferControl<BigStackBuffer> {
CarlaMutex mutex;
CarlaString filename;
BridgeNonRtClientData* data; BridgeNonRtClientData* data;
CarlaString filename;
CarlaMutex mutex;
shm_t shm; shm_t shm;


BridgeNonRtClientControl() noexcept BridgeNonRtClientControl() noexcept
: mutex(),
: data(nullptr),
filename(), filename(),
data(nullptr)
mutex()
#ifdef CARLA_PROPER_CPP11_SUPPORT #ifdef CARLA_PROPER_CPP11_SUPPORT
, shm(shm_t_INIT) {} , shm(shm_t_INIT) {}
#else #else
@@ -227,20 +290,41 @@ struct BridgeNonRtClientControl : public CarlaRingBufferControl<BigStackBuffer>
clear(); clear();
} }


void clear() noexcept
bool initialize() noexcept
{ {
filename.clear();
char tmpFileBase[64];

std::sprintf(tmpFileBase, PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_CLIENT "XXXXXX");

shm = carla_shm_create_temp(tmpFileBase);


if (! carla_is_shm_valid(shm)) if (! carla_is_shm_valid(shm))
return false;

if (! mapData())
{ {
CARLA_SAFE_ASSERT(data == nullptr);
return;
carla_shm_close(shm);
carla_shm_init(shm);
return false;
} }


CARLA_SAFE_ASSERT(data != nullptr);

filename = tmpFileBase;
return true;
}

void clear() noexcept
{
filename.clear();

if (data != nullptr) if (data != nullptr)
unmapData();

if (! carla_is_shm_valid(shm))
{ {
carla_shm_unmap(shm, data);
data = nullptr;
CARLA_SAFE_ASSERT(data == nullptr);
return;
} }


carla_shm_close(shm); carla_shm_close(shm);
@@ -281,13 +365,13 @@ struct BridgeNonRtClientControl : public CarlaRingBufferControl<BigStackBuffer>
// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------


struct BridgeNonRtServerControl : public CarlaRingBufferControl<HugeStackBuffer> { struct BridgeNonRtServerControl : public CarlaRingBufferControl<HugeStackBuffer> {
CarlaString filename;
BridgeNonRtServerData* data; BridgeNonRtServerData* data;
CarlaString filename;
shm_t shm; shm_t shm;


BridgeNonRtServerControl() noexcept BridgeNonRtServerControl() noexcept
: filename(),
data(nullptr)
: data(nullptr),
filename()
#ifdef CARLA_PROPER_CPP11_SUPPORT #ifdef CARLA_PROPER_CPP11_SUPPORT
, shm(shm_t_INIT) {} , shm(shm_t_INIT) {}
#else #else
@@ -304,20 +388,41 @@ struct BridgeNonRtServerControl : public CarlaRingBufferControl<HugeStackBuffer>
clear(); clear();
} }


void clear() noexcept
bool initialize() noexcept
{ {
filename.clear();
char tmpFileBase[64];

std::sprintf(tmpFileBase, PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_SERVER "XXXXXX");

shm = carla_shm_create_temp(tmpFileBase);


if (! carla_is_shm_valid(shm)) if (! carla_is_shm_valid(shm))
return false;

if (! mapData())
{ {
CARLA_SAFE_ASSERT(data == nullptr);
return;
carla_shm_close(shm);
carla_shm_init(shm);
return false;
} }


CARLA_SAFE_ASSERT(data != nullptr);

filename = tmpFileBase;
return true;
}

void clear() noexcept
{
filename.clear();

if (data != nullptr) if (data != nullptr)
unmapData();

if (! carla_is_shm_valid(shm))
{ {
carla_shm_unmap(shm, data);
data = nullptr;
CARLA_SAFE_ASSERT(data == nullptr);
return;
} }


carla_shm_close(shm); carla_shm_close(shm);
@@ -376,7 +481,7 @@ class CarlaPluginBridgeThread : public CarlaThread
{ {
public: public:
CarlaPluginBridgeThread(CarlaEngine* const engine, CarlaPlugin* const plugin) noexcept CarlaPluginBridgeThread(CarlaEngine* const engine, CarlaPlugin* const plugin) noexcept
: CarlaThread("CarlaThreadDSSIUI"),
: CarlaThread("CarlaPluginBridgeThread"),
kEngine(engine), kEngine(engine),
kPlugin(plugin), kPlugin(plugin),
fBinary(), fBinary(),
@@ -468,7 +573,6 @@ public:
fInitiated(false), fInitiated(false),
fInitError(false), fInitError(false),
fSaved(false), fSaved(false),
fNeedsSemDestroy(false),
fTimedOut(false), fTimedOut(false),
fLastPongCounter(-1), fLastPongCounter(-1),
fBridgeBinary(), fBridgeBinary(),
@@ -520,16 +624,10 @@ public:


fBridgeThread.stopThread(3000); fBridgeThread.stopThread(3000);


if (fNeedsSemDestroy)
{
jackbridge_sem_destroy(&fShmRtClientControl.data->sem.server);
jackbridge_sem_destroy(&fShmRtClientControl.data->sem.client);
}

fShmAudioPool.clear();
fShmRtClientControl.clear();
fShmNonRtClientControl.clear();
fShmNonRtServerControl.clear(); fShmNonRtServerControl.clear();
fShmNonRtClientControl.clear();
fShmRtClientControl.clear();
fShmAudioPool.clear();


clearBuffers(); clearBuffers();


@@ -702,6 +800,7 @@ public:


void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
{ {
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); // never call this from RT
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);


const float fixedValue(pData->param.getFixedValue(parameterId, value)); const float fixedValue(pData->param.getFixedValue(parameterId, value));
@@ -757,6 +856,7 @@ public:


void setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override void setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
{ {
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); // never call this from RT
CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),); CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),);


{ {
@@ -772,6 +872,7 @@ public:


void setMidiProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override void setMidiProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
{ {
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); // never call this from RT
CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),); CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),);


{ {
@@ -865,10 +966,12 @@ public:
if (fTimedOut && pData->active) if (fTimedOut && pData->active)
setActive(false, true, true); setActive(false, true, true);


const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
{
const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);


fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientPing);
fShmNonRtClientControl.commitWrite();
fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientPing);
fShmNonRtClientControl.commitWrite();
}


try { try {
handleNonRtData(); handleNonRtData();
@@ -2026,108 +2129,40 @@ public:
std::srand(static_cast<uint>(std::time(nullptr))); std::srand(static_cast<uint>(std::time(nullptr)));


// --------------------------------------------------------------- // ---------------------------------------------------------------
// SHM Audio Pool
// init sem/shm


if (! fShmAudioPool.initialize())
{ {
char tmpFileBase[64];

std::sprintf(tmpFileBase, "/carla-bridge_shm_ap_XXXXXX");

fShmAudioPool.shm = carla_shm_create_temp(tmpFileBase);

if (! carla_is_shm_valid(fShmAudioPool.shm))
{
carla_stdout("Failed to open or create shared memory file #1");
return false;
}

fShmAudioPool.filename = tmpFileBase;
carla_stdout("Failed to initialize shared memory audio pool");
return false;
} }


// ---------------------------------------------------------------
// SHM RT Control

if (! fShmRtClientControl.initialize())
{ {
char tmpFileBase[64];

std::sprintf(tmpFileBase, "/carla-bridge_shm_rtC_XXXXXX");

fShmRtClientControl.shm = carla_shm_create_temp(tmpFileBase);

if (! carla_is_shm_valid(fShmRtClientControl.shm))
{
carla_stdout("Failed to open or create shared memory file #2");
// clear
carla_shm_close(fShmAudioPool.shm);
return false;
}

fShmRtClientControl.filename = tmpFileBase;

if (! fShmRtClientControl.mapData())
{
carla_stdout("Failed to map shared memory file #2");
// clear
carla_shm_close(fShmRtClientControl.shm);
carla_shm_close(fShmAudioPool.shm);
return false;
}

CARLA_SAFE_ASSERT(fShmRtClientControl.data != nullptr);

if (! jackbridge_sem_init(&fShmRtClientControl.data->sem.server))
{
carla_stdout("Failed to initialize shared memory semaphore #1");
// clear
fShmRtClientControl.unmapData();
carla_shm_close(fShmRtClientControl.shm);
carla_shm_close(fShmAudioPool.shm);
return false;
}

if (! jackbridge_sem_init(&fShmRtClientControl.data->sem.client))
{
carla_stdout("Failed to initialize shared memory semaphore #2");
// clear
jackbridge_sem_destroy(&fShmRtClientControl.data->sem.server);
fShmRtClientControl.unmapData();
carla_shm_close(fShmRtClientControl.shm);
carla_shm_close(fShmAudioPool.shm);
return false;
}

fNeedsSemDestroy = true;
carla_stdout("Failed to initialize RT client control");
fShmAudioPool.clear();
return false;
} }


// ---------------------------------------------------------------
// SHM Non-RT Control
if (! fShmNonRtClientControl.initialize())
{ {
char tmpFileBase[64];

std::sprintf(tmpFileBase, "/carla-bridge_shm_nonrtC_XXXXXX");

fShmNonRtClientControl.shm = carla_shm_create_temp(tmpFileBase);

if (! carla_is_shm_valid(fShmNonRtClientControl.shm))
{
carla_stdout("Failed to open or create shared memory file #3");
return false;
}

fShmNonRtClientControl.filename = tmpFileBase;
carla_stdout("Failed to initialize Non-RT client control");
fShmRtClientControl.clear();
fShmAudioPool.clear();
return false;
}


if (! fShmNonRtClientControl.mapData())
{
carla_stdout("Failed to map shared memory file #3");
// clear
fShmNonRtClientControl.unmapData();
carla_shm_close(fShmNonRtClientControl.shm);
carla_shm_close(fShmRtClientControl.shm);
carla_shm_close(fShmAudioPool.shm);
return false;
}
if (! fShmNonRtServerControl.initialize())
{
carla_stdout("Failed to initialize Non-RT server control");
fShmNonRtClientControl.clear();
fShmRtClientControl.clear();
fShmAudioPool.clear();
return false;
} }


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

carla_stdout("Carla Server Info:"); carla_stdout("Carla Server Info:");
carla_stdout(" sizeof(BridgeRtClientData): " P_SIZE, sizeof(BridgeRtClientData)); carla_stdout(" sizeof(BridgeRtClientData): " P_SIZE, sizeof(BridgeRtClientData));
carla_stdout(" sizeof(BridgeNonRtClientData): " P_SIZE, sizeof(BridgeNonRtClientData)); carla_stdout(" sizeof(BridgeNonRtClientData): " P_SIZE, sizeof(BridgeNonRtClientData));
@@ -2216,7 +2251,6 @@ private:
bool fInitiated; bool fInitiated;
bool fInitError; bool fInitError;
bool fSaved; bool fSaved;
bool fNeedsSemDestroy;
bool fTimedOut; bool fTimedOut;


volatile int32_t fLastPongCounter; volatile int32_t fLastPongCounter;
@@ -2292,8 +2326,6 @@ private:


CARLA_BACKEND_END_NAMESPACE CARLA_BACKEND_END_NAMESPACE


#endif // ! BUILD_BRIDGE

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


CARLA_BACKEND_START_NAMESPACE CARLA_BACKEND_START_NAMESPACE
@@ -2302,7 +2334,6 @@ CarlaPlugin* CarlaPlugin::newBridge(const Initializer& init, BinaryType btype, P
{ {
carla_debug("CarlaPlugin::newBridge({%p, \"%s\", \"%s\", \"%s\"}, %s, %s, \"%s\")", init.engine, init.filename, init.name, init.label, BinaryType2Str(btype), PluginType2Str(ptype), bridgeBinary); carla_debug("CarlaPlugin::newBridge({%p, \"%s\", \"%s\", \"%s\"}, %s, %s, \"%s\")", init.engine, init.filename, init.name, init.label, BinaryType2Str(btype), PluginType2Str(ptype), bridgeBinary);


#ifndef BUILD_BRIDGE
if (bridgeBinary == nullptr || bridgeBinary[0] == '\0') if (bridgeBinary == nullptr || bridgeBinary[0] == '\0')
{ {
init.engine->setLastError("Bridge not possible, bridge-binary not found"); init.engine->setLastError("Bridge not possible, bridge-binary not found");
@@ -2311,10 +2342,8 @@ CarlaPlugin* CarlaPlugin::newBridge(const Initializer& init, BinaryType btype, P


CarlaPluginBridge* const plugin(new CarlaPluginBridge(init.engine, init.id, btype, ptype)); CarlaPluginBridge* const plugin(new CarlaPluginBridge(init.engine, init.id, btype, ptype));


# if 0
if (! plugin->init(init.filename, init.name, init.label, bridgeBinary)) if (! plugin->init(init.filename, init.name, init.label, bridgeBinary))
{ {
init.engine->registerEnginePlugin(init.id, nullptr);
delete plugin; delete plugin;
return nullptr; return nullptr;
} }
@@ -2322,9 +2351,6 @@ CarlaPlugin* CarlaPlugin::newBridge(const Initializer& init, BinaryType btype, P
plugin->reload(); plugin->reload();


bool canRun = true; bool canRun = true;
# else
bool canRun = false;
# endif


if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
{ {
@@ -2352,13 +2378,6 @@ CarlaPlugin* CarlaPlugin::newBridge(const Initializer& init, BinaryType btype, P
} }


return plugin; return plugin;
#else
init.engine->setLastError("Plugin bridge support not available");
return nullptr;

// unused
(void)bridgeBinary; (void)btype; (void)ptype;
#endif
} }


CARLA_BACKEND_END_NAMESPACE CARLA_BACKEND_END_NAMESPACE


+ 5
- 0
source/utils/CarlaBridgeUtils.hpp View File

@@ -20,6 +20,11 @@


#include "CarlaRingBuffer.hpp" #include "CarlaRingBuffer.hpp"


#define PLUGIN_BRIDGE_NAMEPREFIX_AUDIO_POOL "/carla-bridge_shm_ap_"
#define PLUGIN_BRIDGE_NAMEPREFIX_RT_CLIENT "/carla-bridge_shm_rtC_"
#define PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_CLIENT "/carla-bridge_shm_nonrtC_"
#define PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_SERVER "/carla-bridge_shm_nonrtS_"

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


// Server sends these to client during RT // Server sends these to client during RT


+ 1
- 1
source/utils/CarlaShmUtils.hpp View File

@@ -244,7 +244,7 @@ void carla_shm_unmap(shm_t& shm, void* const ptr) noexcept
* Will keep trying until a free random filename is obtained. * Will keep trying until a free random filename is obtained.
*/ */
static inline static inline
shm_t carla_shm_create_temp(char* const fileBase)
shm_t carla_shm_create_temp(char* const fileBase) noexcept
{ {
// check if the fileBase name is valid // check if the fileBase name is valid
CARLA_SAFE_ASSERT_RETURN(fileBase != nullptr, gNullCarlaShm); CARLA_SAFE_ASSERT_RETURN(fileBase != nullptr, gNullCarlaShm);


Loading…
Cancel
Save