@@ -565,7 +565,7 @@ bool CarlaEngine::init(const char* const clientName) | |||
#endif | |||
pData->nextAction.ready(); | |||
pData->thread.startNow(); | |||
pData->thread.startThread(); | |||
return true; | |||
} | |||
@@ -578,7 +578,7 @@ bool CarlaEngine::close() | |||
CARLA_ASSERT(pData->nextPluginId == pData->maxPluginNumber); | |||
carla_debug("CarlaEngine::close()"); | |||
pData->thread.stopNow(); | |||
pData->thread.stopThread(500); | |||
pData->nextAction.ready(); | |||
#ifndef BUILD_BRIDGE | |||
@@ -800,7 +800,7 @@ bool CarlaEngine::removePlugin(const unsigned int id) | |||
CARLA_ASSERT(plugin->getId() == id); | |||
pData->thread.stopNow(); | |||
pData->thread.stopThread(500); | |||
const bool lockWait(isRunning() && fOptions.processMode != PROCESS_MODE_MULTIPLE_CLIENTS); | |||
const CarlaEngineProtectedData::ScopedActionLock sal(pData, kEnginePostActionRemovePlugin, id, 0, lockWait); | |||
@@ -813,7 +813,7 @@ bool CarlaEngine::removePlugin(const unsigned int id) | |||
delete plugin; | |||
if (isRunning() && ! pData->aboutToClose) | |||
pData->thread.startNow(); | |||
pData->thread.startThread(); | |||
callback(CALLBACK_PLUGIN_REMOVED, id, 0, 0, 0.0f, nullptr); | |||
return true; | |||
@@ -828,7 +828,7 @@ void CarlaEngine::removeAllPlugins() | |||
if (pData->plugins == nullptr || pData->curPluginCount == 0) | |||
return; | |||
pData->thread.stopNow(); | |||
pData->thread.stopThread(500); | |||
const bool lockWait(isRunning()); | |||
const CarlaEngineProtectedData::ScopedActionLock sal(pData, kEnginePostActionZeroCount, 0, 0, lockWait); | |||
@@ -850,7 +850,7 @@ void CarlaEngine::removeAllPlugins() | |||
} | |||
if (isRunning() && ! pData->aboutToClose) | |||
pData->thread.startNow(); | |||
pData->thread.startThread(); | |||
carla_debug("CarlaEngine::removeAllPlugins() - END"); | |||
} | |||
@@ -959,7 +959,7 @@ bool CarlaEngine::switchPlugins(const unsigned int idA, const unsigned int idB) | |||
return false; | |||
} | |||
pData->thread.stopNow(); | |||
pData->thread.stopThread(500); | |||
const bool lockWait(isRunning() && fOptions.processMode != PROCESS_MODE_MULTIPLE_CLIENTS); | |||
const CarlaEngineProtectedData::ScopedActionLock sal(pData, kEnginePostActionSwitchPlugins, idA, idB, lockWait); | |||
@@ -970,7 +970,7 @@ bool CarlaEngine::switchPlugins(const unsigned int idA, const unsigned int idB) | |||
#endif | |||
if (isRunning() && ! pData->aboutToClose) | |||
pData->thread.startNow(); | |||
pData->thread.startThread(); | |||
return true; | |||
} | |||
@@ -143,13 +143,13 @@ struct BridgeControl : public RingBufferControl { | |||
// ------------------------------------------------------------------- | |||
class CarlaEngineBridge : public CarlaEngine, | |||
public QThread | |||
public juce::Thread | |||
{ | |||
public: | |||
CarlaEngineBridge(const char* const audioBaseName, const char* const controlBaseName) | |||
: CarlaEngine(), | |||
fIsRunning(false), | |||
fQuitNow(false) | |||
juce::Thread("CarlaEngineBridge"), | |||
fIsRunning(false) | |||
{ | |||
carla_debug("CarlaEngineBridge::CarlaEngineBridge()"); | |||
@@ -214,10 +214,9 @@ public: | |||
fSampleRate = fShmControl.readFloat(); | |||
carla_stderr("SampleRate: %f", fSampleRate); | |||
fQuitNow = false; | |||
fIsRunning = true; | |||
QThread::start(QThread::TimeCriticalPriority); | |||
startThread(10); | |||
CarlaEngine::init(clientName); | |||
return true; | |||
} | |||
@@ -227,8 +226,7 @@ public: | |||
carla_debug("CarlaEnginePlugin::close()"); | |||
CarlaEngine::close(); | |||
fQuitNow = true; | |||
QThread::wait(); | |||
stopThread(6000); | |||
fShmControl.clear(); | |||
fShmAudioPool.clear(); | |||
@@ -259,14 +257,14 @@ public: | |||
// TODO - set RT permissions | |||
carla_debug("CarlaEngineBridge::run()"); | |||
while (! fQuitNow) | |||
while (! threadShouldExit()) | |||
{ | |||
if (! jackbridge_sem_timedwait(&fShmControl.data->runServer, 5)) | |||
{ | |||
if (errno == ETIMEDOUT) | |||
{ | |||
fIsRunning = false; | |||
fQuitNow = true; | |||
signalThreadShouldExit(); | |||
return; | |||
} | |||
} | |||
@@ -397,7 +395,7 @@ public: | |||
} | |||
case kPluginBridgeOpcodeQuit: | |||
fQuitNow = true; | |||
signalThreadShouldExit(); | |||
break; | |||
} | |||
} | |||
@@ -413,8 +411,7 @@ private: | |||
BridgeAudioPool fShmAudioPool; | |||
BridgeControl fShmControl; | |||
bool fIsRunning; | |||
bool fQuitNow; | |||
volatile bool fIsRunning; | |||
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineBridge) | |||
}; | |||
@@ -23,6 +23,7 @@ | |||
#include "CarlaEngineThread.hpp" | |||
#include "CarlaPlugin.hpp" | |||
#include "CarlaMutex.hpp" | |||
#include "RtList.hpp" | |||
CARLA_BACKEND_START_NAMESPACE | |||
@@ -24,6 +24,7 @@ | |||
#include <QtCore/QProcess> | |||
#include <QtCore/QTextStream> | |||
#include <QtCore/QThread> | |||
CARLA_BACKEND_START_NAMESPACE | |||
@@ -25,60 +25,33 @@ CARLA_BACKEND_START_NAMESPACE | |||
// ----------------------------------------------------------------------- | |||
CarlaEngineThread::CarlaEngineThread(CarlaEngine* const engine) | |||
: fEngine(engine), | |||
fStopNow(true) | |||
: juce::Thread("CarlaEngineThread"), | |||
fEngine(engine) | |||
{ | |||
carla_debug("CarlaEngineThread::CarlaEngineThread(%p)", engine); | |||
CARLA_ASSERT(engine != nullptr); | |||
carla_debug("CarlaEngineThread::CarlaEngineThread(%p)", engine); | |||
setPriority(5); | |||
} | |||
CarlaEngineThread::~CarlaEngineThread() | |||
{ | |||
carla_debug("CarlaEngineThread::~CarlaEngineThread()"); | |||
CARLA_ASSERT(fStopNow); | |||
} | |||
// ----------------------------------------------------------------------- | |||
void CarlaEngineThread::startNow() | |||
{ | |||
carla_debug("CarlaEngineThread::startNow()"); | |||
CARLA_ASSERT(fStopNow); | |||
fStopNow = false; | |||
start(); | |||
} | |||
void CarlaEngineThread::stopNow() | |||
{ | |||
carla_debug("CarlaEngineThread::stopNow()"); | |||
if (fStopNow) | |||
return; | |||
fStopNow = true; | |||
const CarlaMutex::ScopedLocker sl(fMutex); | |||
if (isRunning() && ! wait(500)) | |||
terminate(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
void CarlaEngineThread::run() | |||
{ | |||
carla_debug("CarlaEngineThread::run()"); | |||
CARLA_ASSERT(fEngine->isRunning()); | |||
carla_debug("CarlaEngineThread::run()"); | |||
bool oscRegisted, usesSingleThread; | |||
unsigned int i, count; | |||
float value; | |||
while (fEngine->isRunning() && ! fStopNow) | |||
while (fEngine->isRunning() && ! threadShouldExit()) | |||
{ | |||
const CarlaMutex::ScopedLocker sl(fMutex); | |||
#ifdef BUILD_BRIDGE | |||
oscRegisted = fEngine->isOscBridgeRegistered(); | |||
#else | |||
@@ -96,7 +69,7 @@ void CarlaEngineThread::run() | |||
usesSingleThread = (plugin->getHints() & PLUGIN_HAS_SINGLE_THREAD); | |||
// ------------------------------------------------------- | |||
// ----------------------------------------------------------- | |||
// Process postponed events | |||
if (oscRegisted || ! usesSingleThread) | |||
@@ -104,7 +77,7 @@ void CarlaEngineThread::run() | |||
if (! usesSingleThread) | |||
plugin->postRtEventsRun(); | |||
// --------------------------------------------------- | |||
// ------------------------------------------------------- | |||
// Update parameter outputs | |||
for (uint32_t j=0; j < plugin->getParameterCount(); ++j) | |||
@@ -140,8 +113,10 @@ void CarlaEngineThread::run() | |||
} | |||
fEngine->idleOsc(); | |||
carla_msleep(oscRegisted ? 30 : 50); | |||
sleep(oscRegisted ? 30 : 50); | |||
} | |||
} | |||
// ----------------------------------------------------------------------- | |||
CARLA_BACKEND_END_NAMESPACE |
@@ -19,9 +19,7 @@ | |||
#define CARLA_ENGINE_THREAD_HPP_INCLUDED | |||
#include "CarlaBackend.hpp" | |||
#include "CarlaMutex.hpp" | |||
#include <QtCore/QThread> | |||
#include "CarlaJuceUtils.hpp" | |||
CARLA_BACKEND_START_NAMESPACE | |||
@@ -29,24 +27,18 @@ CARLA_BACKEND_START_NAMESPACE | |||
} // Fix editor indentation | |||
#endif | |||
class CarlaEngineThread : public QThread | |||
class CarlaEngineThread : public juce::Thread | |||
{ | |||
public: | |||
CarlaEngineThread(CarlaEngine* const engine); | |||
~CarlaEngineThread(); | |||
void startNow(); | |||
void stopNow(); | |||
~CarlaEngineThread() override; | |||
protected: | |||
void run(); | |||
void run() override; | |||
private: | |||
CarlaEngine* const fEngine; | |||
CarlaMutex fMutex; | |||
bool fStopNow; | |||
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineThread) | |||
}; | |||
@@ -282,7 +282,7 @@ public: | |||
pData->active = false; | |||
} | |||
if (pData->osc.thread.isRunning()) | |||
if (pData->osc.thread.isThreadRunning()) | |||
{ | |||
fShmControl.writeOpcode(kPluginBridgeOpcodeQuit); | |||
fShmControl.commitWrite(); | |||
@@ -296,13 +296,7 @@ public: | |||
} | |||
pData->osc.data.free(); | |||
// Wait a bit first, then force kill | |||
if (pData->osc.thread.isRunning() && ! pData->osc.thread.wait(pData->engine->getOptions().uiBridgesTimeout)) | |||
{ | |||
carla_stderr("Failed to properly stop Plugin Bridge thread"); | |||
pData->osc.thread.terminate(); | |||
} | |||
pData->osc.thread.stopThread(6000); | |||
if (fNeedsSemDestroy) | |||
{ | |||
@@ -599,7 +593,7 @@ public: | |||
void idleGui() override | |||
{ | |||
if (! pData->osc.thread.isRunning()) | |||
if (! pData->osc.thread.isThreadRunning()) | |||
carla_stderr2("TESTING: Bridge has closed!"); | |||
CarlaPlugin::idleGui(); | |||
@@ -1789,12 +1783,12 @@ public: | |||
std::strncat(shmIdStr, &fShmControl.filename[fShmControl.filename.length()-6], 6); | |||
pData->osc.thread.setOscData(bridgeBinary, label, getPluginTypeAsString(fPluginType), shmIdStr); | |||
pData->osc.thread.start(); | |||
pData->osc.thread.startThread(7); | |||
} | |||
for (int i=0; i < 200; ++i) | |||
{ | |||
if (fInitiated || ! pData->osc.thread.isRunning()) | |||
if (fInitiated || ! pData->osc.thread.isThreadRunning()) | |||
break; | |||
carla_msleep(50); | |||
} | |||
@@ -1804,10 +1798,7 @@ public: | |||
// unregister so it gets handled properly | |||
pData->engine->registerEnginePlugin(fId, nullptr); | |||
pData->osc.thread.quit(); | |||
if (pData->osc.thread.isRunning()) | |||
pData->osc.thread.terminate(); | |||
pData->osc.thread.stopThread(6000); | |||
if (! fInitError) | |||
pData->engine->setLastError("Timeout while waiting for a response from plugin-bridge\n(or the plugin crashed on initialization?)"); | |||
@@ -26,9 +26,10 @@ | |||
#include "CarlaOscUtils.hpp" | |||
#include "CarlaMutex.hpp" | |||
#include "CarlaMIDI.h" | |||
#include "RtList.hpp" | |||
#include <QtCore/QByteArray> | |||
#define CARLA_PROCESS_CONTINUE_CHECK if (! fEnabled) { pData->engine->callback(CALLBACK_DEBUG, fId, 0, 0, 0.0f, "Processing while plugin is disabled!!"); return; } | |||
CARLA_BACKEND_START_NAMESPACE | |||
@@ -20,7 +20,9 @@ | |||
#include "CarlaPlugin.hpp" | |||
#include "CarlaEngine.hpp" | |||
#include <QtCore/QProcess> | |||
using juce::ChildProcess; | |||
using juce::String; | |||
using juce::StringArray; | |||
CARLA_BACKEND_START_NAMESPACE | |||
@@ -45,32 +47,29 @@ const char* PluginThreadMode2str(const CarlaPluginThread::Mode mode) | |||
} | |||
CarlaPluginThread::CarlaPluginThread(CarlaBackend::CarlaEngine* const engine, CarlaBackend::CarlaPlugin* const plugin, const Mode mode) | |||
: fEngine(engine), | |||
: juce::Thread("CarlaPluginThread"), | |||
fEngine(engine), | |||
fPlugin(plugin), | |||
fMode(mode), | |||
fProcess(nullptr) | |||
fMode(mode) | |||
{ | |||
carla_debug("CarlaPluginThread::CarlaPluginThread(plugin:\"%s\", engine:\"%s\", %s)", plugin->getName(), engine->getName(), PluginThreadMode2str(mode)); | |||
} | |||
CarlaPluginThread::~CarlaPluginThread() | |||
{ | |||
carla_debug("CarlaPluginThread::~CarlaPluginThread()"); | |||
if (fProcess != nullptr) | |||
{ | |||
delete fProcess; | |||
fProcess = nullptr; | |||
} | |||
setPriority(5); | |||
} | |||
void CarlaPluginThread::setMode(const CarlaPluginThread::Mode mode) noexcept | |||
void CarlaPluginThread::setMode(const CarlaPluginThread::Mode mode) | |||
{ | |||
CARLA_ASSERT(! isThreadRunning()); | |||
carla_debug("CarlaPluginThread::setMode(%s)", PluginThreadMode2str(mode)); | |||
fMode = mode; | |||
} | |||
void CarlaPluginThread::setOscData(const char* const binary, const char* const label, const char* const extra1, const char* const extra2) | |||
{ | |||
CARLA_ASSERT(! isThreadRunning()); | |||
carla_debug("CarlaPluginThread::setOscData(\"%s\", \"%s\", \"%s\", \"%s\")", binary, label, extra1, extra2); | |||
fBinary = binary; | |||
fLabel = label; | |||
fExtra1 = extra1; | |||
@@ -81,35 +80,12 @@ void CarlaPluginThread::run() | |||
{ | |||
carla_debug("CarlaPluginThread::run()"); | |||
if (fProcess == nullptr) | |||
{ | |||
fProcess = new QProcess(nullptr); | |||
fProcess->setProcessChannelMode(QProcess::ForwardedChannels); | |||
} | |||
else if (fProcess->state() == QProcess::Running) | |||
{ | |||
carla_stderr("CarlaPluginThread::run() - already running, giving up..."); | |||
ChildProcess process; | |||
switch (fMode) | |||
{ | |||
case PLUGIN_THREAD_NULL: | |||
break; | |||
case PLUGIN_THREAD_DSSI_GUI: | |||
case PLUGIN_THREAD_LV2_GUI: | |||
case PLUGIN_THREAD_VST_GUI: | |||
fProcess->terminate(); | |||
fEngine->callback(CarlaBackend::CALLBACK_SHOW_GUI, fPlugin->getId(), -1, 0, 0.0f, nullptr); | |||
return; | |||
case PLUGIN_THREAD_BRIDGE: | |||
break; | |||
} | |||
} | |||
QString name(fPlugin->getName()); | |||
QStringList arguments; | |||
StringArray arguments; | |||
arguments.add((const char*)fBinary); | |||
String name(fPlugin->getName()); | |||
if (name.isEmpty()) | |||
name = "(none)"; | |||
@@ -119,37 +95,37 @@ void CarlaPluginThread::run() | |||
break; | |||
case PLUGIN_THREAD_DSSI_GUI: | |||
/* osc-url */ arguments << QString("%1/%2").arg(fEngine->getOscServerPathUDP()).arg(fPlugin->getId()); | |||
/* filename */ arguments << fPlugin->getFilename(); | |||
/* label */ arguments << (const char*)fLabel; | |||
/* ui-title */ arguments << QString("%1 (GUI)").arg(fPlugin->getName()); | |||
/* osc-url */ arguments.add(String(fEngine->getOscServerPathUDP()) + "/" + String(fPlugin->getId())); | |||
/* filename */ arguments.add(fPlugin->getFilename()); | |||
/* label */ arguments.add((const char*)fLabel); | |||
/* ui-title */ arguments.add(name + " (GUI)"); | |||
break; | |||
case PLUGIN_THREAD_LV2_GUI: | |||
/* osc-url */ arguments << QString("%1/%2").arg(fEngine->getOscServerPathTCP()).arg(fPlugin->getId()); | |||
/* URI */ arguments << (const char*)fLabel; | |||
/* ui-URI */ arguments << (const char*)fExtra1; | |||
/* ui-title */ arguments << QString("%1 (GUI)").arg(fPlugin->getName()); | |||
/* osc-url */ arguments.add(String(fEngine->getOscServerPathTCP()) + "/" + String(fPlugin->getId())); | |||
/* URI */ arguments.add((const char*)fLabel); | |||
/* ui-URI */ arguments.add((const char*)fExtra1); | |||
/* ui-title */ arguments.add(name + " (GUI)"); | |||
break; | |||
case PLUGIN_THREAD_VST_GUI: | |||
/* osc-url */ arguments << QString("%1/%2").arg(fEngine->getOscServerPathTCP()).arg(fPlugin->getId()); | |||
/* filename */ arguments << fPlugin->getFilename(); | |||
/* ui-title */ arguments << QString("%1 (GUI)").arg(fPlugin->getName()); | |||
/* osc-url */ arguments.add(String(fEngine->getOscServerPathTCP()) + "/" + String(fPlugin->getId())); | |||
/* filename */ arguments.add(fPlugin->getFilename()); | |||
/* ui-title */ arguments.add(name + " (GUI)"); | |||
break; | |||
case PLUGIN_THREAD_BRIDGE: | |||
/* osc-url */ arguments << QString("%1/%2").arg(fEngine->getOscServerPathTCP()).arg(fPlugin->getId()); | |||
/* stype */ arguments << (const char*)fExtra1; | |||
/* filename */ arguments << fPlugin->getFilename(); | |||
/* name */ arguments << name; | |||
/* label */ arguments << (const char*)fLabel; | |||
/* SHM ids */ arguments << (const char*)fExtra2; | |||
/* osc-url */ arguments.add(String(fEngine->getOscServerPathTCP()) + "/" + String(fPlugin->getId())); | |||
/* stype */ arguments.add((const char*)fExtra1); | |||
/* filename */ arguments.add(fPlugin->getFilename()); | |||
/* name */ arguments.add(name); | |||
/* label */ arguments.add((const char*)fLabel); | |||
/* SHM ids */ arguments.add((const char*)fExtra2); | |||
break; | |||
} | |||
fProcess->start((const char*)fBinary, arguments); | |||
fProcess->waitForStarted(); | |||
if (! process.start(arguments)) | |||
return; | |||
switch (fMode) | |||
{ | |||
@@ -161,50 +137,46 @@ void CarlaPluginThread::run() | |||
case PLUGIN_THREAD_VST_GUI: | |||
if (fPlugin->waitForOscGuiShow()) | |||
{ | |||
fProcess->waitForFinished(-1); | |||
while (process.isRunning() && ! threadShouldExit()) | |||
sleep(1000); | |||
if (fProcess->exitCode() == 0) | |||
// we only get here is UI was closed or thread asked to exit | |||
if (threadShouldExit()) | |||
{ | |||
// Hide | |||
fEngine->callback(CarlaBackend::CALLBACK_SHOW_GUI, fPlugin->getId(), 0, 0, 0.0f, nullptr); | |||
carla_stdout("CarlaPluginThread::run() - GUI closed"); | |||
if (process.isRunning()) | |||
process.kill(); | |||
} | |||
else | |||
{ | |||
// Kill | |||
fEngine->callback(CarlaBackend::CALLBACK_SHOW_GUI, fPlugin->getId(), -1, 0, 0.0f, nullptr); | |||
carla_stderr("CarlaPluginThread::run() - GUI crashed while running"); | |||
fEngine->callback(CarlaBackend::CALLBACK_SHOW_GUI, fPlugin->getId(), 0, 0, 0.0f, nullptr); | |||
} | |||
} | |||
else | |||
{ | |||
fProcess->close(); | |||
CARLA_ASSERT(fProcess->state() == QProcess::NotRunning); | |||
if (fProcess->exitCode() != 0 || fProcess->exitStatus() == QProcess::CrashExit) | |||
if (process.isRunning() && ! process.waitForProcessToFinish(500)) | |||
{ | |||
process.kill(); | |||
fEngine->callback(CarlaBackend::CALLBACK_SHOW_GUI, fPlugin->getId(), -1, 0, 0.0f, nullptr); | |||
carla_stderr("CarlaPluginThread::run() - GUI crashed while opening"); | |||
} | |||
else | |||
{ | |||
fEngine->callback(CarlaBackend::CALLBACK_SHOW_GUI, fPlugin->getId(), 0, 0, 0.0f, nullptr); | |||
carla_debug("CarlaPluginThread::run() - GUI timeout"); | |||
carla_stderr("CarlaPluginThread::run() - GUI timeout"); | |||
} | |||
} | |||
break; | |||
case PLUGIN_THREAD_BRIDGE: | |||
fProcess->waitForFinished(-1); | |||
while (process.isRunning() && ! threadShouldExit()) | |||
sleep(1000); | |||
if (fProcess->exitCode() != 0 || fProcess->exitStatus() == QProcess::CrashExit) | |||
if (threadShouldExit()) | |||
{ | |||
carla_stderr("CarlaPluginThread::run() - bridge crashed"); | |||
CarlaString errorString("Plugin '" + CarlaString(fPlugin->getName()) + "' has crashed!\n" | |||
"Saving now will lose its current settings.\n" | |||
"Please remove this plugin, and not rely on it from this point."); | |||
fEngine->callback(CarlaBackend::CALLBACK_ERROR, fPlugin->getId(), 0, 0, 0.0f, (const char*)errorString); | |||
if (process.isRunning()) | |||
process.kill(); | |||
} | |||
break; | |||
} | |||
@@ -21,13 +21,9 @@ | |||
#include "CarlaBackend.hpp" | |||
#include "CarlaString.hpp" | |||
#include <QtCore/QThread> | |||
class QProcess; | |||
CARLA_BACKEND_START_NAMESPACE | |||
class CarlaPluginThread : public QThread | |||
class CarlaPluginThread : public juce::Thread | |||
{ | |||
public: | |||
enum Mode { | |||
@@ -39,13 +35,12 @@ public: | |||
}; | |||
CarlaPluginThread(CarlaEngine* const engine, CarlaPlugin* const plugin, const Mode mode = PLUGIN_THREAD_NULL); | |||
~CarlaPluginThread(); | |||
void setMode(const CarlaPluginThread::Mode mode) noexcept; | |||
void setMode(const CarlaPluginThread::Mode mode); | |||
void setOscData(const char* const binary, const char* const label, const char* const extra1="", const char* const extra2=""); | |||
protected: | |||
void run(); | |||
void run() override; | |||
private: | |||
CarlaEngine* const fEngine; | |||
@@ -56,7 +51,6 @@ private: | |||
CarlaString fLabel; | |||
CarlaString fExtra1; | |||
CarlaString fExtra2; | |||
QProcess* fProcess; | |||
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginThread) | |||
}; | |||
@@ -57,12 +57,7 @@ public: | |||
{ | |||
showGui(false); | |||
// Wait a bit first, then force kill | |||
if (pData->osc.thread.isRunning() && ! pData->osc.thread.wait(pData->engine->getOptions().uiBridgesTimeout)) | |||
{ | |||
carla_stderr("DSSI GUI thread still running, forcing termination now"); | |||
pData->osc.thread.terminate(); | |||
} | |||
pData->osc.thread.stopThread(pData->engine->getOptions().uiBridgesTimeout); | |||
} | |||
pData->singleMutex.lock(); | |||
@@ -381,7 +376,7 @@ public: | |||
{ | |||
if (yesNo) | |||
{ | |||
pData->osc.thread.start(); | |||
pData->osc.thread.startThread(); | |||
} | |||
else | |||
{ | |||
@@ -392,8 +387,7 @@ public: | |||
pData->osc.data.free(); | |||
} | |||
if (pData->osc.thread.isRunning() && ! pData->osc.thread.wait(pData->engine->getOptions().uiBridgesTimeout)) | |||
pData->osc.thread.terminate(); | |||
pData->osc.thread.stopThread(pData->engine->getOptions().uiBridgesTimeout); | |||
} | |||
} | |||
@@ -408,12 +408,7 @@ public: | |||
if (fUi.type == PLUGIN_UI_OSC) | |||
{ | |||
// Wait a bit first, then force kill | |||
if (pData->osc.thread.isRunning() && ! pData->osc.thread.wait(pData->engine->getOptions().uiBridgesTimeout)) | |||
{ | |||
carla_stderr("LV2 OSC-GUI thread still running, forcing termination now"); | |||
pData->osc.thread.terminate(); | |||
} | |||
pData->osc.thread.stopThread(pData->engine->getOptions().uiBridgesTimeout); | |||
} | |||
else | |||
{ | |||
@@ -1085,7 +1080,7 @@ public: | |||
{ | |||
if (yesNo) | |||
{ | |||
pData->osc.thread.start(); | |||
pData->osc.thread.startThread(); | |||
} | |||
else | |||
{ | |||
@@ -1096,8 +1091,7 @@ public: | |||
pData->osc.data.free(); | |||
} | |||
if (pData->osc.thread.isRunning() && ! pData->osc.thread.wait(pData->engine->getOptions().uiBridgesTimeout)) | |||
pData->osc.thread.terminate(); | |||
pData->osc.thread.stopThread(pData->engine->getOptions().uiBridgesTimeout); | |||
} | |||
return; | |||
@@ -82,12 +82,7 @@ public: | |||
if (fGui.isOsc) | |||
{ | |||
// Wait a bit first, then force kill | |||
if (pData->osc.thread.isRunning() && ! pData->osc.thread.wait(pData->engine->getOptions().uiBridgesTimeout)) | |||
{ | |||
carla_stderr("VST OSC-GUI thread still running, forcing termination now"); | |||
pData->osc.thread.terminate(); | |||
} | |||
pData->osc.thread.stopThread(pData->engine->getOptions().uiBridgesTimeout); | |||
} | |||
} | |||
@@ -381,7 +376,7 @@ public: | |||
{ | |||
if (yesNo) | |||
{ | |||
pData->osc.thread.start(); | |||
pData->osc.thread.startThread(); | |||
} | |||
else | |||
{ | |||
@@ -392,8 +387,7 @@ public: | |||
pData->osc.data.free(); | |||
} | |||
if (pData->osc.thread.isRunning() && ! pData->osc.thread.wait(pData->engine->getOptions().uiBridgesTimeout)) | |||
pData->osc.thread.terminate(); | |||
pData->osc.thread.stopThread(pData->engine->getOptions().uiBridgesTimeout); | |||
} | |||
} | |||
else | |||
@@ -33,7 +33,7 @@ CarlaBridgeClient::CarlaBridgeClient(const char* const uiTitle) | |||
: fOsc(this), | |||
fOscData(fOsc.getControlData()) | |||
#ifdef BUILD_BRIDGE_UI | |||
, fUI(CarlaBridgeToolkit::createNew(this, uiTitle)), | |||
, fUI(CarlaBridgeToolkit::createNew(this, uiTitle)), | |||
#endif | |||
{ | |||
#ifdef BUILD_BRIDGE_UI | |||
@@ -75,6 +75,7 @@ void CarlaBridgeClient::uiClose() | |||
void CarlaBridgeClient::toolkitShow() | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fUI.toolkit != nullptr,); | |||
carla_debug("CarlaBridgeClient::toolkitShow()"); | |||
fUI.toolkit->show(); | |||
@@ -82,6 +83,7 @@ void CarlaBridgeClient::toolkitShow() | |||
void CarlaBridgeClient::toolkitHide() | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fUI.toolkit != nullptr,); | |||
carla_debug("CarlaBridgeClient::toolkitHide()"); | |||
fUI.toolkit->hide(); | |||
@@ -89,6 +91,7 @@ void CarlaBridgeClient::toolkitHide() | |||
void CarlaBridgeClient::toolkitResize(const int width, const int height) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fUI.toolkit != nullptr,); | |||
carla_debug("CarlaBridgeClient::toolkitResize(%i, %i)", width, height); | |||
fUI.toolkit->resize(width, height); | |||
@@ -96,6 +99,7 @@ void CarlaBridgeClient::toolkitResize(const int width, const int height) | |||
void CarlaBridgeClient::toolkitExec(const bool showGui) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fUI.toolkit != nullptr,); | |||
carla_debug("CarlaBridgeClient::toolkitExec(%s)", bool2str(showGui)); | |||
fUI.toolkit->exec(showGui); | |||
@@ -153,19 +157,17 @@ void CarlaBridgeClient::sendOscUpdate() | |||
#ifdef BUILD_BRIDGE_PLUGIN | |||
void CarlaBridgeClient::sendOscBridgeUpdate() | |||
{ | |||
CARLA_ASSERT(fOscData.target != nullptr && fOscData.path != nullptr); | |||
carla_debug("CarlaBridgeClient::sendOscBridgeUpdate()"); | |||
if (fOscData.target != nullptr && fOscData.path != nullptr) | |||
if (fOscData.target != nullptr) | |||
osc_send_bridge_update(fOscData, fOscData.path); | |||
} | |||
void CarlaBridgeClient::sendOscBridgeError(const char* const error) | |||
{ | |||
CARLA_ASSERT(error != nullptr); | |||
carla_debug("CarlaBridgeClient::sendOscBridgeError(\"%s\")", error); | |||
if (fOscData.target != nullptr && error != nullptr) | |||
if (fOscData.target != nullptr) | |||
osc_send_bridge_error(fOscData, error); | |||
} | |||
#endif | |||
@@ -261,12 +263,9 @@ bool CarlaBridgeClient::uiLibOpen(const char* const filename) | |||
bool CarlaBridgeClient::uiLibClose() | |||
{ | |||
CARLA_ASSERT(fUI.lib != nullptr); | |||
CARLA_SAFE_ASSERT_RETURN(fUI.lib != nullptr, false); | |||
carla_debug("CarlaBridgeClient::uiLibClose()"); | |||
if (fUI.lib == nullptr) | |||
return false; | |||
const bool closed = lib_close(fUI.lib); | |||
fUI.lib = nullptr; | |||
return closed; | |||
@@ -274,12 +273,9 @@ bool CarlaBridgeClient::uiLibClose() | |||
void* CarlaBridgeClient::uiLibSymbol(const char* const symbol) | |||
{ | |||
CARLA_ASSERT(fUI.lib != nullptr); | |||
CARLA_SAFE_ASSERT_RETURN(fUI.lib != nullptr, nullptr); | |||
carla_debug("CarlaBridgeClient::uiLibSymbol(\"%s\")", symbol); | |||
if (fUI.lib == nullptr) | |||
return nullptr; | |||
return lib_symbol(fUI.lib, symbol); | |||
} | |||
@@ -121,24 +121,12 @@ void CarlaBridgeOsc::close() | |||
int CarlaBridgeOsc::handleMessage(const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg) | |||
{ | |||
CARLA_ASSERT(fName.isNotEmpty()); | |||
CARLA_ASSERT(fServerPath.isNotEmpty()); | |||
CARLA_ASSERT(fServer != nullptr); | |||
CARLA_ASSERT(path != nullptr); | |||
CARLA_SAFE_ASSERT_RETURN(fName.isNotEmpty(), 1); | |||
CARLA_SAFE_ASSERT_RETURN(fServerPath.isNotEmpty(), 1); | |||
CARLA_SAFE_ASSERT_RETURN(fServer != nullptr, 1); | |||
CARLA_SAFE_ASSERT_RETURN(path != nullptr, 1); | |||
carla_debug("CarlaBridgeOsc::handleMessage(\"%s\", %i, %p, \"%s\", %p)", path, argc, argv, types, msg); | |||
if (path == nullptr) | |||
{ | |||
carla_stderr("CarlaBridgeOsc::handleMessage() - got invalid path"); | |||
return 1; | |||
} | |||
if (fName.isEmpty()) | |||
{ | |||
carla_stderr("CarlaBridgeOsc::handleMessage(\"%s\", ...) - received message but client is offline", path); | |||
return 1; | |||
} | |||
const size_t nameSize(fName.length()); | |||
// Check if message is for this client | |||
@@ -194,9 +182,9 @@ int CarlaBridgeOsc::handleMessage(const char* const path, const int argc, const | |||
if (std::strcmp(method, "plugin_save_now") == 0) | |||
return handleMsgPluginSaveNow(); | |||
if (std::strcmp(method, "plugin_set_parameter_midi_channel") == 0) | |||
return handleMsgPluginSetParameterMidiChannel(argc, argv, types); | |||
return handleMsgPluginSetParameterMidiChannel(argc, argv, types); | |||
if (std::strcmp(method, "plugin_set_parameter_midi_cc") == 0) | |||
return handleMsgPluginSetParameterMidiCC(argc, argv, types); | |||
return handleMsgPluginSetParameterMidiCC(argc, argv, types); | |||
if (std::strcmp(method, "plugin_set_chunk") == 0) | |||
return handleMsgPluginSetChunk(argc, argv, types); | |||
if (std::strcmp(method, "plugin_set_custom_data") == 0) | |||
@@ -211,7 +199,7 @@ int CarlaBridgeOsc::handleMessage(const char* const path, const int argc, const | |||
int CarlaBridgeOsc::handleMsgConfigure(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
{ | |||
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ss"); | |||
CARLA_SAFE_ASSERT_RETURN(fClient == nullptr, 1) | |||
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1); | |||
carla_debug("CarlaBridgeOsc::handleMsgConfigure()"); | |||
// nothing here for now | |||
@@ -224,21 +212,15 @@ int CarlaBridgeOsc::handleMsgConfigure(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
int CarlaBridgeOsc::handleMsgControl(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
{ | |||
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "if"); | |||
CARLA_SAFE_ASSERT_RETURN(fClient == nullptr, 1) | |||
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1); | |||
carla_debug("CarlaBridgeOsc::handleMsgControl()"); | |||
if (kClient == nullptr) | |||
return 1; | |||
const int32_t index = argv[0]->i; | |||
const float value = argv[1]->f; | |||
CARLA_SAFE_ASSERT_INT(index != -1, index); | |||
CARLA_SAFE_ASSERT_RETURN(index != -1, 1); | |||
if (index == -1) | |||
return 1; | |||
kClient->setParameter(index, value); | |||
fClient->setParameter(index, value); | |||
return 0; | |||
} | |||
@@ -246,20 +228,14 @@ int CarlaBridgeOsc::handleMsgControl(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
int CarlaBridgeOsc::handleMsgProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
{ | |||
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "i"); | |||
CARLA_SAFE_ASSERT_RETURN(fClient == nullptr, 1) | |||
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1); | |||
carla_debug("CarlaBridgeOsc::handleMsgProgram()"); | |||
if (kClient == nullptr) | |||
return 1; | |||
const int32_t index = argv[0]->i; | |||
CARLA_SAFE_ASSERT_INT(index >= 0, index); | |||
CARLA_SAFE_ASSERT_RETURN(index >= 0, 1); | |||
if (index < 0) | |||
return 1; | |||
kClient->setProgram(static_cast<uint32_t>(index)); | |||
fClient->setProgram(static_cast<uint32_t>(index)); | |||
return 0; | |||
} | |||
@@ -267,24 +243,16 @@ int CarlaBridgeOsc::handleMsgProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
int CarlaBridgeOsc::handleMsgMidiProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
{ | |||
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ii"); | |||
CARLA_SAFE_ASSERT_RETURN(fClient == nullptr, 1) | |||
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1); | |||
carla_debug("CarlaBridgeOsc::handleMsgMidiProgram()"); | |||
if (kClient == nullptr) | |||
return 1; | |||
const int32_t bank = argv[0]->i; | |||
const int32_t program = argv[1]->i; | |||
CARLA_SAFE_ASSERT_INT(bank >= 0, bank); | |||
CARLA_SAFE_ASSERT_INT(program >= 0, program); | |||
CARLA_SAFE_ASSERT_RETURN(bank >= 0, 1); | |||
CARLA_SAFE_ASSERT_RETURN(program >= 0, 1); | |||
if (bank < 0) | |||
return 1; | |||
if (program < 0) | |||
return 1; | |||
kClient->setMidiProgram(static_cast<uint32_t>(bank), static_cast<uint32_t>(program)); | |||
fClient->setMidiProgram(static_cast<uint32_t>(bank), static_cast<uint32_t>(program)); | |||
return 0; | |||
} | |||
@@ -292,12 +260,9 @@ int CarlaBridgeOsc::handleMsgMidiProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
int CarlaBridgeOsc::handleMsgMidi(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
{ | |||
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "m"); | |||
CARLA_SAFE_ASSERT_RETURN(fClient == nullptr, 1) | |||
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1); | |||
carla_debug("CarlaBridgeOsc::handleMsgMidi()"); | |||
if (kClient == nullptr) | |||
return 1; | |||
const uint8_t* const data = argv[0]->m; | |||
uint8_t status = data[1]; | |||
uint8_t channel = status & 0x0F; | |||
@@ -310,27 +275,19 @@ int CarlaBridgeOsc::handleMsgMidi(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
{ | |||
const uint8_t note = data[2]; | |||
CARLA_SAFE_ASSERT_INT(note < MAX_MIDI_NOTE, note); | |||
CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE, 1); | |||
if (note >= MAX_MIDI_NOTE) | |||
return 1; | |||
kClient->noteOff(channel, note); | |||
fClient->noteOff(channel, note); | |||
} | |||
else if (MIDI_IS_STATUS_NOTE_ON(status)) | |||
{ | |||
const uint8_t note = data[2]; | |||
const uint8_t velo = data[3]; | |||
CARLA_SAFE_ASSERT_INT(note < MAX_MIDI_NOTE, note); | |||
CARLA_SAFE_ASSERT_INT(velo < MAX_MIDI_VALUE, velo); | |||
if (note >= MAX_MIDI_NOTE) | |||
return 1; | |||
if (velo >= MAX_MIDI_VALUE) | |||
return 1; | |||
CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE, 1); | |||
CARLA_SAFE_ASSERT_RETURN(velo < MAX_MIDI_VALUE, 1); | |||
kClient->noteOn(channel, note, velo); | |||
fClient->noteOn(channel, note, velo); | |||
} | |||
return 0; | |||
@@ -338,39 +295,30 @@ int CarlaBridgeOsc::handleMsgMidi(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
int CarlaBridgeOsc::handleMsgShow() | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fClient == nullptr, 1) | |||
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1); | |||
carla_debug("CarlaBridgeOsc::handleMsgShow()"); | |||
if (kClient == nullptr) | |||
return 1; | |||
kClient->toolkitShow(); | |||
fClient->toolkitShow(); | |||
return 0; | |||
} | |||
int CarlaBridgeOsc::handleMsgHide() | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fClient == nullptr, 1) | |||
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1); | |||
carla_debug("CarlaBridgeOsc::handleMsgHide()"); | |||
if (kClient == nullptr) | |||
return 1; | |||
kClient->toolkitHide(); | |||
fClient->toolkitHide(); | |||
return 0; | |||
} | |||
int CarlaBridgeOsc::handleMsgQuit() | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fClient == nullptr, 1) | |||
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1); | |||
carla_debug("CarlaBridgeOsc::handleMsgQuit()"); | |||
if (kClient == nullptr) | |||
return 1; | |||
kClient->toolkitQuit(); | |||
fClient->toolkitQuit(); | |||
return 0; | |||
} | |||