Browse Source

Make sure to stop pipe communication right when UI bridges close

tags/1.9.8
falkTX 7 years ago
parent
commit
d40e36ddfa
5 changed files with 75 additions and 25 deletions
  1. +4
    -12
      source/bridges-ui/CarlaBridgeUI.cpp
  2. +1
    -0
      source/externalui.py
  3. +1
    -4
      source/native-plugins/zynaddsubfx-ui.cpp
  4. +61
    -9
      source/utils/CarlaPipeUtils.cpp
  5. +8
    -0
      source/utils/CarlaPipeUtils.hpp

+ 4
- 12
source/bridges-ui/CarlaBridgeUI.cpp View File

@@ -57,19 +57,15 @@ CarlaBridgeUI::~CarlaBridgeUI() /*noexcept*/
{ {
carla_debug("CarlaBridgeUI::~CarlaBridgeUI()"); carla_debug("CarlaBridgeUI::~CarlaBridgeUI()");


if (isPipeRunning() && ! fQuitReceived)
writeExitingMessageAndWait();

if (fLib != nullptr) if (fLib != nullptr)
{ {
lib_close(fLib); lib_close(fLib);
fLib = nullptr; fLib = nullptr;
} }


if (isPipeRunning() && ! fQuitReceived)
{
const CarlaMutexLocker cml(getPipeLock());
writeMessage("exiting\n", 8);
flushMessages();
}

if (fToolkit != nullptr) if (fToolkit != nullptr)
{ {
fToolkit->quit(); fToolkit->quit();
@@ -318,11 +314,7 @@ bool CarlaBridgeUI::init(const int argc, const char* argv[])
if (! fGotOptions) if (! fGotOptions)
{ {
carla_stderr2("CarlaBridgeUI::init() - did not get options on time, quitting..."); carla_stderr2("CarlaBridgeUI::init() - did not get options on time, quitting...");
{
const CarlaMutexLocker cml(getPipeLock());
writeMessage("exiting\n", 8);
flushMessages();
}
writeExitingMessageAndWait();
closePipeClient(); closePipeClient();
return false; return false;
} }


+ 1
- 0
source/externalui.py View File

@@ -60,6 +60,7 @@ class ExternalUI(object):
if self.fPipeClient is None: if self.fPipeClient is None:
return return


# FIXME
if not self.fQuitReceived: if not self.fQuitReceived:
self.send(["exiting"]) self.send(["exiting"])




+ 1
- 4
source/native-plugins/zynaddsubfx-ui.cpp View File

@@ -136,10 +136,7 @@ public:
if (fQuitReceived) if (fQuitReceived)
return; return;


const CarlaMutexLocker cml(getPipeLock());

writeMessage("exiting\n");
flushMessages();
writeExitingMessageAndWait();
} }


protected: protected:


+ 61
- 9
source/utils/CarlaPipeUtils.cpp View File

@@ -411,9 +411,18 @@ struct CarlaPipeCommon::PrivateData {
// read functions must only be called in context of idlePipe() // read functions must only be called in context of idlePipe()
bool isReading; bool isReading;


// the client side is closing down, only waiting for response from server
bool clientClosingDown;

// other side of pipe has closed
bool pipeClosed;

// print error only once // print error only once
bool lastMessageFailed; bool lastMessageFailed;


// for debugging
bool isServer;

// common write lock // common write lock
CarlaMutex writeLock; CarlaMutex writeLock;


@@ -430,7 +439,10 @@ struct CarlaPipeCommon::PrivateData {
pipeRecv(INVALID_PIPE_VALUE), pipeRecv(INVALID_PIPE_VALUE),
pipeSend(INVALID_PIPE_VALUE), pipeSend(INVALID_PIPE_VALUE),
isReading(false), isReading(false),
clientClosingDown(false),
pipeClosed(true),
lastMessageFailed(false), lastMessageFailed(false),
isServer(false),
writeLock(), writeLock(),
tmpBuf(), tmpBuf(),
tmpStr() tmpStr()
@@ -466,7 +478,7 @@ CarlaPipeCommon::~CarlaPipeCommon() /*noexcept*/


bool CarlaPipeCommon::isPipeRunning() const noexcept bool CarlaPipeCommon::isPipeRunning() const noexcept
{ {
return (pData->pipeRecv != INVALID_PIPE_VALUE && pData->pipeSend != INVALID_PIPE_VALUE);
return (pData->pipeRecv != INVALID_PIPE_VALUE && pData->pipeSend != INVALID_PIPE_VALUE && ! pData->pipeClosed);
} }


void CarlaPipeCommon::idlePipe(const bool onlyOnce) noexcept void CarlaPipeCommon::idlePipe(const bool onlyOnce) noexcept
@@ -488,15 +500,22 @@ void CarlaPipeCommon::idlePipe(const bool onlyOnce) noexcept


pData->isReading = true; pData->isReading = true;


try {
msgReceived(msg);
} CARLA_SAFE_EXCEPTION("msgReceived");
if (std::strcmp(msg, "__carla-quit__") == 0)
{
pData->pipeClosed = true;
}
else if (! pData->clientClosingDown)
{
try {
msgReceived(msg);
} CARLA_SAFE_EXCEPTION("msgReceived");
}


pData->isReading = false; pData->isReading = false;


delete[] msg; delete[] msg;


if (onlyOnce)
if (onlyOnce || pData->pipeRecv == INVALID_PIPE_VALUE)
break; break;
} }


@@ -1015,12 +1034,18 @@ bool CarlaPipeCommon::_writeMsgBuffer(const char* const msg, const std::size_t s
return true; return true;
} }


#if 0
// ignore errors if the other side of the pipe has closed
if (pData->pipeClosed)
return false;
#endif

if (! pData->lastMessageFailed) if (! pData->lastMessageFailed)
{ {
pData->lastMessageFailed = true; pData->lastMessageFailed = true;
fprintf(stderr, fprintf(stderr,
"CarlaPipeCommon::_writeMsgBuffer(..., " P_SIZE ") - failed with " P_SSIZE ", message was:\n%s",
size, ret, msg);
"CarlaPipeCommon::_writeMsgBuffer(..., " P_SIZE ") - failed with " P_SSIZE " (%s), message was:\n%s",
size, ret, bool2str(pData->isServer), msg);
} }


return false; return false;
@@ -1032,6 +1057,7 @@ CarlaPipeServer::CarlaPipeServer() noexcept
: CarlaPipeCommon() : CarlaPipeCommon()
{ {
carla_debug("CarlaPipeServer::CarlaPipeServer()"); carla_debug("CarlaPipeServer::CarlaPipeServer()");
pData->isServer = true;
} }


CarlaPipeServer::~CarlaPipeServer() /*noexcept*/ CarlaPipeServer::~CarlaPipeServer() /*noexcept*/
@@ -1269,6 +1295,7 @@ bool CarlaPipeServer::startPipeServer(const char* const filename,
#endif #endif
pData->pipeRecv = pipeRecvClient; pData->pipeRecv = pipeRecvClient;
pData->pipeSend = pipeSendClient; pData->pipeSend = pipeSendClient;
pData->pipeClosed = false;
carla_stdout("ALL OK!"); carla_stdout("ALL OK!");
return true; return true;
} }
@@ -1323,7 +1350,7 @@ void CarlaPipeServer::stopPipeServer(const uint32_t timeOutMilliseconds) noexcep


if (pData->pipeSend != INVALID_PIPE_VALUE) if (pData->pipeSend != INVALID_PIPE_VALUE)
{ {
_writeMsgBuffer("quit\n", 5);
_writeMsgBuffer("__carla-quit__\n", 15);
flushMessages(); flushMessages();
} }


@@ -1341,7 +1368,7 @@ void CarlaPipeServer::stopPipeServer(const uint32_t timeOutMilliseconds) noexcep


if (pData->pipeSend != INVALID_PIPE_VALUE) if (pData->pipeSend != INVALID_PIPE_VALUE)
{ {
_writeMsgBuffer("quit\n", 5);
_writeMsgBuffer("__carla-quit__\n", 15);
flushMessages(); flushMessages();
} }


@@ -1357,6 +1384,8 @@ void CarlaPipeServer::closePipeServer() noexcept
{ {
carla_debug("CarlaPipeServer::closePipeServer()"); carla_debug("CarlaPipeServer::closePipeServer()");


pData->pipeClosed = true;

const CarlaMutexLocker cml(pData->writeLock); const CarlaMutexLocker cml(pData->writeLock);


if (pData->pipeRecv != INVALID_PIPE_VALUE) if (pData->pipeRecv != INVALID_PIPE_VALUE)
@@ -1472,6 +1501,8 @@ bool CarlaPipeClient::initPipeClient(const char* argv[]) noexcept


pData->pipeRecv = pipeRecvServer; pData->pipeRecv = pipeRecvServer;
pData->pipeSend = pipeSendServer; pData->pipeSend = pipeSendServer;
pData->pipeClosed = false;
pData->clientClosingDown = false;


writeMessage("\n", 1); writeMessage("\n", 1);
flushMessages(); flushMessages();
@@ -1483,6 +1514,8 @@ void CarlaPipeClient::closePipeClient() noexcept
{ {
carla_debug("CarlaPipeClient::closePipeClient()"); carla_debug("CarlaPipeClient::closePipeClient()");


pData->pipeClosed = true;

const CarlaMutexLocker cml(pData->writeLock); const CarlaMutexLocker cml(pData->writeLock);


if (pData->pipeRecv != INVALID_PIPE_VALUE) if (pData->pipeRecv != INVALID_PIPE_VALUE)
@@ -1506,6 +1539,25 @@ void CarlaPipeClient::closePipeClient() noexcept
} }
} }


void CarlaPipeClient::writeExitingMessageAndWait() noexcept
{
{
const CarlaMutexLocker cml(pData->writeLock);
_writeMsgBuffer("exiting\n", 8);
flushMessages();
}

// NOTE: no more messages are handled after this point
pData->clientClosingDown = true;

// FIXME: don't sleep forever
for (; ! pData->pipeClosed;)
{
carla_msleep(50);
idlePipe(true);
}
}

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


ScopedEnvVar::ScopedEnvVar(const char* const key, const char* const value) noexcept ScopedEnvVar::ScopedEnvVar(const char* const key, const char* const value) noexcept


+ 8
- 0
source/utils/CarlaPipeUtils.hpp View File

@@ -320,6 +320,14 @@ public:
*/ */
void closePipeClient() noexcept; void closePipeClient() noexcept;


// -------------------------------------------------------------------
// write prepared messages, no lock or flush needed (done internally)

/*!
* Write a single "exiting" message and wait for server to respond.
*/
void writeExitingMessageAndWait() noexcept;

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeClient) CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeClient)
}; };




Loading…
Cancel
Save