mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
ChildProcessDemo: Fix crashes when stopping child process
Previously, the child process could be deleted from its own handleConnectionLost() callback, which would attempt to stop the child process's thread from that same thread. Now, the demo will attempt to stop the coordinator thread from the main thread instead.
This commit is contained in:
parent
c1a3cc28fd
commit
e5255eb76c
1 changed files with 37 additions and 15 deletions
|
|
@ -98,7 +98,12 @@ public:
|
|||
testResultsBox.setFont ({ Font::getDefaultMonospacedFontName(), 12.0f, Font::plain });
|
||||
|
||||
logMessage (String ("This demo uses the ChildProcessCoordinator and ChildProcessWorker classes to launch and communicate "
|
||||
"with a child process, sending messages in the form of serialised ValueTree objects.") + newLine);
|
||||
"with a child process, sending messages in the form of serialised ValueTree objects.") + newLine
|
||||
+ String ("In this demo, the child process will automatically quit if it fails to receive a ping message at least every ")
|
||||
+ String (timeoutSeconds)
|
||||
+ String (" seconds. To keep the process alive, press the \"")
|
||||
+ pingButton.getButtonText()
|
||||
+ String ("\" button periodically.") + newLine);
|
||||
|
||||
setSize (500, 500);
|
||||
}
|
||||
|
|
@ -136,10 +141,14 @@ public:
|
|||
{
|
||||
if (coordinatorProcess.get() == nullptr)
|
||||
{
|
||||
coordinatorProcess.reset (new DemoCoordinatorProcess (*this));
|
||||
coordinatorProcess = std::make_unique<DemoCoordinatorProcess> (*this);
|
||||
|
||||
if (coordinatorProcess->launchWorkerProcess (File::getSpecialLocation (File::currentExecutableFile), demoCommandLineUID))
|
||||
if (coordinatorProcess->launchWorkerProcess (File::getSpecialLocation (File::currentExecutableFile),
|
||||
demoCommandLineUID,
|
||||
timeoutMillis))
|
||||
{
|
||||
logMessage ("Child process started");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -166,11 +175,14 @@ public:
|
|||
// This class is used by the main process, acting as the coordinator and receiving messages
|
||||
// from the worker process.
|
||||
class DemoCoordinatorProcess : public ChildProcessCoordinator,
|
||||
private DeletedAtShutdown
|
||||
private DeletedAtShutdown,
|
||||
private AsyncUpdater
|
||||
{
|
||||
public:
|
||||
DemoCoordinatorProcess (ChildProcessDemo& d) : demo (d) {}
|
||||
|
||||
~DemoCoordinatorProcess() override { cancelPendingUpdate(); }
|
||||
|
||||
// This gets called when a message arrives from the worker process..
|
||||
void handleMessageFromWorker (const MemoryBlock& mb) override
|
||||
{
|
||||
|
|
@ -183,6 +195,11 @@ public:
|
|||
void handleConnectionLost() override
|
||||
{
|
||||
demo.logMessage ("Connection lost to child process!");
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
|
||||
void handleAsyncUpdate() override
|
||||
{
|
||||
demo.killChildProcess();
|
||||
}
|
||||
|
||||
|
|
@ -203,7 +220,11 @@ public:
|
|||
//==============================================================================
|
||||
std::unique_ptr<DemoCoordinatorProcess> coordinatorProcess;
|
||||
|
||||
static constexpr auto timeoutSeconds = 10;
|
||||
static constexpr auto timeoutMillis = timeoutSeconds * 1000;
|
||||
|
||||
private:
|
||||
|
||||
TextButton launchButton { "Launch Child Process" };
|
||||
TextButton pingButton { "Send Ping" };
|
||||
TextButton killButton { "Kill Child Process" };
|
||||
|
|
@ -268,8 +289,8 @@ public:
|
|||
}
|
||||
|
||||
/* If no pings are received from the coordinator process for a number of seconds, then this will get invoked.
|
||||
Typically you'll want to use this as a signal to kill the process as quickly as possible, as you
|
||||
don't want to leave it hanging around as a zombie..
|
||||
Typically, you'll want to use this as a signal to kill the process as quickly as possible, as you
|
||||
don't want to leave it hanging around as a zombie.
|
||||
*/
|
||||
void handleConnectionLost() override
|
||||
{
|
||||
|
|
@ -280,13 +301,13 @@ public:
|
|||
//==============================================================================
|
||||
/* The JUCEApplication::initialise method calls this function to allow the
|
||||
child process to launch when the command line parameters indicate that we're
|
||||
being asked to run as a child process..
|
||||
being asked to run as a child process.
|
||||
*/
|
||||
bool invokeChildProcessDemo (const String& commandLine)
|
||||
{
|
||||
std::unique_ptr<DemoWorkerProcess> worker (new DemoWorkerProcess());
|
||||
auto worker = std::make_unique<DemoWorkerProcess>();
|
||||
|
||||
if (worker->initialiseFromCommandLine (commandLine, demoCommandLineUID))
|
||||
if (worker->initialiseFromCommandLine (commandLine, demoCommandLineUID, ChildProcessDemo::timeoutMillis))
|
||||
{
|
||||
worker.release(); // allow the worker object to stay alive - it'll handle its own deletion.
|
||||
return true;
|
||||
|
|
@ -316,7 +337,7 @@ bool invokeChildProcessDemo (const String& commandLine)
|
|||
if (invokeChildProcessDemo (commandLine))
|
||||
return;
|
||||
|
||||
mainWindow.reset (new MainWindow ("ChildProcessDemo", new ChildProcessDemo()));
|
||||
mainWindow = std::make_unique<MainWindow> ("ChildProcessDemo", std::make_unique<ChildProcessDemo>());
|
||||
}
|
||||
|
||||
void shutdown() override { mainWindow = nullptr; }
|
||||
|
|
@ -325,13 +346,14 @@ bool invokeChildProcessDemo (const String& commandLine)
|
|||
class MainWindow : public DocumentWindow
|
||||
{
|
||||
public:
|
||||
MainWindow (const String& name, Component* c) : DocumentWindow (name,
|
||||
Desktop::getInstance().getDefaultLookAndFeel()
|
||||
.findColour (ResizableWindow::backgroundColourId),
|
||||
DocumentWindow::allButtons)
|
||||
MainWindow (const String& name, std::unique_ptr<Component> c)
|
||||
: DocumentWindow (name,
|
||||
Desktop::getInstance().getDefaultLookAndFeel()
|
||||
.findColour (ResizableWindow::backgroundColourId),
|
||||
DocumentWindow::allButtons)
|
||||
{
|
||||
setUsingNativeTitleBar (true);
|
||||
setContentOwned (c, true);
|
||||
setContentOwned (c.release(), true);
|
||||
|
||||
centreWithSize (getWidth(), getHeight());
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue