forked from qt-creator/qt-creator
LanguageClient: track clients scheduled for deletion
So report an async shutdown if we have clients scheduled for deletion and wait until all clients have been fully deleted. Change-Id: I40d35d3429003ab2a5c68cb81486c3e16b5f6f63 Reviewed-by: Christian Stenger <christian.stenger@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -189,7 +189,7 @@ void LanguageClientManager::clientFinished(Client *client)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
deleteClient(client);
|
deleteClient(client);
|
||||||
if (PluginManager::isShuttingDown() && managerInstance->m_clients.isEmpty())
|
if (isShutdownFinished())
|
||||||
emit managerInstance->shutdownFinished();
|
emit managerInstance->shutdownFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,6 +243,7 @@ void LanguageClientManager::deleteClient(Client *client)
|
|||||||
// that will not handle the delete later event. Use invokeMethod with Qt::QueuedConnection
|
// that will not handle the delete later event. Use invokeMethod with Qt::QueuedConnection
|
||||||
// instead.
|
// instead.
|
||||||
QMetaObject::invokeMethod(client, [client] {delete client;}, Qt::QueuedConnection);
|
QMetaObject::invokeMethod(client, [client] {delete client;}, Qt::QueuedConnection);
|
||||||
|
managerInstance->trackClientDeletion(client);
|
||||||
|
|
||||||
if (!PluginManager::isShuttingDown())
|
if (!PluginManager::isShuttingDown())
|
||||||
emit instance()->clientRemoved(client);
|
emit instance()->clientRemoved(client);
|
||||||
@@ -608,4 +609,24 @@ void LanguageClientManager::projectAdded(ProjectExplorer::Project *project)
|
|||||||
client->projectOpened(project);
|
client->projectOpened(project);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LanguageClientManager::trackClientDeletion(Client *client)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(!m_scheduledForDeletion.contains(client->id()), return);
|
||||||
|
m_scheduledForDeletion.insert(client->id());
|
||||||
|
connect(client, &QObject::destroyed, [this, id = client->id()](){
|
||||||
|
m_scheduledForDeletion.remove(id);
|
||||||
|
if (isShutdownFinished())
|
||||||
|
emit shutdownFinished();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LanguageClientManager::isShutdownFinished()
|
||||||
|
{
|
||||||
|
if (!PluginManager::isShuttingDown())
|
||||||
|
return false;
|
||||||
|
QTC_ASSERT(managerInstance, return true);
|
||||||
|
return managerInstance->m_clients.isEmpty()
|
||||||
|
&& managerInstance->m_scheduledForDeletion.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace LanguageClient
|
} // namespace LanguageClient
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ public:
|
|||||||
static void deleteClient(Client *client);
|
static void deleteClient(Client *client);
|
||||||
|
|
||||||
static void shutdown();
|
static void shutdown();
|
||||||
|
static bool isShutdownFinished();
|
||||||
|
|
||||||
static LanguageClientManager *instance();
|
static LanguageClientManager *instance();
|
||||||
|
|
||||||
@@ -96,6 +97,8 @@ private:
|
|||||||
void updateProject(ProjectExplorer::Project *project);
|
void updateProject(ProjectExplorer::Project *project);
|
||||||
void projectAdded(ProjectExplorer::Project *project);
|
void projectAdded(ProjectExplorer::Project *project);
|
||||||
|
|
||||||
|
void trackClientDeletion(Client *client);
|
||||||
|
|
||||||
QList<Client *> reachableClients();
|
QList<Client *> reachableClients();
|
||||||
|
|
||||||
QList<Client *> m_clients;
|
QList<Client *> m_clients;
|
||||||
@@ -105,6 +108,7 @@ private:
|
|||||||
QHash<TextEditor::TextDocument *, QPointer<Client>> m_clientForDocument;
|
QHash<TextEditor::TextDocument *, QPointer<Client>> m_clientForDocument;
|
||||||
std::unique_ptr<LanguageClientManagerPrivate> d;
|
std::unique_ptr<LanguageClientManagerPrivate> d;
|
||||||
LspInspector m_inspector;
|
LspInspector m_inspector;
|
||||||
|
QSet<Utils::Id> m_scheduledForDeletion;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> bool LanguageClientManager::hasClients()
|
template<typename T> bool LanguageClientManager::hasClients()
|
||||||
|
|||||||
@@ -60,12 +60,12 @@ void LanguageClientPlugin::extensionsInitialized()
|
|||||||
ExtensionSystem::IPlugin::ShutdownFlag LanguageClientPlugin::aboutToShutdown()
|
ExtensionSystem::IPlugin::ShutdownFlag LanguageClientPlugin::aboutToShutdown()
|
||||||
{
|
{
|
||||||
LanguageClientManager::shutdown();
|
LanguageClientManager::shutdown();
|
||||||
if (LanguageClientManager::clients().isEmpty())
|
if (LanguageClientManager::isShutdownFinished())
|
||||||
return ExtensionSystem::IPlugin::SynchronousShutdown;
|
return ExtensionSystem::IPlugin::SynchronousShutdown;
|
||||||
QTC_ASSERT(LanguageClientManager::instance(),
|
QTC_ASSERT(LanguageClientManager::instance(),
|
||||||
return ExtensionSystem::IPlugin::SynchronousShutdown);
|
return ExtensionSystem::IPlugin::SynchronousShutdown);
|
||||||
connect(LanguageClientManager::instance(), &LanguageClientManager::shutdownFinished,
|
connect(LanguageClientManager::instance(), &LanguageClientManager::shutdownFinished,
|
||||||
this, &ExtensionSystem::IPlugin::asynchronousShutdownFinished, Qt::QueuedConnection);
|
this, &ExtensionSystem::IPlugin::asynchronousShutdownFinished);
|
||||||
return ExtensionSystem::IPlugin::AsynchronousShutdown;
|
return ExtensionSystem::IPlugin::AsynchronousShutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user