Browse Source

Clarified some shutdown behaviour in ConnectedChildProcess

tags/2021-05-28
jules 8 years ago
parent
commit
f4cf0c0ef4
2 changed files with 49 additions and 38 deletions
  1. +36
    -36
      modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp
  2. +13
    -2
      modules/juce_events/interprocess/juce_ConnectedChildProcess.h

+ 36
- 36
modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp View File

@@ -30,6 +30,11 @@ static const char* killMessage = "__ipc_k_";
static const char* pingMessage = "__ipc_p_";
enum { specialMessageSize = 8, defaultTimeoutMs = 8000 };
static inline bool isMessageType (const MemoryBlock& mb, const char* messageType) noexcept
{
return mb.matches (messageType, (size_t) specialMessageSize);
}
static String getCommandLinePrefix (const String& commandLineUniqueID)
{
return "--" + commandLineUniqueID + ":";
@@ -46,11 +51,6 @@ struct ChildProcessPingThread : public Thread,
pingReceived();
}
static bool isPingMessage (const MemoryBlock& m) noexcept
{
return memcmp (m.getData(), pingMessage, specialMessageSize) == 0;
}
void pingReceived() noexcept { countdown = timeoutMs / 1000 + 1; }
void triggerConnectionLostMessage() { triggerAsyncUpdate(); }
@@ -68,7 +68,7 @@ private:
{
while (! threadShouldExit())
{
if (--countdown <= 0 || ! sendPingMessage (MemoryBlock (pingMessage, specialMessageSize)))
if (--countdown <= 0 || ! sendPingMessage ({ pingMessage, specialMessageSize }))
{
triggerConnectionLostMessage();
break;
@@ -110,7 +110,7 @@ private:
{
pingReceived();
if (m.getSize() != specialMessageSize || ! isPingMessage (m))
if (m.getSize() != specialMessageSize || ! isMessageType (m, pingMessage))
owner.handleMessageFromSlave (m);
}
@@ -124,12 +124,7 @@ ChildProcessMaster::ChildProcessMaster() {}
ChildProcessMaster::~ChildProcessMaster()
{
if (connection != nullptr)
{
sendMessageToSlave (MemoryBlock (killMessage, specialMessageSize));
connection->disconnect();
connection.reset();
}
killSlaveProcess();
}
void ChildProcessMaster::handleConnectionLost() {}
@@ -143,10 +138,10 @@ bool ChildProcessMaster::sendMessageToSlave (const MemoryBlock& mb)
return false;
}
bool ChildProcessMaster::launchSlaveProcess (const File& executable, const String& commandLineUniqueID, int timeoutMs, int streamFlags)
bool ChildProcessMaster::launchSlaveProcess (const File& executable, const String& commandLineUniqueID,
int timeoutMs, int streamFlags)
{
connection.reset();
jassert (childProcess.kill());
killSlaveProcess();
auto pipeName = "p" + String::toHexString (Random().nextInt64());
@@ -154,13 +149,15 @@ bool ChildProcessMaster::launchSlaveProcess (const File& executable, const Strin
args.add (executable.getFullPathName());
args.add (getCommandLinePrefix (commandLineUniqueID) + pipeName);
if (childProcess.start (args, streamFlags))
childProcess.reset (new ChildProcess());
if (childProcess->start (args, streamFlags))
{
connection = new Connection (*this, pipeName, timeoutMs <= 0 ? defaultTimeoutMs : timeoutMs);
if (connection->isConnected())
{
sendMessageToSlave (MemoryBlock (startMessage, specialMessageSize));
sendMessageToSlave ({ startMessage, specialMessageSize });
return true;
}
@@ -170,6 +167,18 @@ bool ChildProcessMaster::launchSlaveProcess (const File& executable, const Strin
return false;
}
void ChildProcessMaster::killSlaveProcess()
{
if (connection != nullptr)
{
sendMessageToSlave ({ killMessage, specialMessageSize });
connection->disconnect();
connection.reset();
}
childProcess.reset();
}
//==============================================================================
struct ChildProcessSlave::Connection : public InterprocessConnection,
private ChildProcessPingThread
@@ -201,23 +210,14 @@ private:
{
pingReceived();
if (m.getSize() == specialMessageSize)
{
if (isPingMessage (m))
return;
if (isMessageType (m, pingMessage))
return;
if (memcmp (m.getData(), killMessage, specialMessageSize) == 0)
{
triggerConnectionLostMessage();
return;
}
if (isMessageType (m, killMessage))
return triggerConnectionLostMessage();
if (memcmp (m.getData(), startMessage, specialMessageSize) == 0)
{
owner.handleConnectionMade();
return;
}
}
if (isMessageType (m, startMessage))
return owner.handleConnectionMade();
owner.handleMessageFromMaster (m);
}
@@ -245,12 +245,12 @@ bool ChildProcessSlave::initialiseFromCommandLine (const String& commandLine,
const String& commandLineUniqueID,
int timeoutMs)
{
String prefix (getCommandLinePrefix (commandLineUniqueID));
auto prefix = getCommandLinePrefix (commandLineUniqueID);
if (commandLine.trim().startsWith (prefix))
{
String pipeName (commandLine.fromFirstOccurrenceOf (prefix, false, false)
.upToFirstOccurrenceOf (" ", false, false).trim());
auto pipeName = commandLine.fromFirstOccurrenceOf (prefix, false, false)
.upToFirstOccurrenceOf (" ", false, false).trim();
if (pipeName.isNotEmpty())
{


+ 13
- 2
modules/juce_events/interprocess/juce_ConnectedChildProcess.h View File

@@ -135,7 +135,10 @@ public:
*/
ChildProcessMaster();
/** Destructor. */
/** Destructor.
Note that the destructor calls killSlaveProcess(), but doesn't wait for
the child process to finish terminating.
*/
virtual ~ChildProcessMaster();
/** Attempts to launch and connect to a slave process.
@@ -152,12 +155,20 @@ public:
If this all works, the method returns true, and you can begin sending and
receiving messages with the slave process.
If a child process is already running, this will call killSlaveProcess() and
start a new one.
*/
bool launchSlaveProcess (const File& executableToLaunch,
const String& commandLineUniqueID,
int timeoutMs = 0,
int streamFlags = ChildProcess::wantStdOut | ChildProcess::wantStdErr);
/** Sends a kill message to the slave, and disconnects from it.
Note that this won't wait for it to terminate.
*/
void killSlaveProcess();
/** This will be called to deliver a message from the slave process.
The call will probably be made on a background thread, so be careful with your thread-safety!
*/
@@ -176,7 +187,7 @@ public:
bool sendMessageToSlave (const MemoryBlock&);
private:
ChildProcess childProcess;
ScopedPointer<ChildProcess> childProcess;
struct Connection;
friend struct Connection;


Loading…
Cancel
Save