diff options
Diffstat (limited to 'src/lane.cpp')
-rw-r--r-- | src/lane.cpp | 48 |
1 files changed, 31 insertions, 17 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() | ||
47 | static LUAG_FUNC(get_debug_threadname) | 48 | static 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 |
82 | static 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 |
85 | static 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); |