Browse Source

Finish moving bridge stuff to shared code

Closes #462
tags/1.9.8
falkTX 7 years ago
parent
commit
a7e8556fdd
4 changed files with 377 additions and 420 deletions
  1. +6
    -190
      source/backend/engine/CarlaEngineBridge.cpp
  2. +2
    -212
      source/backend/plugin/CarlaPluginBridge.cpp
  3. +301
    -15
      source/utils/CarlaBridgeUtils.cpp
  4. +68
    -3
      source/utils/CarlaBridgeUtils.hpp

+ 6
- 190
source/backend/engine/CarlaEngineBridge.cpp View File

@@ -40,190 +40,8 @@ using juce::String;
using juce::Time;
using juce::Thread;

template<typename T>
bool jackbridge_shm_map3(void* shm, T*& value) noexcept
{
value = (T*)jackbridge_shm_map(shm, sizeof(T));
return (value != nullptr);
}

CARLA_BACKEND_START_NAMESPACE

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

struct BridgeNonRtClientControl : public CarlaRingBufferControl<BigStackBuffer> {
CarlaString filename;
BridgeNonRtClientData* data;
char shm[64];

BridgeNonRtClientControl() noexcept
: filename(),
data(nullptr)
{
carla_zeroChars(shm, 64);
jackbridge_shm_init(shm);
}

~BridgeNonRtClientControl() noexcept override
{
// should be cleared by now
CARLA_SAFE_ASSERT(data == nullptr);

clear();
}

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

if (data != nullptr)
unmapData();

if (! jackbridge_shm_is_valid(shm))
{
CARLA_SAFE_ASSERT(data == nullptr);
return;
}

jackbridge_shm_close(shm);
jackbridge_shm_init(shm);
}

bool attach() noexcept
{
// must be invalid right now
CARLA_SAFE_ASSERT_RETURN(! jackbridge_shm_is_valid(shm), false);

jackbridge_shm_attach(shm, filename);

return jackbridge_shm_is_valid(shm);
}

bool mapData() noexcept
{
CARLA_SAFE_ASSERT(data == nullptr);

if (jackbridge_shm_map3<BridgeNonRtClientData>(shm, data))
{
setRingBuffer(&data->ringBuffer, false);
return true;
}

return false;
}

void unmapData() noexcept
{
data = nullptr;
setRingBuffer(nullptr, false);
}

PluginBridgeNonRtClientOpcode readOpcode() noexcept
{
return static_cast<PluginBridgeNonRtClientOpcode>(readUInt());
}

CARLA_DECLARE_NON_COPY_STRUCT(BridgeNonRtClientControl)
};

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

struct BridgeNonRtServerControl : public CarlaRingBufferControl<HugeStackBuffer> {
CarlaMutex mutex;
CarlaString filename;
BridgeNonRtServerData* data;
char shm[64];

BridgeNonRtServerControl() noexcept
: mutex(),
filename(),
data(nullptr)
{
carla_zeroChars(shm, 64);
jackbridge_shm_init(shm);
}

~BridgeNonRtServerControl() noexcept override
{
// should be cleared by now
CARLA_SAFE_ASSERT(data == nullptr);

clear();
}

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

if (data != nullptr)
unmapData();

if (! jackbridge_shm_is_valid(shm))
{
CARLA_SAFE_ASSERT(data == nullptr);
return;
}

jackbridge_shm_close(shm);
jackbridge_shm_init(shm);
}

bool attach() noexcept
{
// must be invalid right now
CARLA_SAFE_ASSERT_RETURN(! jackbridge_shm_is_valid(shm), false);

jackbridge_shm_attach(shm, filename);

return jackbridge_shm_is_valid(shm);
}

bool mapData() noexcept
{
CARLA_SAFE_ASSERT(data == nullptr);

if (jackbridge_shm_map3<BridgeNonRtServerData>(shm, data))
{
setRingBuffer(&data->ringBuffer, false);
return true;
}

return false;
}

void unmapData() noexcept
{
data = nullptr;
setRingBuffer(nullptr, false);
}

void writeOpcode(const PluginBridgeNonRtServerOpcode opcode) noexcept
{
writeUInt(static_cast<uint32_t>(opcode));
}

void waitIfDataIsReachingLimit() noexcept
{
if (getAvailableDataSize() < HugeStackBuffer::size/4)
return;

for (int i=50; --i >= 0;)
{
if (getAvailableDataSize() >= HugeStackBuffer::size*3/4)
{
writeOpcode(kPluginBridgeNonRtServerPong);
commitWrite();
return;
}
carla_msleep(20);
}

carla_stderr("Client waitIfDataIsReachingLimit() reached and failed");
}

CARLA_DECLARE_NON_COPY_STRUCT(BridgeNonRtServerControl)
};

// -----------------------------------------------------------------------
// Bridge Engine client

@@ -271,17 +89,13 @@ public:
fShmNonRtServerControl(),
fBaseNameAudioPool(audioPoolBaseName),
fBaseNameRtClientControl(rtClientBaseName),
fBaseNameNonRtClientControl(nonRtClientBaseName),
fBaseNameNonRtServerControl(nonRtServerBaseName),
fIsOffline(false),
fFirstIdle(true),
fLastPingTime(-1)
{
carla_debug("CarlaEngineBridge::CarlaEngineBridge(\"%s\", \"%s\", \"%s\", \"%s\")", audioPoolBaseName, rtClientBaseName, nonRtClientBaseName, nonRtServerBaseName);

fShmNonRtClientControl.filename = PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_CLIENT;
fShmNonRtClientControl.filename += nonRtClientBaseName;

fShmNonRtServerControl.filename = PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_SERVER;
fShmNonRtServerControl.filename += nonRtServerBaseName;
}

~CarlaEngineBridge() noexcept override
@@ -324,7 +138,7 @@ public:
return false;
}

if (! fShmNonRtClientControl.attach())
if (! fShmNonRtClientControl.attachClient(fBaseNameNonRtClientControl))
{
clear();
carla_stderr("Failed to attach to non-rt client control shared memory");
@@ -338,7 +152,7 @@ public:
return false;
}

if (! fShmNonRtServerControl.attach())
if (! fShmNonRtServerControl.attachClient(fBaseNameNonRtServerControl))
{
clear();
carla_stderr("Failed to attach to non-rt server control shared memory");
@@ -1491,6 +1305,8 @@ private:

CarlaString fBaseNameAudioPool;
CarlaString fBaseNameRtClientControl;
CarlaString fBaseNameNonRtClientControl;
CarlaString fBaseNameNonRtServerControl;

bool fIsOffline;
bool fFirstIdle;


+ 2
- 212
source/backend/plugin/CarlaPluginBridge.cpp View File

@@ -51,216 +51,6 @@ static const ExternalMidiNote kExternalMidiNoteFallback = { -1, 0, 0 };

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

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

BridgeNonRtClientControl() noexcept
: data(nullptr),
filename(),
mutex()
#ifdef CARLA_PROPER_CPP11_SUPPORT
, shm(carla_shm_t_INIT) {}
#else
{
carla_shm_init(shm);
}
#endif

~BridgeNonRtClientControl() noexcept override
{
// should be cleared by now
CARLA_SAFE_ASSERT(data == nullptr);

clear();
}

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

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

shm = carla_shm_create_temp(tmpFileBase);

CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm), false);

if (! mapData())
{
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)
unmapData();

if (! carla_is_shm_valid(shm))
return;

carla_shm_close(shm);
carla_shm_init(shm);
}

bool mapData() noexcept
{
CARLA_SAFE_ASSERT(data == nullptr);

if (carla_shm_map<BridgeNonRtClientData>(shm, data))
{
setRingBuffer(&data->ringBuffer, true);
return true;
}

return false;
}

void unmapData() noexcept
{
CARLA_SAFE_ASSERT_RETURN(data != nullptr,);

carla_shm_unmap(shm, data);
data = nullptr;

setRingBuffer(nullptr, false);
}

void writeOpcode(const PluginBridgeNonRtClientOpcode opcode) noexcept
{
writeUInt(static_cast<uint32_t>(opcode));
}

void waitIfDataIsReachingLimit() noexcept
{
if (getAvailableDataSize() < BigStackBuffer::size/4)
return;

for (int i=50; --i >= 0;)
{
if (getAvailableDataSize() >= BigStackBuffer::size*3/4)
{
writeOpcode(kPluginBridgeNonRtClientPing);
commitWrite();
return;
}
carla_msleep(20);
}

carla_stderr("Server waitIfDataIsReachingLimit() reached and failed");
}

CARLA_DECLARE_NON_COPY_STRUCT(BridgeNonRtClientControl)
};

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

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

BridgeNonRtServerControl() noexcept
: data(nullptr),
filename()
#ifdef CARLA_PROPER_CPP11_SUPPORT
, shm(carla_shm_t_INIT) {}
#else
{
carla_shm_init(shm);
}
#endif

~BridgeNonRtServerControl() noexcept override
{
// should be cleared by now
CARLA_SAFE_ASSERT(data == nullptr);

clear();
}

bool initialize() noexcept
{
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))
return false;

if (! mapData())
{
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)
unmapData();

if (! carla_is_shm_valid(shm))
return;

carla_shm_close(shm);
carla_shm_init(shm);
}

bool mapData() noexcept
{
CARLA_SAFE_ASSERT(data == nullptr);

if (carla_shm_map<BridgeNonRtServerData>(shm, data))
{
setRingBuffer(&data->ringBuffer, true);
return true;
}

return false;
}

void unmapData() noexcept
{
CARLA_SAFE_ASSERT_RETURN(data != nullptr,);

carla_shm_unmap(shm, data);
data = nullptr;

setRingBuffer(nullptr, false);
}

PluginBridgeNonRtServerOpcode readOpcode() noexcept
{
return static_cast<PluginBridgeNonRtServerOpcode>(readUInt());
}

CARLA_DECLARE_NON_COPY_STRUCT(BridgeNonRtServerControl)
};

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

struct BridgeParamInfo {
float value;
CarlaString name;
@@ -2359,7 +2149,7 @@ public:
return false;
}

if (! fShmNonRtClientControl.initialize())
if (! fShmNonRtClientControl.initializeServer())
{
carla_stderr("Failed to initialize Non-RT client control");
fShmRtClientControl.clear();
@@ -2367,7 +2157,7 @@ public:
return false;
}

if (! fShmNonRtServerControl.initialize())
if (! fShmNonRtServerControl.initializeServer())
{
carla_stderr("Failed to initialize Non-RT server control");
fShmNonRtClientControl.clear();


+ 301
- 15
source/utils/CarlaBridgeUtils.cpp View File

@@ -126,6 +126,7 @@ void BridgeAudioPool::clear() noexcept
jackbridge_shm_init(shm);
}

#ifndef BUILD_BRIDGE
void BridgeAudioPool::resize(const uint32_t bufferSize, const uint32_t audioPortCount, const uint32_t cvPortCount) noexcept
{
CARLA_SAFE_ASSERT_RETURN(jackbridge_shm_is_valid(shm),);
@@ -143,6 +144,7 @@ void BridgeAudioPool::resize(const uint32_t bufferSize, const uint32_t audioPort

std::memset(data, 0, dataSize);
}
#endif

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

@@ -258,15 +260,15 @@ bool BridgeRtClientControl::mapData() noexcept

if (jackbridge_shm_map2<BridgeRtClientData>(shm, data))
{
#ifndef BUILD_BRIDGE
std::memset(data, 0, sizeof(BridgeRtClientData));
setRingBuffer(&data->ringBuffer, true);
#else
#ifdef BUILD_BRIDGE
CARLA_SAFE_ASSERT(data->midiOut[0] == 0);
setRingBuffer(&data->ringBuffer, false);

CARLA_SAFE_ASSERT_RETURN(jackbridge_sem_connect(&data->sem.server), false);
CARLA_SAFE_ASSERT_RETURN(jackbridge_sem_connect(&data->sem.client), false);
#else
std::memset(data, 0, sizeof(BridgeRtClientData));
setRingBuffer(&data->ringBuffer, true);
#endif
return true;
}
@@ -286,44 +288,328 @@ void BridgeRtClientControl::unmapData() noexcept
setRingBuffer(nullptr, false);
}

#ifndef BUILD_BRIDGE
bool BridgeRtClientControl::waitForClient(const uint msecs) noexcept
{
CARLA_SAFE_ASSERT_RETURN(msecs > 0, false);
CARLA_SAFE_ASSERT_RETURN(data != nullptr, false);

#ifndef BUILD_BRIDGE
jackbridge_sem_post(&data->sem.server, true);

return jackbridge_sem_timedwait(&data->sem.client, msecs, true);
return false;
}

void BridgeRtClientControl::writeOpcode(const PluginBridgeRtClientOpcode opcode) noexcept
{
writeUInt(static_cast<uint32_t>(opcode));
}
#else
PluginBridgeRtClientOpcode BridgeRtClientControl::readOpcode() noexcept
{
return static_cast<PluginBridgeRtClientOpcode>(readUInt());
}

BridgeRtClientControl::WaitHelper::WaitHelper(BridgeRtClientControl& c) noexcept
: data(c.data),
ok(jackbridge_sem_timedwait(&data->sem.server, 5000, false)) {}

BridgeRtClientControl::WaitHelper::~WaitHelper() noexcept
{
if (ok)
jackbridge_sem_post(&data->sem.client, false);
}
#endif

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

BridgeNonRtClientControl::BridgeNonRtClientControl() noexcept
: data(nullptr),
filename(),
mutex()
{
carla_zeroChars(shm, 64);
jackbridge_shm_init(shm);
}

BridgeNonRtClientControl::~BridgeNonRtClientControl() noexcept
{
// should be cleared by now
CARLA_SAFE_ASSERT(data == nullptr);

clear();
}

bool BridgeNonRtClientControl::initializeServer() noexcept
{
#ifndef BUILD_BRIDGE
char tmpFileBase[64];
std::sprintf(tmpFileBase, PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_CLIENT "XXXXXX");

const carla_shm_t shm2 = carla_shm_create_temp(tmpFileBase);
CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm2), false);

void* const shmptr = shm;
carla_shm_t& shm1 = *(carla_shm_t*)shmptr;
carla_copyStruct(shm1, shm2);

if (! mapData())
{
jackbridge_shm_close(shm);
jackbridge_shm_init(shm);
return false;
}

CARLA_SAFE_ASSERT(data != nullptr);

filename = tmpFileBase;
return true;
#else
return false;
#endif
}

PluginBridgeRtClientOpcode BridgeRtClientControl::readOpcode() noexcept
bool BridgeNonRtClientControl::attachClient(const char* const basename) noexcept
{
CARLA_SAFE_ASSERT_RETURN(basename != nullptr && basename[0] != '\0', false);

#ifdef BUILD_BRIDGE
return static_cast<PluginBridgeRtClientOpcode>(readUInt());
// must be invalid right now
CARLA_SAFE_ASSERT_RETURN(! jackbridge_shm_is_valid(shm), false);

filename = PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_CLIENT;
filename += basename;

jackbridge_shm_attach(shm, filename);

return jackbridge_shm_is_valid(shm);
#else
return kPluginBridgeRtClientNull;
return false;
#endif
}

void BridgeRtClientControl::writeOpcode(const PluginBridgeRtClientOpcode opcode) noexcept
void BridgeNonRtClientControl::clear() noexcept
{
filename.clear();

if (data != nullptr)
unmapData();

if (! jackbridge_shm_is_valid(shm))
{
#ifdef BUILD_BRIDGE
CARLA_SAFE_ASSERT(data == nullptr);
#endif
return;
}

jackbridge_shm_close(shm);
jackbridge_shm_init(shm);
}

bool BridgeNonRtClientControl::mapData() noexcept
{
CARLA_SAFE_ASSERT(data == nullptr);

if (jackbridge_shm_map2<BridgeNonRtClientData>(shm, data))
{
#ifdef BUILD_BRIDGE
setRingBuffer(&data->ringBuffer, false);
#else
setRingBuffer(&data->ringBuffer, true);
#endif
return true;
}

return false;
}

void BridgeNonRtClientControl::unmapData() noexcept
{
#ifndef BUILD_BRIDGE
CARLA_SAFE_ASSERT_RETURN(data != nullptr,);

jackbridge_shm_unmap(shm, data);
#endif

data = nullptr;
setRingBuffer(nullptr, false);
}

#ifndef BUILD_BRIDGE
void BridgeNonRtClientControl::waitIfDataIsReachingLimit() noexcept
{
if (getAvailableDataSize() < BigStackBuffer::size/4)
return;

for (int i=50; --i >= 0;)
{
if (getAvailableDataSize() >= BigStackBuffer::size*3/4)
{
writeOpcode(kPluginBridgeNonRtClientPing);
commitWrite();
return;
}
carla_msleep(20);
}

carla_stderr("Server waitIfDataIsReachingLimit() reached and failed");
}

void BridgeNonRtClientControl::writeOpcode(const PluginBridgeNonRtClientOpcode opcode) noexcept
{
writeUInt(static_cast<uint32_t>(opcode));
}
#else
PluginBridgeNonRtClientOpcode BridgeNonRtClientControl::readOpcode() noexcept
{
return static_cast<PluginBridgeNonRtClientOpcode>(readUInt());
return kPluginBridgeNonRtClientNull;
}
#endif

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

BridgeNonRtServerControl::BridgeNonRtServerControl() noexcept
: data(nullptr),
filename(),
mutex()
{
carla_zeroChars(shm, 64);
jackbridge_shm_init(shm);
}

BridgeRtClientControl::WaitHelper::WaitHelper(BridgeRtClientControl& c) noexcept
: data(c.data),
ok(jackbridge_sem_timedwait(&data->sem.server, 5000, false)) {}
BridgeNonRtServerControl::~BridgeNonRtServerControl() noexcept
{
// should be cleared by now
CARLA_SAFE_ASSERT(data == nullptr);

BridgeRtClientControl::WaitHelper::~WaitHelper() noexcept
clear();
}

bool BridgeNonRtServerControl::initializeServer() noexcept
{
if (ok)
jackbridge_sem_post(&data->sem.client, false);
#ifndef BUILD_BRIDGE
char tmpFileBase[64];
std::sprintf(tmpFileBase, PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_SERVER "XXXXXX");

const carla_shm_t shm2 = carla_shm_create_temp(tmpFileBase);
CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm2), false);

void* const shmptr = shm;
carla_shm_t& shm1 = *(carla_shm_t*)shmptr;
carla_copyStruct(shm1, shm2);

if (! mapData())
{
jackbridge_shm_close(shm);
jackbridge_shm_init(shm);
return false;
}

CARLA_SAFE_ASSERT(data != nullptr);

filename = tmpFileBase;
return true;
#else
return false;
#endif
}

bool BridgeNonRtServerControl::attachClient(const char* const basename) noexcept
{
CARLA_SAFE_ASSERT_RETURN(basename != nullptr && basename[0] != '\0', false);

#ifdef BUILD_BRIDGE
// must be invalid right now
CARLA_SAFE_ASSERT_RETURN(! jackbridge_shm_is_valid(shm), false);

filename = PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_SERVER;
filename += basename;

jackbridge_shm_attach(shm, filename);

return jackbridge_shm_is_valid(shm);
#else
return false;
#endif
}

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

if (data != nullptr)
unmapData();

if (! jackbridge_shm_is_valid(shm))
{
CARLA_SAFE_ASSERT(data == nullptr);
return;
}

jackbridge_shm_close(shm);
jackbridge_shm_init(shm);
}

bool BridgeNonRtServerControl::mapData() noexcept
{
CARLA_SAFE_ASSERT(data == nullptr);

if (jackbridge_shm_map2<BridgeNonRtServerData>(shm, data))
{
#ifdef BUILD_BRIDGE
setRingBuffer(&data->ringBuffer, false);
#else
setRingBuffer(&data->ringBuffer, true);
#endif
return true;
}

return false;
}

void BridgeNonRtServerControl::unmapData() noexcept
{
#ifndef BUILD_BRIDGE
CARLA_SAFE_ASSERT_RETURN(data != nullptr,);

jackbridge_shm_unmap(shm, data);
#endif

data = nullptr;
setRingBuffer(nullptr, false);
}

#ifndef BUILD_BRIDGE
PluginBridgeNonRtServerOpcode BridgeNonRtServerControl::readOpcode() noexcept
{
return static_cast<PluginBridgeNonRtServerOpcode>(readUInt());
}
#else
void BridgeNonRtServerControl::waitIfDataIsReachingLimit() noexcept
{
if (getAvailableDataSize() < HugeStackBuffer::size/4)
return;

for (int i=50; --i >= 0;)
{
if (getAvailableDataSize() >= HugeStackBuffer::size*3/4)
{
writeOpcode(kPluginBridgeNonRtServerPong);
commitWrite();
return;
}
carla_msleep(20);
}

carla_stderr("Client waitIfDataIsReachingLimit() reached and failed");
}

void BridgeNonRtServerControl::writeOpcode(const PluginBridgeNonRtServerOpcode opcode) noexcept
{
writeUInt(static_cast<uint32_t>(opcode));
}
#endif

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

+ 68
- 3
source/utils/CarlaBridgeUtils.hpp View File

@@ -19,6 +19,7 @@
#define CARLA_BRIDGE_UTILS_HPP_INCLUDED

#include "CarlaBridgeDefines.hpp"
#include "CarlaMutex.hpp"
#include "CarlaString.hpp"

#if defined(CARLA_OS_WIN) && defined(BUILDING_CARLA_FOR_WINDOWS)
@@ -211,7 +212,9 @@ struct BridgeAudioPool {
bool attachClient(const char* const fname) noexcept;
void clear() noexcept;

#ifndef BUILD_BRIDGE
void resize(const uint32_t bufferSize, const uint32_t audioPortCount, const uint32_t cvPortCount) noexcept;
#endif

CARLA_DECLARE_NON_COPY_STRUCT(BridgeAudioPool)
};
@@ -234,11 +237,12 @@ struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> {
bool mapData() noexcept;
void unmapData() noexcept;

// Client calls
#ifndef BUILD_BRIDGE
// non-bridge, server
bool waitForClient(const uint msecs) noexcept;
void writeOpcode(const PluginBridgeRtClientOpcode opcode) noexcept;
// Servers calls
#else
// bridge, client
PluginBridgeRtClientOpcode readOpcode() noexcept;

// helper class that automatically posts semaphore on destructor
@@ -251,10 +255,71 @@ struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> {

CARLA_DECLARE_NON_COPY_STRUCT(WaitHelper)
};
#endif

CARLA_DECLARE_NON_COPY_STRUCT(BridgeRtClientControl)
};

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

struct BridgeNonRtClientControl : public CarlaRingBufferControl<BigStackBuffer> {
BridgeNonRtClientData* data;
CarlaString filename;
CarlaMutex mutex;
char shm[64];

BridgeNonRtClientControl() noexcept;
~BridgeNonRtClientControl() noexcept override;

bool initializeServer() noexcept;
bool attachClient(const char* const basename) noexcept;
void clear() noexcept;

bool mapData() noexcept;
void unmapData() noexcept;

#ifndef BUILD_BRIDGE
// non-bridge, server
void waitIfDataIsReachingLimit() noexcept;
void writeOpcode(const PluginBridgeNonRtClientOpcode opcode) noexcept;
#else
// bridge, client
PluginBridgeNonRtClientOpcode readOpcode() noexcept;
#endif

CARLA_DECLARE_NON_COPY_STRUCT(BridgeNonRtClientControl)
};

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

struct BridgeNonRtServerControl : public CarlaRingBufferControl<HugeStackBuffer> {
BridgeNonRtServerData* data;
CarlaString filename;
CarlaMutex mutex;
char shm[64];

BridgeNonRtServerControl() noexcept;
~BridgeNonRtServerControl() noexcept override;

bool initializeServer() noexcept;
bool attachClient(const char* const basename) noexcept;
void clear() noexcept;

bool mapData() noexcept;
void unmapData() noexcept;

#ifndef BUILD_BRIDGE
// non-bridge, server
PluginBridgeNonRtServerOpcode readOpcode() noexcept;
#else
// bridge, client
void waitIfDataIsReachingLimit() noexcept;
void writeOpcode(const PluginBridgeNonRtServerOpcode opcode) noexcept;
#endif

CARLA_DECLARE_NON_COPY_STRUCT(BridgeNonRtServerControl)
};

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

#endif // CARLA_BRIDGE_UTILS_HPP_INCLUDED

Loading…
Cancel
Save