Fix LauncherInterface's destruction

Change the lifetime of LauncherInterface. Now it's being
constructed when startLauncher() is called and
destructed on stopLauncher(). Before, we hold the
static LauncherInterface object and couldn't control when
it's being destructed, so in fact the destruction
started too late, after the QtSingleApplication's destructor
finished.

Simplify LauncherInterface::isStarted() method.

Change-Id: I91f38212177318746d2530a418eb3efd3d9258cb
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2021-08-24 15:41:16 +02:00
parent 1a25f356ff
commit e2599b45ff
2 changed files with 12 additions and 20 deletions

View File

@@ -94,8 +94,6 @@ public:
void setPathToLauncher(const QString &path) { if (!path.isEmpty()) m_pathToLauncher = path; }
QString launcherFilePath() const { return m_pathToLauncher + QLatin1String("/qtcreator_processlauncher"); }
void setStarted(bool started) { m_startRequested = started; }
bool isStarted() const { return m_startRequests; }
signals:
void errorOccurred(const QString &error);
@@ -105,7 +103,6 @@ private:
Internal::LauncherProcess *m_process = nullptr;
QString m_pathToLauncher;
int m_startRequests = 0;
std::atomic_bool m_startRequested = false;
};
LauncherInterfacePrivate::LauncherInterfacePrivate()
@@ -123,8 +120,6 @@ LauncherInterfacePrivate::~LauncherInterfacePrivate()
void LauncherInterfacePrivate::doStart()
{
if (++m_startRequests > 1)
return;
const QString &socketName = launcherSocketName();
QLocalServer::removeServer(socketName);
if (!m_server->listen(socketName)) {
@@ -143,8 +138,6 @@ void LauncherInterfacePrivate::doStart()
void LauncherInterfacePrivate::doStop()
{
if (--m_startRequests > 0)
return;
m_server->close();
if (!m_process)
return;
@@ -191,6 +184,8 @@ void LauncherInterfacePrivate::handleProcessStderr()
using namespace Utils::Internal;
static LauncherInterface *s_instance = nullptr;
LauncherInterface::LauncherInterface()
: m_private(new LauncherInterfacePrivate())
{
@@ -201,12 +196,6 @@ LauncherInterface::LauncherInterface()
m_thread.start();
}
LauncherInterface &LauncherInterface::instance()
{
static LauncherInterface p;
return p;
}
LauncherInterface::~LauncherInterface()
{
m_thread.quit();
@@ -216,7 +205,9 @@ LauncherInterface::~LauncherInterface()
// Called from main thread
void LauncherInterface::startLauncher(const QString &pathToLauncher)
{
LauncherInterfacePrivate *p = instance().m_private;
QTC_ASSERT(s_instance == nullptr, return);
s_instance = new LauncherInterface();
LauncherInterfacePrivate *p = s_instance->m_private;
p->setPathToLauncher(pathToLauncher);
const FilePath launcherFilePath = FilePath::fromString(p->launcherFilePath())
.cleanPath().withExecutableSuffix();
@@ -225,7 +216,6 @@ void LauncherInterface::startLauncher(const QString &pathToLauncher)
<< launcherFilePath << "is not executable.";
};
QTC_ASSERT(launcherFilePath.isExecutableFile(), launcherIsNotExecutable(); return);
p->setStarted(true);
// Call in launcher's thread.
QMetaObject::invokeMethod(p, &LauncherInterfacePrivate::doStart);
}
@@ -233,20 +223,23 @@ void LauncherInterface::startLauncher(const QString &pathToLauncher)
// Called from main thread
void LauncherInterface::stopLauncher()
{
LauncherInterfacePrivate *p = instance().m_private;
p->setStarted(false);
QTC_ASSERT(s_instance != nullptr, return);
LauncherInterfacePrivate *p = s_instance->m_private;
// Call in launcher's thread.
QMetaObject::invokeMethod(p, &LauncherInterfacePrivate::doStop);
delete s_instance;
s_instance = nullptr;
}
Internal::LauncherSocket *LauncherInterface::socket()
{
return instance().m_private->socket();
QTC_ASSERT(s_instance != nullptr, return nullptr);
return s_instance->m_private->socket();
}
bool LauncherInterface::isStarted()
{
return instance().m_private->isStarted();
return s_instance != nullptr;
}
} // namespace Utils

View File

@@ -50,7 +50,6 @@ signals:
private:
LauncherInterface();
static LauncherInterface &instance();
~LauncherInterface() override;
QThread m_thread;