forked from qt-creator/qt-creator
LauncherInterface: Wait for graceful finish of process launcher
Give process launcher a chance to finish its processes
gracefully before we finish process launcher's process in Creator.
Otherwise, when Creator's process reaper kills the process
launcher's process while the process launcher is still
reaping its processes, the process launcher may leave zombies.
Instantiate the ProcessReaper inside ProcessReaper::reap(),
otherwise its destructor won't run at all inside process launcher.
Reverts e45e16d904
Fixes: QTCREATORBUG-27118
Change-Id: I00290cda05538b5a7ecbeb08240d1e3772d43d62
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -138,12 +138,11 @@ void LauncherInterfacePrivate::doStart()
|
|||||||
void LauncherInterfacePrivate::doStop()
|
void LauncherInterfacePrivate::doStop()
|
||||||
{
|
{
|
||||||
m_server->close();
|
m_server->close();
|
||||||
if (!m_process)
|
QTC_ASSERT(m_process, return);
|
||||||
return;
|
|
||||||
m_process->disconnect();
|
|
||||||
m_socket->shutdown();
|
m_socket->shutdown();
|
||||||
m_process->waitForFinished(3000);
|
m_process->waitForFinished(-1); // Let the process interface finish so that it finishes
|
||||||
ProcessReaper::reap(m_process);
|
// reaping any possible processes it has started.
|
||||||
|
delete m_process;
|
||||||
m_process = nullptr;
|
m_process = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -195,6 +195,7 @@ void ProcessReaper::reap(QProcess *process, int timeoutMs)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProcessReaper::instance();
|
||||||
new Internal::Reaper(process, timeoutMs);
|
new Internal::Reaper(process, timeoutMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,8 +35,6 @@
|
|||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
#include <extensionsystem/iplugin.h>
|
|
||||||
|
|
||||||
#include <projectexplorer/devicesupport/devicemanager.h>
|
#include <projectexplorer/devicesupport/devicemanager.h>
|
||||||
#include <projectexplorer/devicesupport/idevicewidget.h>
|
#include <projectexplorer/devicesupport/idevicewidget.h>
|
||||||
#include <projectexplorer/kitinformation.h>
|
#include <projectexplorer/kitinformation.h>
|
||||||
@@ -621,28 +619,6 @@ void AndroidDeviceManager::setupDevicesWatcher()
|
|||||||
updateAvdsList();
|
updateAvdsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidDeviceManager::shutdownDevicesWatcher()
|
|
||||||
{
|
|
||||||
m_avdsFutureWatcher.waitForFinished();
|
|
||||||
m_removeAvdFutureWatcher.waitForFinished();
|
|
||||||
|
|
||||||
if (m_adbDeviceWatcherProcess) {
|
|
||||||
m_adbDeviceWatcherProcess->terminate();
|
|
||||||
m_adbDeviceWatcherProcess->waitForFinished();
|
|
||||||
m_adbDeviceWatcherProcess.reset();
|
|
||||||
|
|
||||||
// Despite terminate/waitForFinished, the process may still
|
|
||||||
// be around and remain if Qt Creator finishes too early.
|
|
||||||
QTimer::singleShot(1000, this, [this] { emit devicesWatcherShutdownFinished(); });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ExtensionSystem::IPlugin::ShutdownFlag AndroidDeviceManager::devicesShutdownFlag() const
|
|
||||||
{
|
|
||||||
return m_adbDeviceWatcherProcess ? ExtensionSystem::IPlugin::AsynchronousShutdown
|
|
||||||
: ExtensionSystem::IPlugin::SynchronousShutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AndroidDeviceManager::HandleAvdsListChange()
|
void AndroidDeviceManager::HandleAvdsListChange()
|
||||||
{
|
{
|
||||||
DeviceManager *const devMgr = DeviceManager::instance();
|
DeviceManager *const devMgr = DeviceManager::instance();
|
||||||
@@ -706,6 +682,13 @@ void AndroidDeviceManager::HandleAvdsListChange()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AndroidDeviceManager::shutdownDevicesWatcher()
|
||||||
|
{
|
||||||
|
m_avdsFutureWatcher.waitForFinished();
|
||||||
|
m_removeAvdFutureWatcher.waitForFinished();
|
||||||
|
m_adbDeviceWatcherProcess.reset();
|
||||||
|
}
|
||||||
|
|
||||||
void AndroidDeviceManager::HandleDevicesListChange(const QString &serialNumber)
|
void AndroidDeviceManager::HandleDevicesListChange(const QString &serialNumber)
|
||||||
{
|
{
|
||||||
DeviceManager *const devMgr = DeviceManager::instance();
|
DeviceManager *const devMgr = DeviceManager::instance();
|
||||||
|
@@ -30,8 +30,6 @@
|
|||||||
#include "androidconfigurations.h"
|
#include "androidconfigurations.h"
|
||||||
#include "androiddeviceinfo.h"
|
#include "androiddeviceinfo.h"
|
||||||
|
|
||||||
#include <extensionsystem/iplugin.h>
|
|
||||||
|
|
||||||
#include <projectexplorer/devicesupport/idevice.h>
|
#include <projectexplorer/devicesupport/idevice.h>
|
||||||
#include <projectexplorer/devicesupport/idevicefactory.h>
|
#include <projectexplorer/devicesupport/idevicefactory.h>
|
||||||
|
|
||||||
@@ -106,7 +104,7 @@ public:
|
|||||||
static AndroidDeviceManager *instance();
|
static AndroidDeviceManager *instance();
|
||||||
void setupDevicesWatcher();
|
void setupDevicesWatcher();
|
||||||
void shutdownDevicesWatcher();
|
void shutdownDevicesWatcher();
|
||||||
ExtensionSystem::IPlugin::ShutdownFlag devicesShutdownFlag() const;
|
|
||||||
void updateAvdsList();
|
void updateAvdsList();
|
||||||
IDevice::DeviceState getDeviceState(const QString &serial, IDevice::MachineType type) const;
|
IDevice::DeviceState getDeviceState(const QString &serial, IDevice::MachineType type) const;
|
||||||
void updateDeviceState(const ProjectExplorer::IDevice::ConstPtr &device);
|
void updateDeviceState(const ProjectExplorer::IDevice::ConstPtr &device);
|
||||||
@@ -118,9 +116,6 @@ public:
|
|||||||
|
|
||||||
QString getRunningAvdsSerialNumber(const QString &name) const;
|
QString getRunningAvdsSerialNumber(const QString &name) const;
|
||||||
|
|
||||||
signals:
|
|
||||||
void devicesWatcherShutdownFinished();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AndroidDeviceManager(QObject *parent = nullptr);
|
AndroidDeviceManager(QObject *parent = nullptr);
|
||||||
void HandleDevicesListChange(const QString &serialNumber);
|
void HandleDevicesListChange(const QString &serialNumber);
|
||||||
|
@@ -160,17 +160,10 @@ bool AndroidPlugin::initialize(const QStringList &arguments, QString *errorMessa
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidPlugin::ShutdownFlag AndroidPlugin::aboutToShutdown()
|
ExtensionSystem::IPlugin::ShutdownFlag AndroidPlugin::aboutToShutdown()
|
||||||
{
|
{
|
||||||
AndroidDeviceManager *dm = AndroidDeviceManager::instance();
|
AndroidDeviceManager::instance()->shutdownDevicesWatcher();
|
||||||
const IPlugin::ShutdownFlag sf = dm->devicesShutdownFlag();
|
return ExtensionSystem::IPlugin::SynchronousShutdown;
|
||||||
|
|
||||||
if (sf == AsynchronousShutdown)
|
|
||||||
connect(dm, &AndroidDeviceManager::devicesWatcherShutdownFinished,
|
|
||||||
this, &ExtensionSystem::IPlugin::asynchronousShutdownFinished);
|
|
||||||
|
|
||||||
dm->shutdownDevicesWatcher();
|
|
||||||
return sf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidPlugin::kitsRestored()
|
void AndroidPlugin::kitsRestored()
|
||||||
|
@@ -44,9 +44,7 @@ class AndroidPlugin final : public ExtensionSystem::IPlugin
|
|||||||
|
|
||||||
class AndroidPluginPrivate *d = nullptr;
|
class AndroidPluginPrivate *d = nullptr;
|
||||||
|
|
||||||
public:
|
|
||||||
ShutdownFlag aboutToShutdown() final;
|
ShutdownFlag aboutToShutdown() final;
|
||||||
|
|
||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
private slots:
|
private slots:
|
||||||
void testAndroidSdkManagerProgressParser_data();
|
void testAndroidSdkManagerProgressParser_data();
|
||||||
|
Reference in New Issue
Block a user