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. * 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), fHasBroadcast(false),
fHasOptionalGui(false), fHasOptionalGui(false),
fHasServerControl(false), fHasServerControl(false),
fStarted() {}
fStarted(),
fReadyActionOpen(true),
fReadyActionSave(true) {}


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

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


void start()
void ready(const int action)
{ {
CARLA_SAFE_ASSERT_RETURN(fOscServerThread != nullptr,); 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() static CarlaNSM& getInstance()
@@ -251,28 +290,36 @@ protected:
CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 1); CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 1);
carla_stdout("CarlaNSM::handleOpen(\"%s\", \"%s\", \"%s\")", projectPath, displayName, clientNameId); 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"); 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 // Broadcast ourselves
if (fHasBroadcast) if (fHasBroadcast)
{ {
@@ -301,16 +348,25 @@ protected:
{ {
CARLA_SAFE_ASSERT_RETURN(fOscAddress != nullptr, 1); CARLA_SAFE_ASSERT_RETURN(fOscAddress != nullptr, 1);
CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 1); CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 1);
CARLA_SAFE_ASSERT_RETURN(fProjectPath.isNotEmpty(), 0);
carla_stdout("CarlaNSM::handleSave()"); 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) if (gStandalone.engineCallback != nullptr)
{
fReadyActionSave = false;
gStandalone.engineCallback(gStandalone.engineCallbackPtr, CB::ENGINE_CALLBACK_NSM, 0, 3, 0, 0.0f, nullptr); 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; return 0;
} }


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


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

if (gStandalone.engineCallback != nullptr) if (gStandalone.engineCallback != nullptr)
gStandalone.engineCallback(gStandalone.engineCallbackPtr, CB::ENGINE_CALLBACK_NSM, 0, 5, 0, 0.0f, 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_SAFE_ASSERT_RETURN(fOscServer != nullptr, 1);
carla_stdout("CarlaNSM::handleHideOptionalGui()"); carla_stdout("CarlaNSM::handleHideOptionalGui()");


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

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


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


volatile bool fReadyActionOpen;
volatile bool fReadyActionSave;

#define handlePtr ((CarlaNSM*)data) #define handlePtr ((CarlaNSM*)data)


static void _osc_error_handler(int num, const char* msg, const char* path) 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 #endif
} }


void carla_nsm_ready()
void carla_nsm_ready(int action)
{ {
#ifdef HAVE_LIBLO #ifdef HAVE_LIBLO
CarlaNSM::getInstance().start();
CarlaNSM::getInstance().ready(action);
#endif #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.argtypes = [c_int, c_char_p]
self.lib.carla_nsm_init.restype = c_bool 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 self.lib.carla_nsm_ready.restype = None


# -------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------
@@ -2616,8 +2616,8 @@ class CarlaHostDLL(CarlaHostMeta):
def nsm_init(self, pid, executableName): def nsm_init(self, pid, executableName):
return bool(self.lib.carla_nsm_init(pid, executableName.encode("utf-8"))) 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 # 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 # For NSM we wait for the open message
if NSM_URL and host.nsmOK: if NSM_URL and host.nsmOK:
self.fFirstEngineInit = False
self.setEngineSettings()
host.nsm_ready()
host.nsm_ready(-1)
return return


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


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


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


self.host.nsm_ready(value1)

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


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


Loading…
Cancel
Save