Skip to content

Commit 63fc467

Browse files
committed
fix: add missing destroy engine when load failed
1 parent efb5b02 commit 63fc467

File tree

1 file changed

+40
-31
lines changed

1 file changed

+40
-31
lines changed

src/lse/PluginManager.cpp

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ ll::Expected<> PluginManager::load(ll::mod::Manifest manifest) {
129129
return ll::makeStringError("Plugin has already loaded");
130130
}
131131

132-
auto& scriptEngine = *EngineManager::newEngine(manifest.name);
133-
auto plugin = std::make_shared<Plugin>(manifest);
132+
auto scriptEngine = EngineManager::newEngine(manifest.name);
133+
auto plugin = std::make_shared<Plugin>(manifest);
134134

135135
try {
136136
script::EngineScope engineScope(scriptEngine);
@@ -139,30 +139,30 @@ ll::Expected<> PluginManager::load(ll::mod::Manifest manifest) {
139139
getEngineOwnData()->logger = ll::io::LoggerRegistry::getInstance().getOrCreate(manifest.name);
140140

141141
#ifdef LEGACY_SCRIPT_ENGINE_BACKEND_PYTHON
142-
scriptEngine.eval("import sys as _llse_py_sys_module");
142+
scriptEngine->eval("import sys as _llse_py_sys_module");
143143
std::error_code ec;
144144

145145
// add plugin-own site-packages to sys.path
146146
std::string pluginSitePackageFormatted = ll::string_utils::u8str2str(
147147
std::filesystem::canonical(realPackageInstallDir.make_preferred(), ec).u8string()
148148
);
149149
if (!ec) {
150-
scriptEngine.eval("_llse_py_sys_module.path.insert(0, r'" + pluginSitePackageFormatted + "')");
150+
scriptEngine->eval("_llse_py_sys_module.path.insert(0, r'" + pluginSitePackageFormatted + "')");
151151
}
152152
// add plugin source dir to sys.path
153153
std::string sourceDirFormatted =
154154
ll::string_utils::u8str2str(std::filesystem::canonical(dirPath.make_preferred()).u8string());
155-
scriptEngine.eval("_llse_py_sys_module.path.insert(0, r'" + sourceDirFormatted + "')");
155+
scriptEngine->eval("_llse_py_sys_module.path.insert(0, r'" + sourceDirFormatted + "')");
156156

157157
// set __file__ and __name__
158158
std::string entryPathFormatted = ll::string_utils::u8str2str(
159159
std::filesystem::canonical(std::filesystem::path(entryPath).make_preferred()).u8string()
160160
);
161-
scriptEngine.set("__file__", entryPathFormatted);
161+
scriptEngine->set("__file__", entryPathFormatted);
162162
// engine->set("__name__", String::newString("__main__"));
163163
#endif
164164

165-
BindAPIs(&scriptEngine);
165+
BindAPIs(scriptEngine);
166166

167167
auto& self = LegacyScriptEngine::getInstance().getSelf();
168168
#ifndef LEGACY_SCRIPT_ENGINE_BACKEND_NODEJS // NodeJs backend load depends code in another place
@@ -172,14 +172,14 @@ ll::Expected<> PluginManager::load(ll::mod::Manifest manifest) {
172172
if (!baseLibContent) {
173173
return ll::makeStringError("Failed to read BaseLib at {0}"_tr(baseLibPath.string()));
174174
}
175-
scriptEngine.eval(baseLibContent.value());
175+
scriptEngine->eval(baseLibContent.value());
176176
#endif
177177
// Load the plugin entry.
178178
auto entryPath = plugin->getModDir() / manifest.entry;
179179
getEngineOwnData()->plugin = plugin;
180180
#ifdef LEGACY_SCRIPT_ENGINE_BACKEND_PYTHON
181181
if (!PythonHelper::loadPluginCode(
182-
&scriptEngine,
182+
scriptEngine,
183183
ll::string_utils::u8str2str(entryPath.u8string()),
184184
ll::string_utils::u8str2str(dirPath.u8string())
185185
)) {
@@ -188,7 +188,7 @@ ll::Expected<> PluginManager::load(ll::mod::Manifest manifest) {
188188
#endif
189189
#ifdef LEGACY_SCRIPT_ENGINE_BACKEND_NODEJS
190190
if (!NodeJsHelper::loadPluginCode(
191-
&scriptEngine,
191+
scriptEngine,
192192
ll::string_utils::u8str2str(entryPath.u8string()),
193193
ll::string_utils::u8str2str(dirPath.u8string())
194194
)) {
@@ -198,46 +198,56 @@ ll::Expected<> PluginManager::load(ll::mod::Manifest manifest) {
198198
#if (defined LEGACY_SCRIPT_ENGINE_BACKEND_QUICKJS) || (defined LEGACY_SCRIPT_ENGINE_BACKEND_LUA)
199199
// Try loadFile
200200
try {
201-
scriptEngine.loadFile(entryPath.u8string());
201+
scriptEngine->loadFile(entryPath.u8string());
202202
} catch (const script::Exception&) {
203203
// loadFile failed, try eval
204204
auto pluginEntryContent = ll::file_utils::readFile(entryPath);
205205
if (!pluginEntryContent) {
206206
return ll::makeStringError("Failed to read plugin entry at {0}"_tr(entryPath.string()));
207207
}
208-
scriptEngine.eval(pluginEntryContent.value(), entryPath.u8string());
208+
scriptEngine->eval(pluginEntryContent.value(), entryPath.u8string());
209209
}
210210
#endif
211211
if (ll::getGamingStatus() == ll::GamingStatus::Running) { // Is hot load
212-
LLSECallEventsOnHotLoad(&scriptEngine);
212+
LLSECallEventsOnHotLoad(scriptEngine);
213213
}
214214
ExitEngineScope exit;
215215
plugin->onLoad([](ll::mod::Mod&) { return true; });
216216
plugin->onUnload([](ll::mod::Mod&) { return true; });
217217

218218
return plugin->onLoad().transform([&, this] { addMod(manifest.name, plugin); });
219219
} catch (const Exception& e) {
220-
EngineScope engineScope(scriptEngine);
221-
auto error =
222-
ll::makeStringError("Failed to load plugin {0}: {1}\n{2}"_tr(manifest.name, e.message(), e.stacktrace()));
223-
ExitEngineScope exit;
224-
LLSERemoveTimeTaskData(&scriptEngine);
225-
LLSERemoveAllEventListeners(&scriptEngine);
226-
LLSERemoveCmdRegister(&scriptEngine);
227-
LLSERemoveCmdCallback(&scriptEngine);
228-
LLSERemoveAllExportedFuncs(&scriptEngine);
229-
230-
scriptEngine.getData().reset();
220+
if (scriptEngine) {
221+
EngineScope engineScope(scriptEngine);
222+
auto error = ll::makeStringError(
223+
"Failed to load plugin {0}: {1}\n{2}"_tr(manifest.name, e.message(), e.stacktrace())
224+
);
225+
ExitEngineScope exit;
231226

232-
EngineManager::unregisterEngine(&scriptEngine);
227+
#ifndef LEGACY_SCRIPT_ENGINE_BACKEND_NODEJS
228+
LLSERemoveTimeTaskData(scriptEngine);
229+
#endif
230+
LLSERemoveAllEventListeners(scriptEngine);
231+
LLSERemoveCmdRegister(scriptEngine);
232+
LLSERemoveCmdCallback(scriptEngine);
233+
LLSERemoveAllExportedFuncs(scriptEngine);
233234

234-
return error;
235+
scriptEngine->getData().reset();
236+
EngineManager::unregisterEngine(scriptEngine);
237+
#ifdef LEGACY_SCRIPT_ENGINE_BACKEND_NODEJS
238+
NodeJsHelper::stopEngine(scriptEngine);
239+
#else
240+
scriptEngine->destroy();
241+
#endif
242+
return error;
243+
} else {
244+
return ll::makeStringError("Failed to load plugin {0}: {1}"_tr(manifest.name, "ScriptEngine* is nullptr"));
245+
}
235246
}
236247
}
237248

238249
ll::Expected<> PluginManager::unload(std::string_view name) {
239250
try {
240-
auto plugin = std::static_pointer_cast<Plugin>(getMod(name));
241251
auto scriptEngine = EngineManager::getEngine(std::string(name));
242252

243253
#ifndef LEGACY_SCRIPT_ENGINE_BACKEND_NODEJS
@@ -249,8 +259,10 @@ ll::Expected<> PluginManager::unload(std::string_view name) {
249259
LLSERemoveCmdCallback(scriptEngine);
250260
LLSERemoveAllExportedFuncs(scriptEngine);
251261

252-
scriptEngine->getData().reset();
253262
EngineManager::unregisterEngine(scriptEngine);
263+
scriptEngine->getData().reset();
264+
265+
eraseMod(name);
254266

255267
ll::coro::keepThis([scriptEngine]() -> ll::coro::CoroTask<> {
256268
using namespace ll::chrono_literals;
@@ -260,11 +272,8 @@ ll::Expected<> PluginManager::unload(std::string_view name) {
260272
#else
261273
scriptEngine->destroy(); // TODO: use unique_ptr to manage the engine.
262274
#endif
263-
co_return;
264275
}).launch(ll::thread::ServerThreadExecutor::getDefault());
265276

266-
eraseMod(name);
267-
268277
return {};
269278
} catch (const std::exception& e) {
270279
return ll::makeStringError("Failed to unload plugin {0}: {1}"_tr(name, e.what()));

0 commit comments

Comments
 (0)