aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lane.cpp48
-rw-r--r--src/lane.h14
-rw-r--r--src/tracker.cpp2
3 files changed, 46 insertions, 18 deletions
diff --git a/src/lane.cpp b/src/lane.cpp
index dd038a3..8c4062c 100644
--- a/src/lane.cpp
+++ b/src/lane.cpp
@@ -44,11 +44,12 @@ static constexpr UniqueKey kCachedTostring{ 0xAB5EA23BCEA0C35Cull };
44// ################################################################################################# 44// #################################################################################################
45// ################################################################################################# 45// #################################################################################################
46 46
47// lane:get_debug_threadname()
47static LUAG_FUNC(get_debug_threadname) 48static LUAG_FUNC(get_debug_threadname)
48{ 49{
49 Lane* const _lane{ ToLane(L_, 1) }; 50 Lane* const _lane{ ToLane(L_, 1) };
50 luaL_argcheck(L_, lua_gettop(L_) == 1, 2, "too many arguments"); 51 luaL_argcheck(L_, lua_gettop(L_) == 1, 2, "too many arguments");
51 luaG_pushstring(L_, _lane->debugName); 52 luaG_pushstring(L_, _lane->getDebugName());
52 return 1; 53 return 1;
53} 54}
54 55
@@ -78,17 +79,26 @@ static LUAG_FUNC(set_finalizer)
78 79
79// ################################################################################################# 80// #################################################################################################
80 81
82// serves both to read and write the name from the inside of the lane
81// upvalue #1 is the lane userdata 83// upvalue #1 is the lane userdata
82static LUAG_FUNC(set_debug_threadname) 84// this function is exported in a lane's state, therefore it is callable only from inside the Lane's state
85static LUAG_FUNC(lane_threadname)
83{ 86{
84 // C s_lane structure is a light userdata upvalue 87 // C s_lane structure is a light userdata upvalue
85 Lane* const _lane{ luaG_tolightuserdata<Lane>(L_, lua_upvalueindex(1)) }; 88 Lane* const _lane{ luaG_tolightuserdata<Lane>(L_, lua_upvalueindex(1)) };
86 LUA_ASSERT(L_, L_ == _lane->L); // this function is exported in a lane's state, therefore it is callable only from inside the Lane's state 89 LUA_ASSERT(L_, L_ == _lane->L); // this function is exported in a lane's state, therefore it is callable only from inside the Lane's state
87 lua_settop(L_, 1); 90 if (lua_gettop(L_) == 1) {
88 STACK_CHECK_START_REL(L_, 0); 91 lua_settop(L_, 1);
89 _lane->changeDebugName(-1); 92 STACK_CHECK_START_REL(L_, 0);
90 STACK_CHECK(L_, 0); 93 _lane->changeDebugName(-1);
91 return 0; 94 STACK_CHECK(L_, 0);
95 return 0;
96 } else if (lua_gettop(L_) == 0) {
97 luaG_pushstring(L_, _lane->getDebugName());
98 return 1;
99 } else {
100 raise_luaL_error(L_, "Wrong number of arguments");
101 }
92} 102}
93 103
94// ################################################################################################# 104// #################################################################################################
@@ -339,7 +349,7 @@ static int thread_index_number(lua_State* L_)
339 lua_replace(L_, -3); // L_: lane n error() "error" 349 lua_replace(L_, -3); // L_: lane n error() "error"
340 lua_pushinteger(L_, 3); // L_: lane n error() "error" 3 350 lua_pushinteger(L_, 3); // L_: lane n error() "error" 3
341 lua_call(L_, 2, 0); // error(tostring(errstring), 3) -> doesn't return // L_: lane n 351 lua_call(L_, 2, 0); // error(tostring(errstring), 3) -> doesn't return // L_: lane n
342 raise_luaL_error(L_, "%s: should not get here!", _lane->debugName.data()); 352 raise_luaL_error(L_, "%s: should not get here!", _lane->getDebugName().data());
343 } else { 353 } else {
344 lua_pop(L_, 1); // L_: lane n {uv} 354 lua_pop(L_, 1); // L_: lane n {uv}
345 } 355 }
@@ -416,7 +426,7 @@ static LUAG_FUNC(thread_index)
416 lua_call(L_, 1, 1); // L_: mt error() "Unknown key: " "k" 426 lua_call(L_, 1, 1); // L_: mt error() "Unknown key: " "k"
417 lua_concat(L_, 2); // L_: mt error() "Unknown key: <k>" 427 lua_concat(L_, 2); // L_: mt error() "Unknown key: <k>"
418 lua_call(L_, 1, 0); // error( "Unknown key: " .. key) -> doesn't return // L_: mt 428 lua_call(L_, 1, 0); // error( "Unknown key: " .. key) -> doesn't return // L_: mt
419 raise_luaL_error(L_, "%s[%s]: should not get here!", _lane->debugName.data(), luaG_typename(L_, kKey).data()); 429 raise_luaL_error(L_, "%s[%s]: should not get here!", _lane->getDebugName().data(), luaG_typename(L_, kKey).data());
420 } 430 }
421} 431}
422 432
@@ -716,11 +726,11 @@ static void PrepareLaneHelpers(Lane* lane_)
716 tools::PopulateFuncLookupTable(_L, -1, "set_finalizer"); 726 tools::PopulateFuncLookupTable(_L, -1, "set_finalizer");
717 lua_setglobal(_L, "set_finalizer"); 727 lua_setglobal(_L, "set_finalizer");
718 728
719 // Tie "set_debug_threadname()" to the state 729 // Tie "lane_threadname()" to the state
720 // But don't register it in the lookup database because of the Lane pointer upvalue 730 // But don't register it in the lookup database because of the Lane pointer upvalue
721 lua_pushlightuserdata(_L, lane_); 731 lua_pushlightuserdata(_L, lane_);
722 lua_pushcclosure(_L, LG_set_debug_threadname, 1); 732 lua_pushcclosure(_L, LG_lane_threadname, 1);
723 lua_setglobal(_L, "set_debug_threadname"); 733 lua_setglobal(_L, "lane_threadname");
724 734
725 // Tie "cancel_test()" to the state 735 // Tie "cancel_test()" to the state
726 lua_pushcfunction(_L, LG_cancel_test); 736 lua_pushcfunction(_L, LG_cancel_test);
@@ -860,7 +870,7 @@ static LUAG_FUNC(lane_gc)
860 lua_rawget(L_, -2); // L_: ud uservalue gc_cb|nil 870 lua_rawget(L_, -2); // L_: ud uservalue gc_cb|nil
861 if (!lua_isnil(L_, -1)) { 871 if (!lua_isnil(L_, -1)) {
862 lua_remove(L_, -2); // L_: ud gc_cb|nil 872 lua_remove(L_, -2); // L_: ud gc_cb|nil
863 luaG_pushstring(L_, _lane->debugName); // L_: ud gc_cb name 873 luaG_pushstring(L_, _lane->getDebugName()); // L_: ud gc_cb name
864 _have_gc_cb = true; 874 _have_gc_cb = true;
865 } else { 875 } else {
866 lua_pop(L_, 2); // L_: ud 876 lua_pop(L_, 2); // L_: ud
@@ -879,8 +889,6 @@ static LUAG_FUNC(lane_gc)
879 } else if (_lane->L) { 889 } else if (_lane->L) {
880 // no longer accessing the Lua VM: we can close right now 890 // no longer accessing the Lua VM: we can close right now
881 _lane->closeState(); 891 _lane->closeState();
882 // just in case, but _lane will be freed soon so...
883 _lane->debugName = std::string_view{ "<gc>" };
884 } 892 }
885 893
886 // Clean up after a (finished) thread 894 // Clean up after a (finished) thread
@@ -1003,7 +1011,10 @@ void Lane::changeDebugName(int const nameIdx_)
1003 // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global... 1011 // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global...
1004 kLaneNameRegKey.setValue(L, [idx = _nameIdx](lua_State* L_) { lua_pushvalue(L_, idx); }); // L: ... "name" ... 1012 kLaneNameRegKey.setValue(L, [idx = _nameIdx](lua_State* L_) { lua_pushvalue(L_, idx); }); // L: ... "name" ...
1005 // keep a direct pointer on the string 1013 // keep a direct pointer on the string
1006 debugName = luaG_tostring(L, _nameIdx); 1014 {
1015 std::lock_guard<std::mutex> _guard{ debugNameMutex };
1016 debugName = luaG_tostring(L, _nameIdx);
1017 }
1007 if constexpr (HAVE_DECODA_SUPPORT()) { 1018 if constexpr (HAVE_DECODA_SUPPORT()) {
1008 // to see VM name in Decoda debugger Virtual Machine window 1019 // to see VM name in Decoda debugger Virtual Machine window
1009 lua_pushvalue(L, _nameIdx); // L: ... "name" ... "name" 1020 lua_pushvalue(L, _nameIdx); // L: ... "name" ... "name"
@@ -1119,7 +1130,10 @@ void Lane::securizeDebugName(lua_State* L_)
1119 LUA_ASSERT(L_, lua_istable(L_, -1)); 1130 LUA_ASSERT(L_, lua_istable(L_, -1));
1120 // we don't care about the actual key, so long as it's unique and can't collide with anything. 1131 // we don't care about the actual key, so long as it's unique and can't collide with anything.
1121 lua_newtable(L_); // L_: lane ... {uv} {} 1132 lua_newtable(L_); // L_: lane ... {uv} {}
1122 debugName = luaG_pushstring(L_, debugName); // L_: lane ... {uv} {} name 1133 {
1134 std::lock_guard<std::mutex> _guard{ debugNameMutex };
1135 debugName = luaG_pushstring(L_, debugName); // L_: lane ... {uv} {} name
1136 }
1123 lua_rawset(L_, -3); // L_: lane ... {uv} 1137 lua_rawset(L_, -3); // L_: lane ... {uv}
1124 lua_pop(L_, 1); // L_: lane 1138 lua_pop(L_, 1); // L_: lane
1125 STACK_CHECK(L_, 0); 1139 STACK_CHECK(L_, 0);
diff --git a/src/lane.h b/src/lane.h
index 753c230..964c3c0 100644
--- a/src/lane.h
+++ b/src/lane.h
@@ -89,8 +89,13 @@ class Lane
89 // M: sub-thread OS thread 89 // M: sub-thread OS thread
90 // S: not used 90 // S: not used
91 91
92 private:
93
94 mutable std::mutex debugNameMutex;
92 std::string_view debugName{ "<unnamed>" }; 95 std::string_view debugName{ "<unnamed>" };
93 96
97 public:
98
94 Universe* const U{}; 99 Universe* const U{};
95 lua_State* S{}; // the master state of the lane 100 lua_State* S{}; // the master state of the lane
96 lua_State* L{}; // the state we run things in (either S or a lua_newthread() state if we run in coroutine mode) 101 lua_State* L{}; // the state we run things in (either S or a lua_newthread() state if we run in coroutine mode)
@@ -143,12 +148,21 @@ class Lane
143 void changeDebugName(int const nameIdx_); 148 void changeDebugName(int const nameIdx_);
144 void closeState() 149 void closeState()
145 { 150 {
151 {
152 std::lock_guard<std::mutex> _guard{ debugNameMutex };
153 debugName = std::string_view{ "<gc>" };
154 }
146 lua_State* _L{ S }; 155 lua_State* _L{ S };
147 S = nullptr; 156 S = nullptr;
148 L = nullptr; 157 L = nullptr;
149 lua_close(_L); // this collects our coroutine thread at the same time 158 lua_close(_L); // this collects our coroutine thread at the same time
150 } 159 }
151 [[nodiscard]] std::string_view errorTraceLevelString() const; 160 [[nodiscard]] std::string_view errorTraceLevelString() const;
161 [[nodiscard]] std::string_view getDebugName() const
162 {
163 std::lock_guard<std::mutex> _guard{ debugNameMutex };
164 return debugName;
165 }
152 [[nodiscard]] int pushErrorHandler() const; 166 [[nodiscard]] int pushErrorHandler() const;
153 [[nodiscard]] std::string_view pushErrorTraceLevel(lua_State* L_) const; 167 [[nodiscard]] std::string_view pushErrorTraceLevel(lua_State* L_) const;
154 static void PushMetatable(lua_State* L_); 168 static void PushMetatable(lua_State* L_);
diff --git a/src/tracker.cpp b/src/tracker.cpp
index 05902c9..16c9c55 100644
--- a/src/tracker.cpp
+++ b/src/tracker.cpp
@@ -94,7 +94,7 @@ void LaneTracker::tracking_add(Lane* lane_)
94 while (_lane != TRACKING_END) { 94 while (_lane != TRACKING_END) {
95 // insert a { name='<name>', status='<status>' } tuple, so that several lanes with the same name can't clobber each other 95 // insert a { name='<name>', status='<status>' } tuple, so that several lanes with the same name can't clobber each other
96 lua_createtable(L_, 0, 2); // L_: {} {} 96 lua_createtable(L_, 0, 2); // L_: {} {}
97 luaG_pushstring(L_, _lane->debugName); // L_: {} {} "name" 97 luaG_pushstring(L_, _lane->getDebugName()); // L_: {} {} "name"
98 lua_setfield(L_, -2, "name"); // L_: {} {} 98 lua_setfield(L_, -2, "name"); // L_: {} {}
99 _lane->pushStatusString(L_); // L_: {} {} "<status>" 99 _lane->pushStatusString(L_); // L_: {} {} "<status>"
100 lua_setfield(L_, -2, "status"); // L_: {} {} 100 lua_setfield(L_, -2, "status"); // L_: {} {}