From 5978665ad64f7cc86e49cb84b76d6edd8d6b032d Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Thu, 16 Sep 2021 10:07:04 +0200 Subject: [PATCH] Lua: Fix threading related crash --- include/IThreaded.h | 5 +++++ include/TLuaEngine.h | 6 +++--- src/TConsole.cpp | 8 +++++--- src/TLuaEngine.cpp | 22 +++++++++++++++------- 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/include/IThreaded.h b/include/IThreaded.h index ca5d7cd..d08e428 100644 --- a/include/IThreaded.h +++ b/include/IThreaded.h @@ -8,6 +8,11 @@ public: IThreaded() // invokes operator() on this object : mThread() { } + ~IThreaded() noexcept { + if (mThread.joinable()) { + mThread.join(); + } + } virtual void Start() final { mThread = std::thread([this] { (*this)(); }); diff --git a/include/TLuaEngine.h b/include/TLuaEngine.h index 72b3d68..4899817 100644 --- a/include/TLuaEngine.h +++ b/include/TLuaEngine.h @@ -19,14 +19,15 @@ class TLuaPlugin; struct TLuaResult { std::atomic_bool Ready; + std::atomic_bool Error; + std::string ErrorMessage; // TODO: Add condition_variable - std::any Result; }; struct TLuaPluginConfig { static inline const std::string FileName = "PluginConfig.toml"; TLuaStateId StateId; - // TODO: Execute list + // TODO: Add execute list }; class TLuaEngine : IThreaded { @@ -49,7 +50,6 @@ private: StateThreadData(const StateThreadData&) = delete; [[nodiscard]] std::shared_ptr EnqueueScript(const std::shared_ptr& Script); void operator()() override; - ~StateThreadData(); private: std::string mName; diff --git a/src/TConsole.cpp b/src/TConsole.cpp index 1cdc71e..34e858f 100644 --- a/src/TConsole.cpp +++ b/src/TConsole.cpp @@ -64,9 +64,11 @@ TConsole::TConsole() { auto Future = mLuaEngine->EnqueueScript(mStateId, std::make_shared(cmd)); // wait for it to finish while (!Future->Ready) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + if (Future->Error) { + beammp_error(Future->ErrorMessage); } - mCommandline.write("Result ready."); } }; } @@ -82,6 +84,6 @@ void TConsole::WriteRaw(const std::string& str) { } void TConsole::InitializeLuaConsole(TLuaEngine& Engine) { - Engine.EnsureStateExists(mStateId, "<>"); + Engine.EnsureStateExists(mStateId, "Console"); mLuaEngine = &Engine; } diff --git a/src/TLuaEngine.cpp b/src/TLuaEngine.cpp index 5012b61..3b0fa1e 100644 --- a/src/TLuaEngine.cpp +++ b/src/TLuaEngine.cpp @@ -5,6 +5,9 @@ #include #include +#define SOL_ALL_SAFETIES_ON 1 +#include + static std::mt19937_64 MTGen64; static TLuaStateId GenerateUniqueStateId() { @@ -106,6 +109,9 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomi , mShutdown(Shutdown) { mState = luaL_newstate(); luaL_openlibs(mState); + sol::state_view StateView(mState); + auto LuaPrint = [](const std::string& Msg) { luaprint(Msg); }; + StateView.set_function("print", LuaPrint); Start(); } @@ -129,18 +135,20 @@ void TLuaEngine::StateThreadData::operator()() { mStateExecuteQueue.pop(); Lock.unlock(); beammp_debug("Running script"); - luaL_dostring(mState, S.first->data()); + sol::state_view StateView(mState); + auto Res = StateView.safe_script(*S.first, sol::script_pass_on_error); + if (Res.valid()) { + S.second->Error = false; + } else { + S.second->Error = true; + sol::error Err = Res; + S.second->ErrorMessage = Err.what(); + } S.second->Ready = true; } } } -TLuaEngine::StateThreadData::~StateThreadData() { - if (mThread.joinable()) { - mThread.join(); - } -} - // AHHH std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaPlugin* Caller, std::shared_ptr arg, bool Wait) { }