From 547fcccd9c4737b2750ef0142ef6b2a5d4b25abc Mon Sep 17 00:00:00 2001 From: 0O0o0oOoO00 <11174151+0O0o0oOoO00@users.noreply.github.com> Date: Sun, 23 Nov 2025 15:09:32 +0800 Subject: [PATCH] fix: use std::binary_semaphore as lock for pausing lua state --- blcrack/cracker/cracker.cpp | 28 ++++++++++++---------------- blcrack/cracker/cracker.hpp | 10 +++------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/blcrack/cracker/cracker.cpp b/blcrack/cracker/cracker.cpp index 411b08346..88f01e840 100644 --- a/blcrack/cracker/cracker.cpp +++ b/blcrack/cracker/cracker.cpp @@ -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& func) { auto _ = std::lock_guard(m_atomic_pause); ensure_debug_hook(); - auto lk = std::mutex(); + auto lk = std::binary_semaphore(0); - auto fn = std::function([&]() { - 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 LuaStatePauser::g_pause_flag = nullptr; -std::atomic*> LuaStatePauser::g_lua_state_operation = nullptr; +std::atomic*> 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(); } } diff --git a/blcrack/cracker/cracker.hpp b/blcrack/cracker/cracker.hpp index aaf90be16..77f0bed26 100644 --- a/blcrack/cracker/cracker.hpp +++ b/blcrack/cracker/cracker.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "timer.hpp" @@ -27,17 +28,12 @@ public: void do_when_paused(const std::function& 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*> g_lua_state_operation; + static std::atomic g_pause_flag; + static std::atomic*> g_lua_state_operation; static void debug_hook(lua_State *L, lua_Debug *ar); std::mutex m_atomic_pause;