@@ -83,12 +83,14 @@ void Debugger::Attach(lua_State* L) {
8383 states.insert (L);
8484 // execute helper code
8585 if (!helperCode.empty ()) {
86- const int t = lua_gettop (L);
87- const int r = luaL_loadstring (L, helperCode.c_str ());
88- if (r == LUA_OK) {
89- lua_pcall (L, 0 , 0 , 0 );
90- }
91- lua_settop (L, t);
86+ ExecuteOnLuaThread ([this ](lua_State* L) {
87+ const int t = lua_gettop (L);
88+ const int r = luaL_loadstring (L, helperCode.c_str ());
89+ if (r == LUA_OK) {
90+ lua_pcall (L, 0 , 0 , 0 );
91+ }
92+ lua_settop (L, t);
93+ });
9294 }
9395 // todo: just set hook when break point added.
9496 UpdateHook (L, LUA_MASKCALL | LUA_MASKLINE | LUA_MASKRET);
@@ -109,7 +111,14 @@ void Debugger::Hook(lua_State* L, lua_Debug* ar) {
109111 return ;
110112 }
111113 if (getDebugEvent (ar) == LUA_HOOKLINE) {
112- const auto bp = FindBreakPoint (L, ar);
114+ if (luaThreadExecutors.empty () == false ) {
115+ std::unique_lock<std::mutex> lock (mutexLuaThread);
116+ for (auto & executor : luaThreadExecutors) {
117+ ExecuteWithSkipHook (L, executor);
118+ }
119+ luaThreadExecutors.clear ();
120+ }
121+ const auto * bp = FindBreakPoint (L, ar);
113122 if (bp) {
114123 HandleBreak (L);
115124 return ;
@@ -123,11 +132,16 @@ void Debugger::Stop() {
123132 running = false ;
124133 skipHook = true ;
125134 blocking = false ;
126- for (auto L : states) {
135+ for (auto * L : states) {
127136 UpdateHook (L, 0 );
128137 }
129138 states.clear ();
130139 hookState = nullptr ;
140+
141+ // clear lua thread executors
142+ std::unique_lock<std::mutex> luaThreadLock (mutexLuaThread);
143+ luaThreadExecutors.clear ();
144+
131145 ExitDebugMode ();
132146}
133147
@@ -783,18 +797,23 @@ bool Debugger::MatchFileName(const std::string& chunkName, const std::string& fi
783797
784798void Debugger::RefreshLineSet () {
785799 lineSet.clear ();
786- for (auto bp : breakPoints) {
800+ for (auto * bp : breakPoints) {
787801 lineSet.insert (bp->line );
788802 }
789803}
790804
791- void Debugger::ExecuteWithSkipHook (Executor exec) {
805+ void Debugger::ExecuteWithSkipHook (lua_State* L, const Executor& exec) {
792806 const bool skip = skipHook;
793807 skipHook = true ;
794- exec ();
808+ exec (L );
795809 skipHook = skip;
796810}
797811
812+ void Debugger::ExecuteOnLuaThread (const Executor& exec) {
813+ std::unique_lock<std::mutex> lock (mutexLuaThread);
814+ luaThreadExecutors.push_back (exec);
815+ }
816+
798817void Debugger::SetExtNames (const std::vector<std::string>& names) {
799818 this ->extNames = names;
800819}
0 commit comments