mirror of
https://github.com/0O0o0oOoO00/Alas.git
synced 2026-05-14 08:59:25 +08:00
fix: use std::binary_semaphore as lock for pausing lua state
This commit is contained in:
@@ -58,23 +58,18 @@ static fnset_TimeScaleT get_Time_set_timeScale() {
|
||||
}
|
||||
|
||||
LuaStatePauser::LuaStatePauser(lua_State* L) : m_L(L) {
|
||||
thiz = this;
|
||||
ensure_debug_hook();
|
||||
}
|
||||
|
||||
void LuaStatePauser::do_when_paused(const std::function<void()>& func) {
|
||||
auto _ = std::lock_guard<std::mutex>(m_atomic_pause);
|
||||
ensure_debug_hook();
|
||||
auto lk = std::mutex();
|
||||
auto lk = std::binary_semaphore(0);
|
||||
|
||||
auto fn = std::function<void()>([&]() {
|
||||
g_lua_state_operation.store(nullptr);
|
||||
func();
|
||||
lk.unlock();
|
||||
});
|
||||
lk.lock();
|
||||
g_lua_state_operation.store(&fn);
|
||||
lk.lock();
|
||||
g_pause_flag.store(&lk);
|
||||
g_lua_state_operation.store(&func);
|
||||
lk.acquire();
|
||||
SPDLOG_INFO("lua operation finished");
|
||||
}
|
||||
|
||||
void LuaStatePauser::ensure_debug_hook() {
|
||||
@@ -83,13 +78,13 @@ void LuaStatePauser::ensure_debug_hook() {
|
||||
}
|
||||
}
|
||||
|
||||
LuaStatePauser* LuaStatePauser::thiz = nullptr;
|
||||
std::atomic<std::binary_semaphore*> LuaStatePauser::g_pause_flag = nullptr;
|
||||
|
||||
std::atomic<std::function<void()>*> LuaStatePauser::g_lua_state_operation = nullptr;
|
||||
std::atomic<const std::function<void()>*> LuaStatePauser::g_lua_state_operation = nullptr;
|
||||
|
||||
void LuaStatePauser::register_debug_hook() {
|
||||
SPDLOG_INFO("registering debug hook");
|
||||
int ret = lua_sethook(m_L, LuaStatePauser::debug_hook, LUA_MASKCALL, 0);
|
||||
int ret = lua_sethook(m_L, LuaStatePauser::debug_hook, LUA_MASKCALL | LUA_MASKRET, 0);
|
||||
if (ret != 1) {
|
||||
SPDLOG_INFO("set pause hook failed with code: {}", ret);
|
||||
}
|
||||
@@ -99,15 +94,16 @@ extern bool g_is_game_loaded;
|
||||
|
||||
void LuaStatePauser::debug_hook(lua_State *L, lua_Debug *ar) {
|
||||
if (g_is_game_loaded) {
|
||||
if (!thiz) {
|
||||
return;
|
||||
}
|
||||
auto callback = g_lua_state_operation.load();
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
SPDLOG_INFO("pause triggered, operate lua state");
|
||||
(*callback)();
|
||||
auto f = g_pause_flag.load();
|
||||
g_lua_state_operation.store(nullptr);
|
||||
g_pause_flag.store(nullptr);
|
||||
f->release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <sol/variadic_args.hpp>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <semaphore>
|
||||
#include <json/json.h>
|
||||
|
||||
#include "timer.hpp"
|
||||
@@ -27,17 +28,12 @@ public:
|
||||
|
||||
void do_when_paused(const std::function<void()>& func);
|
||||
|
||||
void set();
|
||||
void wait_paused();
|
||||
void ready();
|
||||
void release();
|
||||
|
||||
private:
|
||||
void ensure_debug_hook();
|
||||
void register_debug_hook();
|
||||
|
||||
static LuaStatePauser* thiz;
|
||||
static std::atomic<std::function<void()>*> g_lua_state_operation;
|
||||
static std::atomic<std::binary_semaphore*> g_pause_flag;
|
||||
static std::atomic<const std::function<void()>*> g_lua_state_operation;
|
||||
static void debug_hook(lua_State *L, lua_Debug *ar);
|
||||
|
||||
std::mutex m_atomic_pause;
|
||||
|
||||
Reference in New Issue
Block a user