mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Naming: Fix up naming of ChildProcessCoordinator and ChildProcessWorker
This commit is contained in:
parent
6ae1137d91
commit
b72b155443
13 changed files with 194 additions and 146 deletions
|
|
@ -23,7 +23,7 @@
|
|||
namespace juce
|
||||
{
|
||||
|
||||
enum { magicMastSlaveConnectionHeader = 0x712baf04 };
|
||||
enum { magicCoordWorkerConnectionHeader = 0x712baf04 };
|
||||
|
||||
static const char* startMessage = "__ipc_st";
|
||||
static const char* killMessage = "__ipc_k_";
|
||||
|
|
@ -82,11 +82,11 @@ private:
|
|||
};
|
||||
|
||||
//==============================================================================
|
||||
struct ChildProcessMaster::Connection : public InterprocessConnection,
|
||||
private ChildProcessPingThread
|
||||
struct ChildProcessCoordinator::Connection : public InterprocessConnection,
|
||||
private ChildProcessPingThread
|
||||
{
|
||||
Connection (ChildProcessMaster& m, const String& pipeName, int timeout)
|
||||
: InterprocessConnection (false, magicMastSlaveConnectionHeader),
|
||||
Connection (ChildProcessCoordinator& m, const String& pipeName, int timeout)
|
||||
: InterprocessConnection (false, magicCoordWorkerConnectionHeader),
|
||||
ChildProcessPingThread (timeout),
|
||||
owner (m)
|
||||
{
|
||||
|
|
@ -103,7 +103,7 @@ private:
|
|||
void connectionMade() override {}
|
||||
void connectionLost() override { owner.handleConnectionLost(); }
|
||||
|
||||
bool sendPingMessage (const MemoryBlock& m) override { return owner.sendMessageToSlave (m); }
|
||||
bool sendPingMessage (const MemoryBlock& m) override { return owner.sendMessageToWorker (m); }
|
||||
void pingFailed() override { connectionLost(); }
|
||||
|
||||
void messageReceived (const MemoryBlock& m) override
|
||||
|
|
@ -111,25 +111,34 @@ private:
|
|||
pingReceived();
|
||||
|
||||
if (m.getSize() != specialMessageSize || ! isMessageType (m, pingMessage))
|
||||
owner.handleMessageFromSlave (m);
|
||||
owner.handleMessageFromWorker (m);
|
||||
}
|
||||
|
||||
ChildProcessMaster& owner;
|
||||
ChildProcessCoordinator& owner;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Connection)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
ChildProcessMaster::ChildProcessMaster() {}
|
||||
ChildProcessCoordinator::ChildProcessCoordinator() = default;
|
||||
|
||||
ChildProcessMaster::~ChildProcessMaster()
|
||||
ChildProcessCoordinator::~ChildProcessCoordinator()
|
||||
{
|
||||
killSlaveProcess();
|
||||
killWorkerProcess();
|
||||
}
|
||||
|
||||
void ChildProcessMaster::handleConnectionLost() {}
|
||||
void ChildProcessCoordinator::handleConnectionLost() {}
|
||||
|
||||
bool ChildProcessMaster::sendMessageToSlave (const MemoryBlock& mb)
|
||||
void ChildProcessCoordinator::handleMessageFromWorker (const MemoryBlock& mb)
|
||||
{
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations")
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996)
|
||||
handleMessageFromSlave (mb);
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
}
|
||||
|
||||
bool ChildProcessCoordinator::sendMessageToWorker (const MemoryBlock& mb)
|
||||
{
|
||||
if (connection != nullptr)
|
||||
return connection->sendMessage (mb);
|
||||
|
|
@ -138,10 +147,10 @@ bool ChildProcessMaster::sendMessageToSlave (const MemoryBlock& mb)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ChildProcessMaster::launchSlaveProcess (const File& executable, const String& commandLineUniqueID,
|
||||
int timeoutMs, int streamFlags)
|
||||
bool ChildProcessCoordinator::launchWorkerProcess (const File& executable, const String& commandLineUniqueID,
|
||||
int timeoutMs, int streamFlags)
|
||||
{
|
||||
killSlaveProcess();
|
||||
killWorkerProcess();
|
||||
|
||||
auto pipeName = "p" + String::toHexString (Random().nextInt64());
|
||||
|
||||
|
|
@ -157,7 +166,7 @@ bool ChildProcessMaster::launchSlaveProcess (const File& executable, const Strin
|
|||
|
||||
if (connection->isConnected())
|
||||
{
|
||||
sendMessageToSlave ({ startMessage, specialMessageSize });
|
||||
sendMessageToWorker ({ startMessage, specialMessageSize });
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -167,11 +176,11 @@ bool ChildProcessMaster::launchSlaveProcess (const File& executable, const Strin
|
|||
return false;
|
||||
}
|
||||
|
||||
void ChildProcessMaster::killSlaveProcess()
|
||||
void ChildProcessCoordinator::killWorkerProcess()
|
||||
{
|
||||
if (connection != nullptr)
|
||||
{
|
||||
sendMessageToSlave ({ killMessage, specialMessageSize });
|
||||
sendMessageToWorker ({ killMessage, specialMessageSize });
|
||||
connection->disconnect();
|
||||
connection.reset();
|
||||
}
|
||||
|
|
@ -180,11 +189,11 @@ void ChildProcessMaster::killSlaveProcess()
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
struct ChildProcessSlave::Connection : public InterprocessConnection,
|
||||
private ChildProcessPingThread
|
||||
struct ChildProcessWorker::Connection : public InterprocessConnection,
|
||||
private ChildProcessPingThread
|
||||
{
|
||||
Connection (ChildProcessSlave& p, const String& pipeName, int timeout)
|
||||
: InterprocessConnection (false, magicMastSlaveConnectionHeader),
|
||||
Connection (ChildProcessWorker& p, const String& pipeName, int timeout)
|
||||
: InterprocessConnection (false, magicCoordWorkerConnectionHeader),
|
||||
ChildProcessPingThread (timeout),
|
||||
owner (p)
|
||||
{
|
||||
|
|
@ -198,12 +207,12 @@ struct ChildProcessSlave::Connection : public InterprocessConnection,
|
|||
}
|
||||
|
||||
private:
|
||||
ChildProcessSlave& owner;
|
||||
ChildProcessWorker& owner;
|
||||
|
||||
void connectionMade() override {}
|
||||
void connectionLost() override { owner.handleConnectionLost(); }
|
||||
|
||||
bool sendPingMessage (const MemoryBlock& m) override { return owner.sendMessageToMaster (m); }
|
||||
bool sendPingMessage (const MemoryBlock& m) override { return owner.sendMessageToCoordinator (m); }
|
||||
void pingFailed() override { connectionLost(); }
|
||||
|
||||
void messageReceived (const MemoryBlock& m) override
|
||||
|
|
@ -219,20 +228,29 @@ private:
|
|||
if (isMessageType (m, startMessage))
|
||||
return owner.handleConnectionMade();
|
||||
|
||||
owner.handleMessageFromMaster (m);
|
||||
owner.handleMessageFromCoordinator (m);
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Connection)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
ChildProcessSlave::ChildProcessSlave() {}
|
||||
ChildProcessSlave::~ChildProcessSlave() {}
|
||||
ChildProcessWorker::ChildProcessWorker() = default;
|
||||
ChildProcessWorker::~ChildProcessWorker() = default;
|
||||
|
||||
void ChildProcessSlave::handleConnectionMade() {}
|
||||
void ChildProcessSlave::handleConnectionLost() {}
|
||||
void ChildProcessWorker::handleConnectionMade() {}
|
||||
void ChildProcessWorker::handleConnectionLost() {}
|
||||
|
||||
bool ChildProcessSlave::sendMessageToMaster (const MemoryBlock& mb)
|
||||
void ChildProcessWorker::handleMessageFromCoordinator (const MemoryBlock& mb)
|
||||
{
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations")
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996)
|
||||
handleMessageFromMaster (mb);
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
}
|
||||
|
||||
bool ChildProcessWorker::sendMessageToCoordinator (const MemoryBlock& mb)
|
||||
{
|
||||
if (connection != nullptr)
|
||||
return connection->sendMessage (mb);
|
||||
|
|
@ -241,9 +259,9 @@ bool ChildProcessSlave::sendMessageToMaster (const MemoryBlock& mb)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ChildProcessSlave::initialiseFromCommandLine (const String& commandLine,
|
||||
const String& commandLineUniqueID,
|
||||
int timeoutMs)
|
||||
bool ChildProcessWorker::initialiseFromCommandLine (const String& commandLine,
|
||||
const String& commandLineUniqueID,
|
||||
int timeoutMs)
|
||||
{
|
||||
auto prefix = getCommandLinePrefix (commandLineUniqueID);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,47 +25,47 @@ namespace juce
|
|||
|
||||
//==============================================================================
|
||||
/**
|
||||
Acts as the slave end of a master/slave pair of connected processes.
|
||||
Acts as the worker end of a coordinator/worker pair of connected processes.
|
||||
|
||||
The ChildProcessSlave and ChildProcessMaster classes make it easy for an app
|
||||
The ChildProcessWorker and ChildProcessCoordinator classes make it easy for an app
|
||||
to spawn a child process, and to manage a 2-way messaging connection to control it.
|
||||
|
||||
To use the system, you need to create subclasses of both ChildProcessSlave and
|
||||
ChildProcessMaster. To instantiate the ChildProcessSlave object, you must
|
||||
To use the system, you need to create subclasses of both ChildProcessWorker and
|
||||
ChildProcessCoordinator. To instantiate the ChildProcessWorker object, you must
|
||||
add some code to your main() or JUCEApplication::initialise() function that
|
||||
calls the initialiseFromCommandLine() method to check the app's command-line
|
||||
parameters to see whether it's being launched as a child process. If this returns
|
||||
true then the slave process can be allowed to run, and its handleMessageFromMaster()
|
||||
true then the worker process can be allowed to run, and its handleMessageFromCoordinator()
|
||||
method will be called whenever a message arrives.
|
||||
|
||||
The juce demo app has a good example of this class in action.
|
||||
|
||||
@see ChildProcessMaster, InterprocessConnection, ChildProcess
|
||||
@see ChildProcessCoordinator, InterprocessConnection, ChildProcess
|
||||
|
||||
@tags{Events}
|
||||
*/
|
||||
class JUCE_API ChildProcessSlave
|
||||
class JUCE_API ChildProcessWorker
|
||||
{
|
||||
public:
|
||||
/** Creates a non-connected slave process.
|
||||
Use initialiseFromCommandLine to connect to a master process.
|
||||
/** Creates a non-connected worker process.
|
||||
Use initialiseFromCommandLine to connect to a coordinator process.
|
||||
*/
|
||||
ChildProcessSlave();
|
||||
ChildProcessWorker();
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~ChildProcessSlave();
|
||||
virtual ~ChildProcessWorker();
|
||||
|
||||
/** This checks some command-line parameters to see whether they were generated by
|
||||
ChildProcessMaster::launchSlaveProcess(), and if so, connects to that master process.
|
||||
ChildProcessCoordinator::launchWorkerProcess(), and if so, connects to that coordinator process.
|
||||
|
||||
In an exe that can be used as a child process, you should add some code to your
|
||||
main() or JUCEApplication::initialise() that calls this method.
|
||||
|
||||
The commandLineUniqueID should be a short alphanumeric identifier (no spaces!)
|
||||
that matches the string passed to ChildProcessMaster::launchSlaveProcess().
|
||||
that matches the string passed to ChildProcessCoordinator::launchWorkerProcess().
|
||||
|
||||
The timeoutMs parameter lets you specify how long the child process is allowed
|
||||
to run without receiving a ping from the master before the master is considered to
|
||||
to run without receiving a ping from the coordinator before the coordinator is considered to
|
||||
have died, and handleConnectionLost() will be called. Passing <= 0 for this timeout
|
||||
makes it use a default value.
|
||||
|
||||
|
|
@ -76,78 +76,86 @@ public:
|
|||
int timeoutMs = 0);
|
||||
|
||||
//==============================================================================
|
||||
/** This will be called to deliver messages from the master process.
|
||||
/** This will be called to deliver messages from the coordinator process.
|
||||
The call will probably be made on a background thread, so be careful with your
|
||||
thread-safety! You may want to respond by sending back a message with
|
||||
sendMessageToMaster()
|
||||
sendMessageToCoordinator()
|
||||
*/
|
||||
virtual void handleMessageFromMaster (const MemoryBlock&) = 0;
|
||||
virtual void handleMessageFromCoordinator (const MemoryBlock& mb);
|
||||
|
||||
/** This will be called when the master process finishes connecting to this slave.
|
||||
[[deprecated ("Replaced by handleMessageFromCoordinator.")]]
|
||||
virtual void handleMessageFromMaster (const MemoryBlock&) {}
|
||||
|
||||
/** This will be called when the coordinator process finishes connecting to this worker.
|
||||
The call will probably be made on a background thread, so be careful with your thread-safety!
|
||||
*/
|
||||
virtual void handleConnectionMade();
|
||||
|
||||
/** This will be called when the connection to the master process is lost.
|
||||
/** This will be called when the connection to the coordinator process is lost.
|
||||
The call may be made from any thread (including the message thread).
|
||||
Typically, if your process only exists to act as a slave, you should probably exit
|
||||
Typically, if your process only exists to act as a worker, you should probably exit
|
||||
when this happens.
|
||||
*/
|
||||
virtual void handleConnectionLost();
|
||||
|
||||
/** Tries to send a message to the master process.
|
||||
/** Tries to send a message to the coordinator process.
|
||||
This returns true if the message was sent, but doesn't check that it actually gets
|
||||
delivered at the other end. If successful, the data will emerge in a call to your
|
||||
ChildProcessMaster::handleMessageFromSlave().
|
||||
ChildProcessCoordinator::handleMessageFromWorker().
|
||||
*/
|
||||
bool sendMessageToMaster (const MemoryBlock&);
|
||||
bool sendMessageToCoordinator (const MemoryBlock&);
|
||||
|
||||
[[deprecated ("Replaced by sendMessageToCoordinator.")]]
|
||||
bool sendMessageToMaster (const MemoryBlock& mb) { return sendMessageToCoordinator (mb); }
|
||||
|
||||
private:
|
||||
struct Connection;
|
||||
std::unique_ptr<Connection> connection;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessSlave)
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessWorker)
|
||||
};
|
||||
|
||||
using ChildProcessSlave [[deprecated ("Replaced by ChildProcessWorker.")]] = ChildProcessWorker;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Acts as the master in a master/slave pair of connected processes.
|
||||
Acts as the coordinator in a coordinator/worker pair of connected processes.
|
||||
|
||||
The ChildProcessSlave and ChildProcessMaster classes make it easy for an app
|
||||
The ChildProcessWorker and ChildProcessCoordinator classes make it easy for an app
|
||||
to spawn a child process, and to manage a 2-way messaging connection to control it.
|
||||
|
||||
To use the system, you need to create subclasses of both ChildProcessSlave and
|
||||
ChildProcessMaster. When you want your master process to launch the slave, you
|
||||
just call launchSlaveProcess(), and it'll attempt to launch the executable that
|
||||
To use the system, you need to create subclasses of both ChildProcessWorker and
|
||||
ChildProcessCoordinator. When you want your coordinator process to launch the worker, you
|
||||
just call launchWorkerProcess(), and it'll attempt to launch the executable that
|
||||
you specify (which may be the same exe), and assuming it has been set-up to
|
||||
correctly parse the command-line parameters (see ChildProcessSlave) then a
|
||||
correctly parse the command-line parameters (see ChildProcessWorker) then a
|
||||
two-way connection will be created.
|
||||
|
||||
The juce demo app has a good example of this class in action.
|
||||
|
||||
@see ChildProcessSlave, InterprocessConnection, ChildProcess
|
||||
@see ChildProcessWorker, InterprocessConnection, ChildProcess
|
||||
|
||||
@tags{Events}
|
||||
*/
|
||||
class JUCE_API ChildProcessMaster
|
||||
class JUCE_API ChildProcessCoordinator
|
||||
{
|
||||
public:
|
||||
/** Creates an uninitialised master process object.
|
||||
Use launchSlaveProcess to launch and connect to a child process.
|
||||
/** Creates an uninitialised coordinator process object.
|
||||
Use launchWorkerProcess to launch and connect to a child process.
|
||||
*/
|
||||
ChildProcessMaster();
|
||||
ChildProcessCoordinator();
|
||||
|
||||
/** Destructor.
|
||||
Note that the destructor calls killSlaveProcess(), but doesn't wait for
|
||||
Note that the destructor calls killWorkerProcess(), but doesn't wait for
|
||||
the child process to finish terminating.
|
||||
*/
|
||||
virtual ~ChildProcessMaster();
|
||||
virtual ~ChildProcessCoordinator();
|
||||
|
||||
/** Attempts to launch and connect to a slave process.
|
||||
/** Attempts to launch and connect to a worker process.
|
||||
This will start the given executable, passing it a special command-line
|
||||
parameter based around the commandLineUniqueID string, which must be a
|
||||
short alphanumeric string (no spaces!) that identifies your app. The exe
|
||||
that gets launched must respond by calling ChildProcessSlave::initialiseFromCommandLine()
|
||||
that gets launched must respond by calling ChildProcessWorker::initialiseFromCommandLine()
|
||||
in its startup code, and must use a matching ID to commandLineUniqueID.
|
||||
|
||||
The timeoutMs parameter lets you specify how long the child process is allowed
|
||||
|
|
@ -156,37 +164,55 @@ public:
|
|||
it use a default value.
|
||||
|
||||
If this all works, the method returns true, and you can begin sending and
|
||||
receiving messages with the slave process.
|
||||
receiving messages with the worker process.
|
||||
|
||||
If a child process is already running, this will call killSlaveProcess() and
|
||||
If a child process is already running, this will call killWorkerProcess() and
|
||||
start a new one.
|
||||
*/
|
||||
bool launchWorkerProcess (const File& executableToLaunch,
|
||||
const String& commandLineUniqueID,
|
||||
int timeoutMs = 0,
|
||||
int streamFlags = ChildProcess::wantStdOut | ChildProcess::wantStdErr);
|
||||
|
||||
[[deprecated ("Replaced by launchWorkerProcess.")]]
|
||||
bool launchSlaveProcess (const File& executableToLaunch,
|
||||
const String& commandLineUniqueID,
|
||||
int timeoutMs = 0,
|
||||
int streamFlags = ChildProcess::wantStdOut | ChildProcess::wantStdErr);
|
||||
int streamFlags = ChildProcess::wantStdOut | ChildProcess::wantStdErr)
|
||||
{
|
||||
return launchWorkerProcess (executableToLaunch, commandLineUniqueID, timeoutMs, streamFlags);
|
||||
}
|
||||
|
||||
/** Sends a kill message to the slave, and disconnects from it.
|
||||
/** Sends a kill message to the worker, and disconnects from it.
|
||||
Note that this won't wait for it to terminate.
|
||||
*/
|
||||
void killSlaveProcess();
|
||||
void killWorkerProcess();
|
||||
|
||||
/** This will be called to deliver a message from the slave process.
|
||||
[[deprecated ("Replaced by killWorkerProcess.")]]
|
||||
void killSlaveProcess() { killWorkerProcess(); }
|
||||
|
||||
/** This will be called to deliver a message from the worker process.
|
||||
The call will probably be made on a background thread, so be careful with your thread-safety!
|
||||
*/
|
||||
virtual void handleMessageFromSlave (const MemoryBlock&) = 0;
|
||||
virtual void handleMessageFromWorker (const MemoryBlock&);
|
||||
|
||||
/** This will be called when the slave process dies or is somehow disconnected.
|
||||
[[deprecated ("Replaced by handleMessageFromWorker")]]
|
||||
virtual void handleMessageFromSlave (const MemoryBlock&) {}
|
||||
|
||||
/** This will be called when the worker process dies or is somehow disconnected.
|
||||
The call will probably be made on a background thread, so be careful with your thread-safety!
|
||||
*/
|
||||
virtual void handleConnectionLost();
|
||||
|
||||
/** Attempts to send a message to the slave process.
|
||||
/** Attempts to send a message to the worker process.
|
||||
This returns true if the message was dispatched, but doesn't check that it actually
|
||||
gets delivered at the other end. If successful, the data will emerge in a call to
|
||||
your ChildProcessSlave::handleMessageFromMaster().
|
||||
your ChildProcessWorker::handleMessageFromCoordinator().
|
||||
*/
|
||||
bool sendMessageToSlave (const MemoryBlock&);
|
||||
bool sendMessageToWorker (const MemoryBlock&);
|
||||
|
||||
[[deprecated ("Replaced by sendMessageToWorker.")]]
|
||||
bool sendMessageToSlave (const MemoryBlock& mb) { return sendMessageToWorker (mb); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<ChildProcess> childProcess;
|
||||
|
|
@ -194,7 +220,9 @@ private:
|
|||
struct Connection;
|
||||
std::unique_ptr<Connection> connection;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessMaster)
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessCoordinator)
|
||||
};
|
||||
|
||||
using ChildProcessMaster [[deprecated ("Replaced by ChildProcessCoordinator.")]] = ChildProcessCoordinator;
|
||||
|
||||
} // namespace juce
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue