LuaLSC: Fix crash on exit

Since the client lives longer than the lua context, its destruction would
also cleanup the custom handlers which had captured the lua function.

Calling anything as well as the destructor of a sol object after the lua
context is gone results in a crash, so make sure that we don't keep it
around any longer.

A better solution in the long term would be to allow custom handlers to
be unregistered in the Language Client.

Change-Id: I59ac39d9279dc5faf24d3fd3b29e8c7c00e2b48e
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Marcus Tillmanns
2024-06-07 10:34:55 +02:00
parent 421210e609
commit 13c892f9d3

View File

@@ -294,8 +294,13 @@ public:
} }
} }
// TODO: Unregister Client settings from LanguageClientManager ~LuaClientWrapper()
~LuaClientWrapper() = default; {
for (auto client : m_clients)
LanguageClientManager::shutdownClient(client);
// TODO: Unregister Client settings from LanguageClientManager
}
TransportType transportType() { return m_transportType; } TransportType transportType() { return m_transportType; }
@@ -338,9 +343,15 @@ public:
for (Client *c : m_clients) { for (Client *c : m_clients) {
for (const auto &[msg, func] : m_messageCallbacks.asKeyValueRange()) { for (const auto &[msg, func] : m_messageCallbacks.asKeyValueRange()) {
c->registerCustomMethod( c->registerCustomMethod(
msg, [name = msg, f = func](const LanguageServerProtocol::JsonRpcMessage &m) { msg,
auto table = ::Lua::LuaEngine::toTable(f.lua_state(), m.toJsonObject()); [self = QPointer<LuaClientWrapper>(this),
auto result = f.call(table); name = msg](const LanguageServerProtocol::JsonRpcMessage &m) {
if (!self)
return;
auto func = self->m_messageCallbacks.value(name);
auto table = ::Lua::LuaEngine::toTable(func.lua_state(), m.toJsonObject());
auto result = func.call(table);
if (!result.valid()) { if (!result.valid()) {
qWarning() << "Error calling message callback for:" << name << ":" qWarning() << "Error calling message callback for:" << name << ":"
<< (result.get<sol::error>().what()); << (result.get<sol::error>().what());