Browse Source

Make NSM actions thread-safe

tags/1.9.6
falkTX 10 years ago
parent
commit
2bc0b3ddb7
4 changed files with 95 additions and 38 deletions
  1. +1
    -1
      source/backend/CarlaHost.h
  2. +84
    -29
      source/backend/CarlaStandalone.cpp
  3. +3
    -3
      source/carla_backend.py
  4. +7
    -5
      source/carla_host.py

+ 1
- 1
source/backend/CarlaHost.h View File

@@ -907,7 +907,7 @@ CARLA_EXPORT bool carla_nsm_init(int pid, const char* executableName);
/*!
* Allow NSM callbacks.
*/
CARLA_EXPORT void carla_nsm_ready();
CARLA_EXPORT void carla_nsm_ready(int action);

/** @} */



+ 84
- 29
source/backend/CarlaStandalone.cpp View File

@@ -104,10 +104,15 @@ public:
fHasBroadcast(false),
fHasOptionalGui(false),
fHasServerControl(false),
fStarted() {}
fStarted(),
fReadyActionOpen(true),
fReadyActionSave(true) {}

~CarlaNSM()
{
CARLA_SAFE_ASSERT(fReadyActionOpen);
CARLA_SAFE_ASSERT(fReadyActionSave);

if (fOscServerThread != nullptr)
{
lo_server_thread_stop(fOscServerThread);
@@ -167,13 +172,47 @@ public:
return true;
}

void start()
void ready(const int action)
{
CARLA_SAFE_ASSERT_RETURN(fOscServerThread != nullptr,);
CARLA_SAFE_ASSERT_RETURN(! fStarted,);

fStarted = true;
lo_server_thread_start(fOscServerThread);
switch (action)
{
case -1: // init
CARLA_SAFE_ASSERT_BREAK(! fStarted);
fStarted = true;
lo_server_thread_start(fOscServerThread);
break;

case 0: // error
break;

case 1: // reply
break;

case 2: // open
fReadyActionOpen = true;
break;

case 3: // save
fReadyActionSave = true;
break;

case 4: // session loaded
break;

case 5: // show gui
CARLA_SAFE_ASSERT_BREAK(fOscAddress != nullptr);
CARLA_SAFE_ASSERT_BREAK(fOscServer != nullptr);
lo_send_from(fOscAddress, fOscServer, LO_TT_IMMEDIATE, "/nsm/client/gui_is_shown", "");
break;

case 6: // hide gui
CARLA_SAFE_ASSERT_BREAK(fOscAddress != nullptr);
CARLA_SAFE_ASSERT_BREAK(fOscServer != nullptr);
lo_send_from(fOscAddress, fOscServer, LO_TT_IMMEDIATE, "/nsm/client/gui_is_hidden", "");
break;
}
}

static CarlaNSM& getInstance()
@@ -251,28 +290,36 @@ protected:
CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 1);
carla_stdout("CarlaNSM::handleOpen(\"%s\", \"%s\", \"%s\")", projectPath, displayName, clientNameId);

if (carla_is_engine_running())
carla_engine_close();
if (gStandalone.engineCallback != nullptr)
{
fReadyActionOpen = false;
gStandalone.engineCallback(gStandalone.engineCallbackPtr, CB::ENGINE_CALLBACK_NSM, 0, 2, 0, 0.0f, projectPath);

for (; ! fReadyActionOpen;)
carla_msleep(10);
}
else
{
using namespace juce;

carla_engine_init("JACK", clientNameId);
if (carla_is_engine_running())
carla_engine_close();

fProjectPath = projectPath;
fProjectPath += ".carxp";
carla_engine_init("JACK", clientNameId);

fClientNameId = clientNameId;
fProjectPath = projectPath;
fProjectPath += ".carxp";

using namespace juce;
const String jfilename = String(CharPointer_UTF8(fProjectPath));

const String jfilename = String(CharPointer_UTF8(fProjectPath));
if (File(jfilename).existsAsFile())
carla_load_project(fProjectPath);
}

if (File(jfilename).existsAsFile())
carla_load_project(fProjectPath);
fClientNameId = clientNameId;

lo_send_from(fOscAddress, fOscServer, LO_TT_IMMEDIATE, "/reply", "ss", "/nsm/client/open", "OK");

if (gStandalone.engineCallback != nullptr)
gStandalone.engineCallback(gStandalone.engineCallbackPtr, CB::ENGINE_CALLBACK_NSM, 0, 2, 0, 0.0f, projectPath);

// Broadcast ourselves
if (fHasBroadcast)
{
@@ -301,16 +348,25 @@ protected:
{
CARLA_SAFE_ASSERT_RETURN(fOscAddress != nullptr, 1);
CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 1);
CARLA_SAFE_ASSERT_RETURN(fProjectPath.isNotEmpty(), 0);
carla_stdout("CarlaNSM::handleSave()");

carla_save_project(fProjectPath);

lo_send_from(fOscAddress, fOscServer, LO_TT_IMMEDIATE, "/reply", "ss", "/nsm/client/save", "OK");

if (gStandalone.engineCallback != nullptr)
{
fReadyActionSave = false;
gStandalone.engineCallback(gStandalone.engineCallbackPtr, CB::ENGINE_CALLBACK_NSM, 0, 3, 0, 0.0f, nullptr);

for (; ! fReadyActionSave;)
carla_msleep(10);
}
else
{
CARLA_SAFE_ASSERT_RETURN(fProjectPath.isNotEmpty(), 0);

carla_save_project(fProjectPath);
}

lo_send_from(fOscAddress, fOscServer, LO_TT_IMMEDIATE, "/reply", "ss", "/nsm/client/save", "OK");

return 0;
}

@@ -332,8 +388,6 @@ protected:
CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 1);
carla_stdout("CarlaNSM::handleShowOptionalGui()");

lo_send_from(fOscAddress, fOscServer, LO_TT_IMMEDIATE, "/nsm/client/gui_is_shown", "");

if (gStandalone.engineCallback != nullptr)
gStandalone.engineCallback(gStandalone.engineCallbackPtr, CB::ENGINE_CALLBACK_NSM, 0, 5, 0, 0.0f, nullptr);

@@ -346,8 +400,6 @@ protected:
CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 1);
carla_stdout("CarlaNSM::handleHideOptionalGui()");

lo_send_from(fOscAddress, fOscServer, LO_TT_IMMEDIATE, "/nsm/client/gui_is_hidden", "");

if (gStandalone.engineCallback != nullptr)
gStandalone.engineCallback(gStandalone.engineCallbackPtr, CB::ENGINE_CALLBACK_NSM, 0, 6, 0, 0.0f, nullptr);

@@ -591,6 +643,9 @@ private:
bool fHasServerControl;
bool fStarted;

volatile bool fReadyActionOpen;
volatile bool fReadyActionSave;

#define handlePtr ((CarlaNSM*)data)

static void _osc_error_handler(int num, const char* msg, const char* path)
@@ -2521,10 +2576,10 @@ bool carla_nsm_init(int pid, const char* executableName)
#endif
}

void carla_nsm_ready()
void carla_nsm_ready(int action)
{
#ifdef HAVE_LIBLO
CarlaNSM::getInstance().start();
CarlaNSM::getInstance().ready(action);
#endif
}



+ 3
- 3
source/carla_backend.py View File

@@ -2348,7 +2348,7 @@ class CarlaHostDLL(CarlaHostMeta):
self.lib.carla_nsm_init.argtypes = [c_int, c_char_p]
self.lib.carla_nsm_init.restype = c_bool

self.lib.carla_nsm_ready.argtypes = None
self.lib.carla_nsm_ready.argtypes = [c_int]
self.lib.carla_nsm_ready.restype = None

# --------------------------------------------------------------------------------------------------------
@@ -2616,8 +2616,8 @@ class CarlaHostDLL(CarlaHostMeta):
def nsm_init(self, pid, executableName):
return bool(self.lib.carla_nsm_init(pid, executableName.encode("utf-8")))

def nsm_ready(self):
self.lib.carla_nsm_ready()
def nsm_ready(self, action):
self.lib.carla_nsm_ready(action)

# ------------------------------------------------------------------------------------------------------------
# Helper object for CarlaHostPlugin


+ 7
- 5
source/carla_host.py View File

@@ -411,9 +411,7 @@ class HostWindow(QMainWindow):

# For NSM we wait for the open message
if NSM_URL and host.nsmOK:
self.fFirstEngineInit = False
self.setEngineSettings()
host.nsm_ready()
host.nsm_ready(-1)
return

QTimer.singleShot(0, self.slot_engineStart)
@@ -1594,11 +1592,13 @@ class HostWindow(QMainWindow):
self.fClientName = os.path.basename(valueStr)
self.fProjectFilename = QFileInfo(valueStr+".carxp").absoluteFilePath()
self.setProperWindowTitle()
self.ui.act_file_save.setEnabled(True)
self.slot_engineStop(True)
self.slot_engineStart()
self.loadProjectNow()

# Save
elif value1 == 3:
pass
self.saveProjectNow()

# Session is Loaded
elif value1 == 4:
@@ -1612,6 +1612,8 @@ class HostWindow(QMainWindow):
elif value1 == 6:
self.hide()

self.host.nsm_ready(value1)

# --------------------------------------------------------------------------------------------------------

@pyqtSlot(int, int, int, float, str)


Loading…
Cancel
Save