Browse Source

Init libjack class on load

tags/1.9.8
falkTX 7 years ago
parent
commit
cebd6d0802
1 changed files with 131 additions and 171 deletions
  1. +131
    -171
      source/interposer/libjack.cpp

+ 131
- 171
source/interposer/libjack.cpp View File

@@ -156,17 +156,10 @@ class CarlaJackClient : public Thread
public:
JackClientState fState;

CarlaJackClient(const char* const audioPoolBaseName, const char* const rtClientBaseName, const char* const nonRtClientBaseName, const char* const nonRtServerBaseName)
CarlaJackClient()
: Thread("CarlaJackClient"),
fState(),
fShmAudioPool(),
fShmRtClientControl(),
fShmNonRtClientControl(),
fShmNonRtServerControl(),
fBaseNameAudioPool(audioPoolBaseName),
fBaseNameRtClientControl(rtClientBaseName),
fBaseNameNonRtClientControl(nonRtClientBaseName),
fBaseNameNonRtServerControl(nonRtServerBaseName),
fIsValid(false),
fIsOffline(false),
fFirstIdle(true),
fLastPingTime(-1),
@@ -174,118 +167,27 @@ public:
fAudioOuts(0)
{
carla_debug("CarlaJackClient::CarlaJackClient(\"%s\", \"%s\", \"%s\", \"%s\")", audioPoolBaseName, rtClientBaseName, nonRtClientBaseName, nonRtServerBaseName);
}

~CarlaJackClient() noexcept override
{
carla_debug("CarlaJackClient::~CarlaJackClient()");

clear();
}

bool init(const char* const clientName)
{
carla_debug("CarlaJackClient::init(\"%s\")", clientName);

if (! fShmAudioPool.attachClient(fBaseNameAudioPool))
{
carla_stderr("Failed to attach to audio pool shared memory");
return false;
}
const char* const shmIds(std::getenv("CARLA_SHM_IDS"));
CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr && std::strlen(shmIds) == 6*4,);

if (! fShmRtClientControl.attachClient(fBaseNameRtClientControl))
{
clear();
carla_stderr("Failed to attach to rt client control shared memory");
return false;
}
std::memcpy(fBaseNameAudioPool, shmIds+6*0, 6);
std::memcpy(fBaseNameRtClientControl, shmIds+6*1, 6);
std::memcpy(fBaseNameNonRtClientControl, shmIds+6*2, 6);
std::memcpy(fBaseNameNonRtServerControl, shmIds+6*3, 6);

if (! fShmRtClientControl.mapData())
{
clear();
carla_stderr("Failed to map rt client control shared memory");
return false;
}

if (! fShmNonRtClientControl.attachClient(fBaseNameNonRtClientControl))
{
clear();
carla_stderr("Failed to attach to non-rt client control shared memory");
return false;
}

if (! fShmNonRtClientControl.mapData())
{
clear();
carla_stderr("Failed to map non-rt control client shared memory");
return false;
}

if (! fShmNonRtServerControl.attachClient(fBaseNameNonRtServerControl))
{
clear();
carla_stderr("Failed to attach to non-rt server control shared memory");
return false;
}

if (! fShmNonRtServerControl.mapData())
{
clear();
carla_stderr("Failed to map non-rt control server shared memory");
return false;
}

PluginBridgeNonRtClientOpcode opcode;

opcode = fShmNonRtClientControl.readOpcode();
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientNull, opcode);

const uint32_t shmRtClientDataSize = fShmNonRtClientControl.readUInt();
CARLA_SAFE_ASSERT_INT2(shmRtClientDataSize == sizeof(BridgeRtClientData), shmRtClientDataSize, sizeof(BridgeRtClientData));

const uint32_t shmNonRtClientDataSize = fShmNonRtClientControl.readUInt();
CARLA_SAFE_ASSERT_INT2(shmNonRtClientDataSize == sizeof(BridgeNonRtClientData), shmNonRtClientDataSize, sizeof(BridgeNonRtClientData));

const uint32_t shmNonRtServerDataSize = fShmNonRtClientControl.readUInt();
CARLA_SAFE_ASSERT_INT2(shmNonRtServerDataSize == sizeof(BridgeNonRtServerData), shmNonRtServerDataSize, sizeof(BridgeNonRtServerData));

if (shmRtClientDataSize != sizeof(BridgeRtClientData) || shmNonRtClientDataSize != sizeof(BridgeNonRtClientData) || shmNonRtServerDataSize != sizeof(BridgeNonRtServerData))
{
carla_stderr2("CarlaJackClient: data size mismatch");
return false;
}

opcode = fShmNonRtClientControl.readOpcode();
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientSetBufferSize, opcode);
fState.bufferSize = fShmNonRtClientControl.readUInt();

opcode = fShmNonRtClientControl.readOpcode();
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientSetSampleRate, opcode);
fState.sampleRate = fShmNonRtClientControl.readDouble();

if (fState.bufferSize == 0 || carla_isZero(fState.sampleRate))
{
carla_stderr2("CarlaJackClient: invalid empty state");
return false;
}

fState.name = strdup(clientName);

// tell backend we're live
{
const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);

fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPong);
fShmNonRtServerControl.commitWrite();
}
fBaseNameAudioPool[6] = '\0';
fBaseNameRtClientControl[6] = '\0';
fBaseNameNonRtClientControl[6] = '\0';
fBaseNameNonRtServerControl[6] = '\0';

startThread(10);

return true;
}

bool close()
~CarlaJackClient() noexcept override
{
carla_debug("CarlaJackClient::~CarlaJackClient()");

carla_debug("CarlaEnginePlugin::close()");
fLastPingTime = -1;

@@ -306,8 +208,16 @@ public:

fState.audioIns.clear();
fState.audioOuts.clear();
}

bool initIfNeeded(const char* const clientName)
{
carla_debug("CarlaJackClient::initIfNeeded(\"%s\")", clientName);

if (fState.name == nullptr)
fState.name = strdup(clientName);

return true;
return fIsValid;
}

void clear() noexcept
@@ -318,6 +228,11 @@ public:
fShmNonRtServerControl.clear();
}

bool isValid() const noexcept
{
return fIsValid;
}

void activate()
{
const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
@@ -607,6 +522,98 @@ protected:
{
carla_stderr("CarlaJackClient run START");

if (! fShmAudioPool.attachClient(fBaseNameAudioPool))
{
carla_stderr("Failed to attach to audio pool shared memory");
return;
}

if (! fShmRtClientControl.attachClient(fBaseNameRtClientControl))
{
clear();
carla_stderr("Failed to attach to rt client control shared memory");
return;
}

if (! fShmRtClientControl.mapData())
{
clear();
carla_stderr("Failed to map rt client control shared memory");
return;
}

if (! fShmNonRtClientControl.attachClient(fBaseNameNonRtClientControl))
{
clear();
carla_stderr("Failed to attach to non-rt client control shared memory");
return;
}

if (! fShmNonRtClientControl.mapData())
{
clear();
carla_stderr("Failed to map non-rt control client shared memory");
return;
}

if (! fShmNonRtServerControl.attachClient(fBaseNameNonRtServerControl))
{
clear();
carla_stderr("Failed to attach to non-rt server control shared memory");
return;
}

if (! fShmNonRtServerControl.mapData())
{
clear();
carla_stderr("Failed to map non-rt control server shared memory");
return;
}

PluginBridgeNonRtClientOpcode opcode;

opcode = fShmNonRtClientControl.readOpcode();
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientNull, opcode);

const uint32_t shmRtClientDataSize = fShmNonRtClientControl.readUInt();
CARLA_SAFE_ASSERT_INT2(shmRtClientDataSize == sizeof(BridgeRtClientData), shmRtClientDataSize, sizeof(BridgeRtClientData));

const uint32_t shmNonRtClientDataSize = fShmNonRtClientControl.readUInt();
CARLA_SAFE_ASSERT_INT2(shmNonRtClientDataSize == sizeof(BridgeNonRtClientData), shmNonRtClientDataSize, sizeof(BridgeNonRtClientData));

const uint32_t shmNonRtServerDataSize = fShmNonRtClientControl.readUInt();
CARLA_SAFE_ASSERT_INT2(shmNonRtServerDataSize == sizeof(BridgeNonRtServerData), shmNonRtServerDataSize, sizeof(BridgeNonRtServerData));

if (shmRtClientDataSize != sizeof(BridgeRtClientData) || shmNonRtClientDataSize != sizeof(BridgeNonRtClientData) || shmNonRtServerDataSize != sizeof(BridgeNonRtServerData))
{
carla_stderr2("CarlaJackClient: data size mismatch");
return;
}

opcode = fShmNonRtClientControl.readOpcode();
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientSetBufferSize, opcode);
fState.bufferSize = fShmNonRtClientControl.readUInt();

opcode = fShmNonRtClientControl.readOpcode();
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientSetSampleRate, opcode);
fState.sampleRate = fShmNonRtClientControl.readDouble();

if (fState.bufferSize == 0 || carla_isZero(fState.sampleRate))
{
carla_stderr2("CarlaJackClient: invalid empty state");
return;
}

// tell backend we're live
{
const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);

fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPong);
fShmNonRtServerControl.commitWrite();
}

fIsValid = true;

#ifdef __SSE2_MATH__
// Set FTZ and DAZ flags
_mm_setcsr(_mm_getcsr() | 0x8040);
@@ -791,11 +798,12 @@ private:
BridgeNonRtClientControl fShmNonRtClientControl;
BridgeNonRtServerControl fShmNonRtServerControl;

CarlaString fBaseNameAudioPool;
CarlaString fBaseNameRtClientControl;
CarlaString fBaseNameNonRtClientControl;
CarlaString fBaseNameNonRtServerControl;
char fBaseNameAudioPool[6+1];
char fBaseNameRtClientControl[6+1];
char fBaseNameNonRtClientControl[6+1];
char fBaseNameNonRtServerControl[6+1];

bool fIsValid;
bool fIsOffline;
bool fFirstIdle;
int64_t fLastPingTime;
@@ -814,57 +822,23 @@ CARLA_BACKEND_END_NAMESPACE

CARLA_BACKEND_USE_NAMESPACE

static CarlaJackClient* gClient = nullptr;
static int gClientRefCount = 0;
static CarlaJackClient gClient;
static int gClientRefCount = 0;

CARLA_EXPORT
jack_client_t* jack_client_open(const char* client_name, jack_options_t /*options*/, jack_status_t* status, ...)
{
carla_stdout("CarlaJackClient :: %s", __FUNCTION__);

if (gClient != nullptr)
{
++gClientRefCount;
return (jack_client_t*)gClient;
}

const char* const shmIds(std::getenv("CARLA_SHM_IDS"));

if (shmIds == nullptr || std::strlen(shmIds) != 6*4)
{
if (status != nullptr)
*status = JackFailure;
return nullptr;
}

char audioPoolBaseName[6+1];
char rtClientBaseName[6+1];
char nonRtClientBaseName[6+1];
char nonRtServerBaseName[6+1];

std::memcpy(audioPoolBaseName, shmIds+6*0, 6);
std::memcpy(rtClientBaseName, shmIds+6*1, 6);
std::memcpy(nonRtClientBaseName, shmIds+6*2, 6);
std::memcpy(nonRtServerBaseName, shmIds+6*3, 6);

audioPoolBaseName[6] = '\0';
rtClientBaseName[6] = '\0';
nonRtClientBaseName[6] = '\0';
nonRtServerBaseName[6] = '\0';

CarlaJackClient* const client = new CarlaJackClient(audioPoolBaseName, rtClientBaseName,
nonRtClientBaseName, nonRtServerBaseName);

if (! client->init(client_name))
if (! gClient.initIfNeeded(client_name))
{
if (status != nullptr)
*status = JackServerError;
return nullptr;
}

gClient = client;
++gClientRefCount;
return (jack_client_t*)client;
return (jack_client_t*)&gClient;
}

CARLA_EXPORT
@@ -886,21 +860,7 @@ int jack_client_close(jack_client_t* client)
if (jstate.activated)
jclient->deactivate();

if (--gClientRefCount == 0)
{
#if 0
static bool ignoreFirstClientClose = true;
if (ignoreFirstClientClose)
{
ignoreFirstClientClose = false;
return 0;
}
#endif
jclient->close();
delete jclient;
gClient = nullptr;
}

--gClientRefCount;
return 0;
}



Loading…
Cancel
Save