Browse Source

Start final code recheck; Add some safety checks to LinkedList

tags/1.9.7
falkTX 10 years ago
parent
commit
7787508b6c
6 changed files with 291 additions and 146 deletions
  1. +217
    -92
      source/backend/plugin/CarlaPluginDSSI.cpp
  2. +10
    -10
      source/backend/plugin/CarlaPluginLADSPA.cpp
  3. +26
    -26
      source/tests/RtLinkedList.cpp
  4. +7
    -7
      source/tests/ansi-pedantic-test.c
  5. +29
    -9
      source/utils/LinkedList.hpp
  6. +2
    -2
      source/utils/RtLinkedList.hpp

+ 217
- 92
source/backend/plugin/CarlaPluginDSSI.cpp View File

@@ -2034,85 +2034,154 @@ public:
CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize); CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
carla_debug("CarlaPluginDSSI::bufferSizeChanged(%i) - start", newBufferSize); carla_debug("CarlaPluginDSSI::bufferSizeChanged(%i) - start", newBufferSize);


const int iBufferSize(static_cast<int>(newBufferSize));

for (uint32_t i=0; i < pData->audioIn.count; ++i) for (uint32_t i=0; i < pData->audioIn.count; ++i)
{ {
if (fAudioInBuffers[i] != nullptr) if (fAudioInBuffers[i] != nullptr)
delete[] fAudioInBuffers[i]; delete[] fAudioInBuffers[i];

fAudioInBuffers[i] = new float[newBufferSize]; fAudioInBuffers[i] = new float[newBufferSize];
FloatVectorOperations::clear(fAudioInBuffers[i], iBufferSize);
} }


for (uint32_t i=0; i < pData->audioOut.count; ++i) for (uint32_t i=0; i < pData->audioOut.count; ++i)
{ {
if (fAudioOutBuffers[i] != nullptr) if (fAudioOutBuffers[i] != nullptr)
delete[] fAudioOutBuffers[i]; delete[] fAudioOutBuffers[i];

fAudioOutBuffers[i] = new float[newBufferSize]; fAudioOutBuffers[i] = new float[newBufferSize];
FloatVectorOperations::clear(fAudioOutBuffers[i], iBufferSize);
} }


if (fHandle2 == nullptr)
if (fExtraStereoBuffer[0] != nullptr)
{ {
for (uint32_t i=0; i < pData->audioIn.count; ++i)
delete[] fExtraStereoBuffer[0];
fExtraStereoBuffer[0] = nullptr;
}

if (fExtraStereoBuffer[1] != nullptr)
{
delete[] fExtraStereoBuffer[1];
fExtraStereoBuffer[1] = nullptr;
}

if (fForcedStereoIn && pData->audioOut.count == 2)
{
fExtraStereoBuffer[0] = new float[newBufferSize];
fExtraStereoBuffer[1] = new float[newBufferSize];
FloatVectorOperations::clear(fExtraStereoBuffer[0], iBufferSize);
FloatVectorOperations::clear(fExtraStereoBuffer[1], iBufferSize);
}

reconnectAudioPorts();

carla_debug("CarlaPluginDSSI::bufferSizeChanged(%i) - end", newBufferSize);
}

void sampleRateChanged(const double newSampleRate) override
{
CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
carla_debug("CarlaPluginDSSI::sampleRateChanged(%g) - start", newSampleRate);

// TODO - handle UI stuff

if (pData->active)
deactivate();

const std::size_t instanceCount(fHandles.count());

if (fDescriptor->cleanup == nullptr)
{
for (LinkedList<LADSPA_Handle>::Itenerator it = fHandles.begin(); it.valid(); it.next())
{ {
CARLA_ASSERT(fAudioInBuffers[i] != nullptr);
LADSPA_Handle const handle(it.getValue(nullptr));
CARLA_SAFE_ASSERT_CONTINUE(handle != nullptr);


try { try {
fDescriptor->connect_port(fHandle, pData->audioIn.ports[i].rindex, fAudioInBuffers[i]);
} CARLA_SAFE_EXCEPTION("DSSI connect_port audio input");
fDescriptor->cleanup(handle);
} CARLA_SAFE_EXCEPTION("LADSPA cleanup");
} }
}


for (uint32_t i=0; i < pData->audioOut.count; ++i)
fHandles.clear();

for (std::size_t i=0; i<instanceCount; ++i)
addInstance();

reconnectAudioPorts();

if (pData->active)
activate();

carla_debug("CarlaPluginDSSI::sampleRateChanged(%g) - end", newSampleRate);
}

void reconnectAudioPorts() const noexcept
{
if (fForcedStereoIn)
{
if (LADSPA_Handle const handle = fHandles.getAt(0, nullptr))
{ {
CARLA_ASSERT(fAudioOutBuffers[i] != nullptr);
try {
fDescriptor->connect_port(handle, pData->audioIn.ports[0].rindex, fAudioInBuffers[0]);
} CARLA_SAFE_EXCEPTION("DSSI connect_port (forced stereo input)");
}


if (LADSPA_Handle const handle = fHandles.getAt(1, nullptr))
{
try { try {
fDescriptor->connect_port(fHandle, pData->audioOut.ports[i].rindex, fAudioOutBuffers[i]);
} CARLA_SAFE_EXCEPTION("DSSI connect_port audio output");
fDescriptor->connect_port(handle, pData->audioIn.ports[1].rindex, fAudioInBuffers[1]);
} CARLA_SAFE_EXCEPTION("DSSI connect_port (forced stereo input)");
} }
} }
else else
{ {
if (pData->audioIn.count > 0)
for (LinkedList<LADSPA_Handle>::Itenerator it = fHandles.begin(); it.valid(); it.next())
{ {
CARLA_ASSERT(pData->audioIn.count == 2);
CARLA_ASSERT(fAudioInBuffers[0] != nullptr);
CARLA_ASSERT(fAudioInBuffers[1] != nullptr);
LADSPA_Handle const handle(it.getValue(nullptr));
CARLA_SAFE_ASSERT_CONTINUE(handle != nullptr);


try {
fDescriptor->connect_port(fHandle, pData->audioIn.ports[0].rindex, fAudioInBuffers[0]);
} CARLA_SAFE_EXCEPTION("DSSI connect_port audio input #1");

try {
fDescriptor->connect_port(fHandle2, pData->audioIn.ports[1].rindex, fAudioInBuffers[1]);
} CARLA_SAFE_EXCEPTION("DSSI connect_port audio input #2");
for (uint32_t i=0; i < pData->audioIn.count; ++i)
{
try {
fDescriptor->connect_port(handle, pData->audioIn.ports[i].rindex, fAudioInBuffers[i]);
} CARLA_SAFE_EXCEPTION("DSSI connect_port (audio input)");
}
} }
}


if (pData->audioOut.count > 0)
if (fForcedStereoOut)
{
if (LADSPA_Handle const handle = fHandles.getAt(0, nullptr))
{ {
CARLA_ASSERT(pData->audioOut.count == 2);
CARLA_ASSERT(fAudioOutBuffers[0] != nullptr);
CARLA_ASSERT(fAudioOutBuffers[1] != nullptr);

try { try {
fDescriptor->connect_port(fHandle, pData->audioOut.ports[0].rindex, fAudioOutBuffers[0]);
} CARLA_SAFE_EXCEPTION("DSSI connect_port audio output #1");
fDescriptor->connect_port(handle, pData->audioOut.ports[0].rindex, fAudioOutBuffers[0]);
} CARLA_SAFE_EXCEPTION("DSSI connect_port (forced stereo output)");
}


if (LADSPA_Handle const handle = fHandles.getAt(1, nullptr))
{
try { try {
fDescriptor->connect_port(fHandle2, pData->audioOut.ports[1].rindex, fAudioOutBuffers[1]);
} CARLA_SAFE_EXCEPTION("DSSI connect_port audio output #2");
fDescriptor->connect_port(handle, pData->audioOut.ports[1].rindex, fAudioOutBuffers[1]);
} CARLA_SAFE_EXCEPTION("DSSI connect_port (forced stereo output)");
} }
} }
else
{
for (LinkedList<LADSPA_Handle>::Itenerator it = fHandles.begin(); it.valid(); it.next())
{
LADSPA_Handle const handle(it.getValue(nullptr));
CARLA_SAFE_ASSERT_CONTINUE(handle != nullptr);


carla_debug("CarlaPluginDSSI::bufferSizeChanged(%i) - end", newBufferSize);
}

void sampleRateChanged(const double newSampleRate) override
{
CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
carla_debug("CarlaPluginDSSI::sampleRateChanged(%g) - start", newSampleRate);

// TODO
(void)newSampleRate;

carla_debug("CarlaPluginDSSI::sampleRateChanged(%g) - end", newSampleRate);
for (uint32_t i=0; i < pData->audioOut.count; ++i)
{
try {
fDescriptor->connect_port(handle, pData->audioOut.ports[i].rindex, fAudioOutBuffers[i]);
} CARLA_SAFE_EXCEPTION("DSSI connect_port (audio output)");
}
}
}
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -2152,6 +2221,18 @@ public:
fAudioOutBuffers = nullptr; fAudioOutBuffers = nullptr;
} }


if (fExtraStereoBuffer[0] != nullptr)
{
delete[] fExtraStereoBuffer[0];
fExtraStereoBuffer[0] = nullptr;
}

if (fExtraStereoBuffer[1] != nullptr)
{
delete[] fExtraStereoBuffer[1];
fExtraStereoBuffer[1] = nullptr;
}

if (fParamBuffers != nullptr) if (fParamBuffers != nullptr)
{ {
delete[] fParamBuffers; delete[] fParamBuffers;
@@ -2362,9 +2443,7 @@ public:
// tell frontend // tell frontend
pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr); pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr);
} }
#endif


#ifdef HAVE_LIBLO
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Post-poned UI Stuff // Post-poned UI Stuff


@@ -2426,15 +2505,10 @@ public:
osc_send_midi(fOscData, midiData); osc_send_midi(fOscData, midiData);
#endif #endif
} }
#endif
#endif // HAVE_LIBLO


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


void* getNativeHandle() const noexcept override
{
return fHandle;
}

const void* getNativeDescriptor() const noexcept override const void* getNativeDescriptor() const noexcept override
{ {
return fDssiDescriptor; return fDssiDescriptor;
@@ -2448,13 +2522,13 @@ public:


const void* getExtraStuff() const noexcept override const void* getExtraStuff() const noexcept override
{ {
return fUiFilename;
return fUiFilename.buffer();
} }
#endif #endif


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


bool init(const char* const filename, const char* const name, const char* const label)
bool init(const char* const filename, const char* const name, const char* const label, const uint options)
{ {
CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false); CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);


@@ -2502,15 +2576,13 @@ public:
// --------------------------------------------------------------- // ---------------------------------------------------------------
// get descriptor that matches label // get descriptor that matches label


ulong i = 0;

for (;;)
for (ulong d=0;; ++d)
{ {
try { try {
fDssiDescriptor = descFn(i++);
fDssiDescriptor = descFn(d);
} }
catch(...) { catch(...) {
carla_stderr2("Caught exception when trying to get LADSPA descriptor");
carla_stderr2("Caught exception when trying to get DSSI descriptor");
fDescriptor = nullptr; fDescriptor = nullptr;
fDssiDescriptor = nullptr; fDssiDescriptor = nullptr;
break; break;
@@ -2590,14 +2662,33 @@ public:
// --------------------------------------------------------------- // ---------------------------------------------------------------
// initialize plugin // initialize plugin


try {
fHandle = fDescriptor->instantiate(fDescriptor, (ulong)pData->engine->getSampleRate());
} CARLA_SAFE_EXCEPTION("DSSI instantiate");
if (! addInstance())
return false;

// ---------------------------------------------------------------
// find latency port index


if (fHandle == nullptr)
for (uint32_t i=0, iCtrl=0, count=getSafePortCount(); i<count; ++i)
{ {
pData->engine->setLastError("Plugin failed to initialize");
return false;
const int portType(fDescriptor->PortDescriptors[i]);

if (! LADSPA_IS_PORT_CONTROL(portType))
continue;

const uint32_t index(iCtrl++);

if (! LADSPA_IS_PORT_OUTPUT(portType))
continue;

const char* const portName(fDescriptor->PortNames[i]);
CARLA_SAFE_ASSERT_BREAK(portName != nullptr);

if (std::strcmp(portName, "latency") == 0 ||
std::strcmp(portName, "_latency") == 0)
{
fLatencyIndex = static_cast<int32_t>(index);
break;
}
} }


// --------------------------------------------------------------- // ---------------------------------------------------------------
@@ -2605,41 +2696,45 @@ public:


if (fDssiDescriptor->configure != nullptr) if (fDssiDescriptor->configure != nullptr)
{ {
if (char* const error = fDssiDescriptor->configure(fHandle, DSSI_CUSTOMDATA_EXTENSION_KEY, ""))
if (char* const error = fDssiDescriptor->configure(fHandles[0], DSSI_CUSTOMDATA_EXTENSION_KEY, ""))
{ {
if (std::strcmp(error, "true") == 0 && fDssiDescriptor->get_custom_data != nullptr && fDssiDescriptor->set_custom_data != nullptr)
if (std::strcmp(error, "true") == 0 && fDssiDescriptor->get_custom_data != nullptr
&& fDssiDescriptor->set_custom_data != nullptr)
fUsesCustomData = true; fUsesCustomData = true;


std::free(error); std::free(error);
} }
} }


// ---------------------------------------------------------------
// check if this is dssi-vst

fIsDssiVst = CarlaString(filename).contains("dssi-vst", true);

#ifdef HAVE_LIBLO #ifdef HAVE_LIBLO
// --------------------------------------------------------------- // ---------------------------------------------------------------
// gui stuff
// check for gui


if (const char* const guiFilename = find_dssi_ui(filename, fDescriptor->Label)) if (const char* const guiFilename = find_dssi_ui(filename, fDescriptor->Label))
{ {
fThreadUI.setData(guiFilename, fDescriptor->Label);
fUiFilename = guiFilename; fUiFilename = guiFilename;
fThreadUI.setData(guiFilename, fDescriptor->Label);
} }
#endif #endif


// --------------------------------------------------------------- // ---------------------------------------------------------------
// set default options // set default options


#ifdef __USE_GNU
const bool isDssiVst(strcasestr(pData->filename, "dssi-vst") != nullptr);
#else
const bool isDssiVst(std::strstr(pData->filename, "dssi-vst") != nullptr);
#endif

pData->options = 0x0; pData->options = 0x0;


if (fLatencyIndex >= 0 || isDssiVst)
/**/ if (fLatencyIndex >= 0 || fIsDssiVst)
pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
else if (options & PLUGIN_OPTION_FIXED_BUFFERS)
pData->options |= PLUGIN_OPTION_FIXED_BUFFERS; pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;


if (pData->engine->getOptions().forceStereo)
/**/ if (pData->engine->getOptions().forceStereo)
pData->options |= PLUGIN_OPTION_FORCE_STEREO;
else if (options & PLUGIN_OPTION_FORCE_STEREO)
pData->options |= PLUGIN_OPTION_FORCE_STEREO; pData->options |= PLUGIN_OPTION_FORCE_STEREO;


if (fUsesCustomData) if (fUsesCustomData)
@@ -2665,32 +2760,60 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------


private: private:
LADSPA_Handle fHandle;
LADSPA_Handle fHandle2;
const LADSPA_Descriptor* fDescriptor;
const DSSI_Descriptor* fDssiDescriptor;

bool fUsesCustomData;
#ifdef HAVE_LIBLO
const char* fUiFilename;
#endif
LinkedList<LADSPA_Handle> fHandles;
const LADSPA_Descriptor* fDescriptor;
const DSSI_Descriptor* fDssiDescriptor;


float** fAudioInBuffers; float** fAudioInBuffers;
float** fAudioOutBuffers; float** fAudioOutBuffers;
float* fExtraStereoBuffer[2]; // used only if forcedStereoIn and audioOut == 2
float* fParamBuffers; float* fParamBuffers;


bool fLatencyChanged;
int32_t fLatencyIndex; // -1 if invalid

snd_seq_event_t fMidiEvents[kPluginMaxMidiEvents]; snd_seq_event_t fMidiEvents[kPluginMaxMidiEvents];


int32_t fLatencyIndex; // -1 if invalid
bool fIsDssiVst;
bool fForcedStereoIn;
bool fForcedStereoOut;
bool fUsesCustomData;

#ifdef HAVE_LIBLO #ifdef HAVE_LIBLO
CarlaOscData fOscData; CarlaOscData fOscData;
CarlaThreadDSSIUI fThreadUI; CarlaThreadDSSIUI fThreadUI;
const char* fUiFilename;
#endif #endif


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


bool addInstance()
{
LADSPA_Handle handle;

try {
handle = fDescriptor->instantiate(fDescriptor, static_cast<ulong>(pData->engine->getSampleRate()));
} CARLA_SAFE_EXCEPTION_RETURN_ERR("LADSPA instantiate", "Plugin failed to initialize");

for (uint32_t i=0, count=pData->param.count; i<count; ++i)
{
const int32_t rindex(pData->param.data[i].rindex);
CARLA_SAFE_ASSERT_CONTINUE(rindex >= 0);

try {
fDescriptor->connect_port(handle, static_cast<ulong>(rindex), &fParamBuffers[i]);
} CARLA_SAFE_EXCEPTION("LADSPA connect_port");
}

if (fHandles.append(handle))
return true;

try {
fDescriptor->cleanup(handle);
} CARLA_SAFE_EXCEPTION("LADSPA cleanup");

pData->engine->setLastError("Out of memory");
return false;
}

uint32_t getSafePortCount() const noexcept uint32_t getSafePortCount() const noexcept
{ {
if (fDescriptor->PortCount == 0) if (fDescriptor->PortCount == 0)
@@ -2712,7 +2835,8 @@ private:
return false; return false;
} }


bool _getSeparatedParameterNameOrUnitImpl(const char* const paramName, char* const strBuf, const bool wantName, const bool useBracket) const noexcept
static bool _getSeparatedParameterNameOrUnitImpl(const char* const paramName, char* const strBuf,
const bool wantName, const bool useBracket) noexcept
{ {
const char* const sepBracketStart(std::strstr(paramName, useBracket ? " [" : " (")); const char* const sepBracketStart(std::strstr(paramName, useBracket ? " [" : " ("));


@@ -2724,15 +2848,15 @@ private:
if (sepBracketEnd == nullptr) if (sepBracketEnd == nullptr)
return false; return false;


const size_t unitSize(static_cast<size_t>(sepBracketEnd-sepBracketStart-2));
const std::size_t unitSize(static_cast<std::size_t>(sepBracketEnd-sepBracketStart-2));


if (unitSize > 7) // very unlikely to have such big unit if (unitSize > 7) // very unlikely to have such big unit
return false; return false;


const size_t sepIndex(std::strlen(paramName)-unitSize-3);
const std::size_t sepIndex(std::strlen(paramName)-unitSize-3);


// just in case // just in case
if (sepIndex > STR_MAX)
if (sepIndex+2 >= STR_MAX)
return false; return false;


if (wantName) if (wantName)
@@ -2805,11 +2929,12 @@ LinkedList<const char*> CarlaPluginDSSI::sMultiSynthList;


CarlaPlugin* CarlaPlugin::newDSSI(const Initializer& init) CarlaPlugin* CarlaPlugin::newDSSI(const Initializer& init)
{ {
carla_debug("CarlaPlugin::newDSSI({%p, \"%s\", \"%s\", \"%s\", " P_INT64 "})", init.engine, init.filename, init.name, init.label, init.uniqueId);
carla_debug("CarlaPlugin::newDSSI({%p, \"%s\", \"%s\", \"%s\", " P_INT64 ", %x})",
init.engine, init.filename, init.name, init.label, init.uniqueId, init.optons);


CarlaPluginDSSI* const plugin(new CarlaPluginDSSI(init.engine, init.id)); CarlaPluginDSSI* const plugin(new CarlaPluginDSSI(init.engine, init.id));


if (! plugin->init(init.filename, init.name, init.label))
if (! plugin->init(init.filename, init.name, init.label, init.options))
{ {
delete plugin; delete plugin;
return nullptr; return nullptr;


+ 10
- 10
source/backend/plugin/CarlaPluginLADSPA.cpp View File

@@ -1534,11 +1534,6 @@ public:


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


void* getNativeHandle() const noexcept override
{
return nullptr; // fHandle;
}

const void* getNativeDescriptor() const noexcept override const void* getNativeDescriptor() const noexcept override
{ {
return fDescriptor; return fDescriptor;
@@ -1577,8 +1572,6 @@ public:
return false; return false;
} }


fIsDssiVst = CarlaString(filename).contains("dssi-vst", true);

// --------------------------------------------------------------- // ---------------------------------------------------------------
// open DLL // open DLL


@@ -1699,6 +1692,11 @@ public:
} }
} }


// ---------------------------------------------------------------
// check if this is dssi-vst

fIsDssiVst = CarlaString(filename).contains("dssi-vst", true);

// --------------------------------------------------------------- // ---------------------------------------------------------------
// set default options // set default options


@@ -1786,7 +1784,8 @@ private:
return false; return false;
} }


static bool _getSeparatedParameterNameOrUnitImpl(const char* const paramName, char* const strBuf, const bool wantName, const bool useBracket) noexcept
static bool _getSeparatedParameterNameOrUnitImpl(const char* const paramName, char* const strBuf,
const bool wantName, const bool useBracket) noexcept
{ {
const char* const sepBracketStart(std::strstr(paramName, useBracket ? " [" : " (")); const char* const sepBracketStart(std::strstr(paramName, useBracket ? " [" : " ("));


@@ -1806,7 +1805,7 @@ private:
const std::size_t sepIndex(std::strlen(paramName)-unitSize-3); const std::size_t sepIndex(std::strlen(paramName)-unitSize-3);


// just in case // just in case
if (sepIndex >= STR_MAX)
if (sepIndex+2 >= STR_MAX)
return false; return false;


if (wantName) if (wantName)
@@ -1832,7 +1831,8 @@ private:


CarlaPlugin* CarlaPlugin::newLADSPA(const Initializer& init, const LADSPA_RDF_Descriptor* const rdfDescriptor) CarlaPlugin* CarlaPlugin::newLADSPA(const Initializer& init, const LADSPA_RDF_Descriptor* const rdfDescriptor)
{ {
carla_debug("CarlaPlugin::newLADSPA({%p, \"%s\", \"%s\", \"%s\", " P_INT64 ", %x}, %p)", init.engine, init.filename, init.name, init.label, init.uniqueId, init.options, rdfDescriptor);
carla_debug("CarlaPlugin::newLADSPA({%p, \"%s\", \"%s\", \"%s\", " P_INT64 ", %x}, %p)",
init.engine, init.filename, init.name, init.label, init.uniqueId, init.options, rdfDescriptor);


CarlaPluginLADSPA* const plugin(new CarlaPluginLADSPA(init.engine, init.id)); CarlaPluginLADSPA* const plugin(new CarlaPluginLADSPA(init.engine, init.id));




+ 26
- 26
source/tests/RtLinkedList.cpp View File

@@ -24,15 +24,8 @@ const unsigned short MIN_RT_EVENTS = 5;
const unsigned short MAX_RT_EVENTS = 10; const unsigned short MAX_RT_EVENTS = 10;


struct MyData { struct MyData {
CarlaString str;
char str[234];
int id; int id;

MyData() noexcept
: id(-1) {}

MyData(int i) noexcept
: str(i),
id(i) {}
}; };


struct PostRtEvents { struct PostRtEvents {
@@ -43,8 +36,8 @@ struct PostRtEvents {


PostRtEvents() noexcept PostRtEvents() noexcept
: dataPool(MIN_RT_EVENTS, MAX_RT_EVENTS), : dataPool(MIN_RT_EVENTS, MAX_RT_EVENTS),
data(dataPool, true),
dataPendingRT(dataPool, true) {}
data(dataPool),
dataPendingRT(dataPool) {}


~PostRtEvents() noexcept ~PostRtEvents() noexcept
{ {
@@ -68,16 +61,17 @@ struct PostRtEvents {
{ {
if (mutex.tryLock()) if (mutex.tryLock())
{ {
dataPendingRT.spliceAppendTo(data);
dataPendingRT.moveTo(data, true);
mutex.unlock(); mutex.unlock();
} }
} }


} postRtEvents; } postRtEvents;


void run5Tests();
void run5Tests() void run5Tests()
{ {
unsigned short k = 0;
ushort k = 0;
MyData allMyData[MAX_RT_EVENTS]; MyData allMyData[MAX_RT_EVENTS];


// Make a safe copy of events while clearing them // Make a safe copy of events while clearing them
@@ -85,7 +79,8 @@ void run5Tests()


while (! postRtEvents.data.isEmpty()) while (! postRtEvents.data.isEmpty())
{ {
MyData& my(postRtEvents.data.getFirst(true));
static MyData fallback = { { '\0' }, 0 };
const MyData& my(postRtEvents.data.getFirst(fallback, true));
allMyData[k++] = my; allMyData[k++] = my;
} }


@@ -101,21 +96,21 @@ void run5Tests()
assert(postRtEvents.dataPendingRT.isEmpty()); assert(postRtEvents.dataPendingRT.isEmpty());


// Handle events now // Handle events now
for (unsigned short i=0; i < k; ++i)
for (ushort i=0; i < k; ++i)
{ {
const MyData& my(allMyData[i]); const MyData& my(allMyData[i]);


carla_stdout("Got data: %i %s", my.id, my.str.buffer());
carla_stdout("Got data: %i %s", my.id, my.str);
} }
} }


int main() int main()
{ {
MyData m1(1);
MyData m2(2);
MyData m3(3);
MyData m4(4);
MyData m5(5);
MyData m1; m1.id = 1; std::strcpy(m1.str, "1");
MyData m2; m2.id = 2; std::strcpy(m2.str, "2");
MyData m3; m3.id = 3; std::strcpy(m3.str, "3");
MyData m4; m4.id = 4; std::strcpy(m4.str, "4");
MyData m5; m5.id = 5; std::strcpy(m5.str, "5");


// start // start
assert(postRtEvents.data.count() == 0); assert(postRtEvents.data.count() == 0);
@@ -125,6 +120,8 @@ int main()


// single append // single append
postRtEvents.appendRT(m1); postRtEvents.appendRT(m1);
assert(postRtEvents.data.count() == 0);
assert(postRtEvents.dataPendingRT.count() == 1);
postRtEvents.trySplice(); postRtEvents.trySplice();
assert(postRtEvents.data.count() == 1); assert(postRtEvents.data.count() == 1);
assert(postRtEvents.dataPendingRT.count() == 0); assert(postRtEvents.dataPendingRT.count() == 0);
@@ -138,12 +135,14 @@ int main()
postRtEvents.trySplice(); postRtEvents.trySplice();
assert(postRtEvents.data.count() == 4); assert(postRtEvents.data.count() == 4);
assert(postRtEvents.dataPendingRT.count() == 0); assert(postRtEvents.dataPendingRT.count() == 0);
// return 0;


for (RtLinkedList<MyData>::Itenerator it = postRtEvents.data.begin(); it.valid(); it.next()) for (RtLinkedList<MyData>::Itenerator it = postRtEvents.data.begin(); it.valid(); it.next())
{ {
const MyData& my(it.getValue());
static const MyData fallback = { { '\0' }, 11 };
const MyData& my(it.getValue(fallback));


carla_stdout("FOR DATA!!!: %i %s", my.id, my.str.buffer());
carla_stdout("FOR DATA!!!: %i %s", my.id, my.str);


if (my.id == 1) if (my.id == 1)
{ {
@@ -151,12 +150,13 @@ int main()
postRtEvents.dataPendingRT.insertAt(m5, it); postRtEvents.dataPendingRT.insertAt(m5, it);
assert(postRtEvents.data.count() == 4); assert(postRtEvents.data.count() == 4);
assert(postRtEvents.dataPendingRT.count() == 1); assert(postRtEvents.dataPendingRT.count() == 1);
postRtEvents.trySplice();
assert(postRtEvents.data.count() == 5);
assert(postRtEvents.dataPendingRT.count() == 0);
} }
} }


postRtEvents.trySplice();
assert(postRtEvents.data.count() == 5);
assert(postRtEvents.dataPendingRT.count() == 0);

run5Tests(); run5Tests();


// reset // reset
@@ -179,7 +179,7 @@ int main()
{ {
for (size_t j=0, count=evIns.count(); j < count; ++j) for (size_t j=0, count=evIns.count(); j < count; ++j)
{ {
const uint32_t& type(evIns.getAt(j));
const uint32_t& type(evIns.getAt(j, 0));


if (type == CARLA_EVENT_DATA_ATOM) if (type == CARLA_EVENT_DATA_ATOM)
pass(); pass();


+ 7
- 7
source/tests/ansi-pedantic-test.c View File

@@ -47,22 +47,22 @@ int main(int argc, char* argv[])
EngineDriverDeviceInfo e; EngineDriverDeviceInfo e;


CarlaPluginInfo f; CarlaPluginInfo f;
CarlaCachedPluginInfo g;
/*CarlaCachedPluginInfo g;*/
CarlaPortCountInfo h; CarlaPortCountInfo h;
CarlaParameterInfo i; CarlaParameterInfo i;
CarlaScalePointInfo j; CarlaScalePointInfo j;
CarlaTransportInfo k; CarlaTransportInfo k;


const char* licenseText;
const char* fileExtensions;
/*const char* licenseText;
const char* fileExtensions;*/


uint l, count; uint l, count;


licenseText = carla_get_complete_license_text();
/*licenseText = carla_get_complete_license_text();
printf("LICENSE:\n%s\n", licenseText); printf("LICENSE:\n%s\n", licenseText);


fileExtensions = carla_get_supported_file_extensions(); fileExtensions = carla_get_supported_file_extensions();
printf("FILE EXTENSIONS:\n%s\n", fileExtensions);
printf("FILE EXTENSIONS:\n%s\n", fileExtensions);*/


count = carla_get_engine_driver_count(); count = carla_get_engine_driver_count();
printf("DRIVER COUNT: %i\n", count); printf("DRIVER COUNT: %i\n", count);
@@ -94,7 +94,7 @@ int main(int argc, char* argv[])
assert(engine != nullptr); assert(engine != nullptr);
engine->getLastError(); engine->getLastError();
#endif #endif
if (carla_add_plugin(BINARY_NATIVE, PLUGIN_INTERNAL, NULL, NULL, "audiofile", 0, NULL))
if (carla_add_plugin(BINARY_NATIVE, PLUGIN_INTERNAL, NULL, NULL, "audiofile", 0, NULL, 0x0))
{ {
#ifdef __cplusplus #ifdef __cplusplus
CarlaPlugin* const plugin(engine->getPlugin(0)); CarlaPlugin* const plugin(engine->getPlugin(0));
@@ -128,7 +128,7 @@ int main(int argc, char* argv[])
(void)argc; (void)argc;
(void)argv; (void)argv;
(void)a; (void)b; (void)c; (void)d; (void)e; (void)a; (void)b; (void)c; (void)d; (void)e;
(void)f; (void)g; (void)h; (void)i; (void)j; (void)k;
(void)f; /*(void)g;*/ (void)h; (void)i; (void)j; (void)k;
#ifdef __cplusplus #ifdef __cplusplus
(void)e1; (void)e2; (void)e4; (void)e5; (void)e6; (void)e1; (void)e2; (void)e4; (void)e5; (void)e6;
#endif #endif


+ 29
- 9
source/utils/LinkedList.hpp View File

@@ -67,15 +67,17 @@ protected:


AbstractLinkedList() noexcept AbstractLinkedList() noexcept
: kDataSize(sizeof(Data)), : kDataSize(sizeof(Data)),
fCount(0)
fCount(0),
#ifdef CARLA_PROPER_CPP11_SUPPORT #ifdef CARLA_PROPER_CPP11_SUPPORT
, fQueue({&fQueue, &fQueue}) {}
#else
fQueue({&fQueue, &fQueue}),
#endif
fUsingItenerator(false)
{ {
#ifndef CARLA_PROPER_CPP11_SUPPORT
fQueue.next = &fQueue; fQueue.next = &fQueue;
fQueue.prev = &fQueue; fQueue.prev = &fQueue;
}
#endif #endif
}


public: public:
virtual ~AbstractLinkedList() noexcept virtual ~AbstractLinkedList() noexcept
@@ -85,15 +87,22 @@ public:


class Itenerator { class Itenerator {
public: public:
Itenerator(const ListHead& queue) noexcept
Itenerator(const ListHead& queue, bool* usingItenerator) noexcept
: fEntry(queue.next), : fEntry(queue.next),
fEntry2(fEntry->next), fEntry2(fEntry->next),
kQueue(queue)
kQueue(queue),
fUsingItenerator(usingItenerator)
{ {
CARLA_SAFE_ASSERT(fEntry != nullptr); CARLA_SAFE_ASSERT(fEntry != nullptr);
CARLA_SAFE_ASSERT(fEntry2 != nullptr); CARLA_SAFE_ASSERT(fEntry2 != nullptr);
} }


~Itenerator()
{
if (fUsingItenerator != nullptr)
*fUsingItenerator = false;
}

bool valid() const noexcept bool valid() const noexcept
{ {
return (fEntry != nullptr && fEntry != &kQueue); return (fEntry != nullptr && fEntry != &kQueue);
@@ -140,13 +149,18 @@ public:
ListHead* fEntry; ListHead* fEntry;
ListHead* fEntry2; ListHead* fEntry2;
const ListHead& kQueue; const ListHead& kQueue;
bool* const fUsingItenerator;


friend class AbstractLinkedList; friend class AbstractLinkedList;
}; };


Itenerator begin() const noexcept Itenerator begin() const noexcept
{ {
return Itenerator(fQueue);
static const ListHead fallback = { nullptr, nullptr };
CARLA_SAFE_ASSERT_RETURN(! fUsingItenerator, Itenerator(fallback, nullptr));

fUsingItenerator = true;
return Itenerator(fQueue, &fUsingItenerator);
} }


void clear() noexcept void clear() noexcept
@@ -331,9 +345,11 @@ public:
} }


// move data to a new list, and clear ourselves // move data to a new list, and clear ourselves
void moveTo(AbstractLinkedList<T>& list, const bool inTail = true) noexcept
bool moveTo(AbstractLinkedList<T>& list, const bool inTail = true) noexcept
{ {
CARLA_SAFE_ASSERT_RETURN(fCount > 0,);
CARLA_SAFE_ASSERT_RETURN(fCount > 0, false);
CARLA_SAFE_ASSERT_RETURN(! fUsingItenerator, false);
CARLA_SAFE_ASSERT_RETURN(! list.fUsingItenerator, false);


if (inTail) if (inTail)
__list_splice_tail(&fQueue, &list.fQueue); __list_splice_tail(&fQueue, &list.fQueue);
@@ -345,6 +361,8 @@ public:


//! and we get nothing //! and we get nothing
_init(); _init();

return true;
} }


protected: protected:
@@ -353,6 +371,8 @@ protected:
std::size_t fCount; std::size_t fCount;
ListHead fQueue; ListHead fQueue;


mutable bool fUsingItenerator;

virtual Data* _allocate() noexcept = 0; virtual Data* _allocate() noexcept = 0;
virtual void _deallocate(Data* const dataPtr) noexcept = 0; virtual void _deallocate(Data* const dataPtr) noexcept = 0;




+ 2
- 2
source/utils/RtLinkedList.hpp View File

@@ -125,11 +125,11 @@ public:
fMemPool.resize(minPreallocated, maxPreallocated); fMemPool.resize(minPreallocated, maxPreallocated);
} }


void moveTo(RtLinkedList<T>& list, const bool inTail) noexcept
bool moveTo(RtLinkedList<T>& list, const bool inTail) noexcept
{ {
CARLA_SAFE_ASSERT_RETURN(fMemPool == list.fMemPool,); CARLA_SAFE_ASSERT_RETURN(fMemPool == list.fMemPool,);


AbstractLinkedList<T>::moveTo(list, inTail);
return AbstractLinkedList<T>::moveTo(list, inTail);
} }


protected: protected:


Loading…
Cancel
Save