Lua: Fix threading related crash

This commit is contained in:
Lion Kortlepel 2021-09-16 10:07:04 +02:00
parent 2cf368c2b0
commit 5978665ad6
No known key found for this signature in database
GPG Key ID: 4322FF2B4C71259B
4 changed files with 28 additions and 13 deletions

View File

@ -8,6 +8,11 @@ public:
IThreaded() IThreaded()
// invokes operator() on this object // invokes operator() on this object
: mThread() { } : mThread() { }
~IThreaded() noexcept {
if (mThread.joinable()) {
mThread.join();
}
}
virtual void Start() final { virtual void Start() final {
mThread = std::thread([this] { (*this)(); }); mThread = std::thread([this] { (*this)(); });

View File

@ -19,14 +19,15 @@ class TLuaPlugin;
struct TLuaResult { struct TLuaResult {
std::atomic_bool Ready; std::atomic_bool Ready;
std::atomic_bool Error;
std::string ErrorMessage;
// TODO: Add condition_variable // TODO: Add condition_variable
std::any Result;
}; };
struct TLuaPluginConfig { struct TLuaPluginConfig {
static inline const std::string FileName = "PluginConfig.toml"; static inline const std::string FileName = "PluginConfig.toml";
TLuaStateId StateId; TLuaStateId StateId;
// TODO: Execute list // TODO: Add execute list
}; };
class TLuaEngine : IThreaded { class TLuaEngine : IThreaded {
@ -49,7 +50,6 @@ private:
StateThreadData(const StateThreadData&) = delete; StateThreadData(const StateThreadData&) = delete;
[[nodiscard]] std::shared_ptr<TLuaResult> EnqueueScript(const std::shared_ptr<std::string>& Script); [[nodiscard]] std::shared_ptr<TLuaResult> EnqueueScript(const std::shared_ptr<std::string>& Script);
void operator()() override; void operator()() override;
~StateThreadData();
private: private:
std::string mName; std::string mName;

View File

@ -64,9 +64,11 @@ TConsole::TConsole() {
auto Future = mLuaEngine->EnqueueScript(mStateId, std::make_shared<std::string>(cmd)); auto Future = mLuaEngine->EnqueueScript(mStateId, std::make_shared<std::string>(cmd));
// wait for it to finish // wait for it to finish
while (!Future->Ready) { 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) { void TConsole::InitializeLuaConsole(TLuaEngine& Engine) {
Engine.EnsureStateExists(mStateId, "<>"); Engine.EnsureStateExists(mStateId, "Console");
mLuaEngine = &Engine; mLuaEngine = &Engine;
} }

View File

@ -5,6 +5,9 @@
#include <chrono> #include <chrono>
#include <random> #include <random>
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
static std::mt19937_64 MTGen64; static std::mt19937_64 MTGen64;
static TLuaStateId GenerateUniqueStateId() { static TLuaStateId GenerateUniqueStateId() {
@ -106,6 +109,9 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomi
, mShutdown(Shutdown) { , mShutdown(Shutdown) {
mState = luaL_newstate(); mState = luaL_newstate();
luaL_openlibs(mState); luaL_openlibs(mState);
sol::state_view StateView(mState);
auto LuaPrint = [](const std::string& Msg) { luaprint(Msg); };
StateView.set_function("print", LuaPrint);
Start(); Start();
} }
@ -129,18 +135,20 @@ void TLuaEngine::StateThreadData::operator()() {
mStateExecuteQueue.pop(); mStateExecuteQueue.pop();
Lock.unlock(); Lock.unlock();
beammp_debug("Running script"); 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; S.second->Ready = true;
} }
} }
} }
TLuaEngine::StateThreadData::~StateThreadData() {
if (mThread.joinable()) {
mThread.join();
}
}
// AHHH // AHHH
std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaPlugin* Caller, std::shared_ptr<TLuaArg> arg, bool Wait) { std::any TriggerLuaEvent(const std::string& Event, bool local, TLuaPlugin* Caller, std::shared_ptr<TLuaArg> arg, bool Wait) {
} }