forked from qt-creator/qt-creator
Lua: Improve memory management
Previously the PluginSpec would create a keep around a single lua vm that was then shared with the actual plugin instance. This made it unclear when the VM was freed. Now we instead cleanup the lua vm used to fetch the plugin infos immediately and instead create a fresh vm for the actual plugin instance that can then follow the normal Plugin lifecylce. Change-Id: I81bb9ecf57706c2ba1b0d8db83ab26b3b8e944f2 Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -34,28 +34,19 @@ class LuaPluginSpecPrivate
|
||||
{
|
||||
public:
|
||||
FilePath pluginScriptPath;
|
||||
|
||||
sol::state lua;
|
||||
sol::table pluginTable;
|
||||
|
||||
sol::function setupFunction;
|
||||
bool printToOutputPane = false;
|
||||
std::unique_ptr<sol::state> activeLuaState;
|
||||
};
|
||||
|
||||
LuaPluginSpec::LuaPluginSpec()
|
||||
: d(new LuaPluginSpecPrivate())
|
||||
{}
|
||||
|
||||
expected_str<LuaPluginSpec *> LuaPluginSpec::create(const FilePath &filePath,
|
||||
sol::state lua,
|
||||
sol::table pluginTable)
|
||||
expected_str<LuaPluginSpec *> LuaPluginSpec::create(const FilePath &filePath, sol::table pluginTable)
|
||||
{
|
||||
std::unique_ptr<LuaPluginSpec> pluginSpec(new LuaPluginSpec());
|
||||
|
||||
pluginSpec->d->lua = std::move(lua);
|
||||
pluginSpec->d->pluginTable = pluginTable;
|
||||
|
||||
pluginSpec->d->setupFunction = pluginTable.get_or<sol::function>("setup", {});
|
||||
if (!pluginSpec->d->setupFunction)
|
||||
if (!pluginTable.get_or<sol::function>("setup", {}))
|
||||
return make_unexpected(QString("Plugin info table did not contain a setup function"));
|
||||
|
||||
QJsonValue v = LuaEngine::toJson(pluginTable);
|
||||
@@ -75,6 +66,7 @@ expected_str<LuaPluginSpec *> LuaPluginSpec::create(const FilePath &filePath,
|
||||
pluginSpec->setLocation(filePath.parentDir());
|
||||
|
||||
pluginSpec->d->pluginScriptPath = filePath;
|
||||
pluginSpec->d->printToOutputPane = pluginTable.get_or("printToOutputPane", false);
|
||||
|
||||
return pluginSpec.release();
|
||||
}
|
||||
@@ -94,16 +86,19 @@ bool LuaPluginSpec::loadLibrary()
|
||||
}
|
||||
bool LuaPluginSpec::initializePlugin()
|
||||
{
|
||||
expected_str<void> setupResult
|
||||
= LuaEngine::instance()
|
||||
.prepareSetup(d->lua, *this, d->pluginTable.get<sol::optional<sol::table>>("hooks"));
|
||||
QTC_ASSERT(!d->activeLuaState, return false);
|
||||
|
||||
std::unique_ptr<sol::state> activeLuaState = std::make_unique<sol::state>();
|
||||
|
||||
expected_str<sol::protected_function> setupResult
|
||||
= LuaEngine::instance().prepareSetup(*activeLuaState, *this);
|
||||
|
||||
if (!setupResult) {
|
||||
setError(Lua::Tr::tr("Failed to prepare plugin setup: %1").arg(setupResult.error()));
|
||||
return false;
|
||||
}
|
||||
|
||||
auto result = d->setupFunction.call();
|
||||
auto result = setupResult->call();
|
||||
|
||||
if (result.get_type() == sol::type::boolean && result.get<bool>() == false) {
|
||||
setError(Lua::Tr::tr("Plugin setup function returned false"));
|
||||
@@ -117,6 +112,8 @@ bool LuaPluginSpec::initializePlugin()
|
||||
}
|
||||
}
|
||||
|
||||
d->activeLuaState = std::move(activeLuaState);
|
||||
|
||||
setState(PluginSpec::State::Initialized);
|
||||
return true;
|
||||
}
|
||||
@@ -133,14 +130,18 @@ bool LuaPluginSpec::delayedInitialize()
|
||||
}
|
||||
ExtensionSystem::IPlugin::ShutdownFlag LuaPluginSpec::stop()
|
||||
{
|
||||
d->activeLuaState.reset();
|
||||
return ExtensionSystem::IPlugin::ShutdownFlag::SynchronousShutdown;
|
||||
}
|
||||
|
||||
void LuaPluginSpec::kill() {}
|
||||
void LuaPluginSpec::kill()
|
||||
{
|
||||
d->activeLuaState.reset();
|
||||
}
|
||||
|
||||
bool LuaPluginSpec::printToOutputPane() const
|
||||
{
|
||||
return d->pluginTable.get_or("printToOutputPane", false);
|
||||
return d->printToOutputPane;
|
||||
}
|
||||
|
||||
} // namespace Lua
|
||||
|
||||
Reference in New Issue
Block a user