aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-06-11 14:56:52 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-06-11 14:56:52 +0200
commit3589b8e04ecc7e02674547c4738a54954f6758bc (patch)
treee1020afd1ad8aec931ca63aa5b88a9539a169a9e /src
parent84294d0b5462d0a05fb5d53df5a64f7ee624a726 (diff)
downloadlanes-3589b8e04ecc7e02674547c4738a54954f6758bc.tar.gz
lanes-3589b8e04ecc7e02674547c4738a54954f6758bc.tar.bz2
lanes-3589b8e04ecc7e02674547c4738a54954f6758bc.zip
New lane:__close does a lane:join()
Diffstat (limited to 'src')
-rw-r--r--src/lane.cpp31
1 files changed, 26 insertions, 5 deletions
diff --git a/src/lane.cpp b/src/lane.cpp
index eaf1c1e..1a01a24 100644
--- a/src/lane.cpp
+++ b/src/lane.cpp
@@ -135,9 +135,9 @@ static LUAG_FUNC(thread_join)
135 switch (_lane->status) { 135 switch (_lane->status) {
136 case Lane::Done: 136 case Lane::Done:
137 { 137 {
138 bool const _calledFromIndex{ lua_toboolean(L_, lua_upvalueindex(1)) ? true : false }; // this upvalue doesn't exist when called from Lua 138 bool const _calledFromLua{ lua_toboolean(L_, lua_upvalueindex(1)) ? false : true }; // this upvalue doesn't exist when called from Lua
139 int const _n{ lua_gettop(_L2) }; // whole L2 stack 139 int const _n{ lua_gettop(_L2) }; // whole L2 stack
140 if (!_calledFromIndex && (_n == 0 || lua_isnil(_L2, 1))) { 140 if (_calledFromLua && (_n == 0 || lua_isnil(_L2, 1))) {
141 raise_luaL_error(L_, "First return value must be non-nil when using join()"); 141 raise_luaL_error(L_, "First return value must be non-nil when using join()");
142 } 142 }
143 if ( 143 if (
@@ -216,7 +216,7 @@ static int thread_index_number(lua_State* L_)
216 lua_pushboolean(L_, 1); // L_: lane n {uv} 0 true 216 lua_pushboolean(L_, 1); // L_: lane n {uv} 0 true
217 lua_rawset(L_, kUsr); // L_: lane n {uv} 217 lua_rawset(L_, kUsr); // L_: lane n {uv}
218 // tell join() that we are called from __index, to avoid raising an error if the first returned value is not nil 218 // tell join() that we are called from __index, to avoid raising an error if the first returned value is not nil
219 lua_pushboolean(L_, 1); // L_: lane n {uv} true 219 std::ignore = luaG_pushstring(L_, "[]"); // L_: lane n {uv} "[]"
220 // wait until thread has completed, transfer everything from the lane's stack to our side 220 // wait until thread has completed, transfer everything from the lane's stack to our side
221 lua_pushcclosure(L_, LG_thread_join, 1); // L_: lane n {uv} join 221 lua_pushcclosure(L_, LG_thread_join, 1); // L_: lane n {uv} join
222 lua_pushvalue(L_, kSelf); // L_: lane n {uv} join lane 222 lua_pushvalue(L_, kSelf); // L_: lane n {uv} join lane
@@ -733,6 +733,24 @@ static void lane_main(Lane* lane_)
733 733
734// ################################################################################################# 734// #################################################################################################
735 735
736#if LUA_VERSION_NUM >= 504
737static LUAG_FUNC(lane_close)
738{
739 [[maybe_unused]] Lane* const _lane{ ToLane(L_, 1) }; // L_: lane err|nil
740 // drop the error if any
741 lua_settop(L_, 1); // L_: lane
742
743 // no error if the lane body doesn't return a non-nil first value
744 std::ignore = luaG_pushstring(L_, "close"); // L_: lane "close"
745 lua_pushcclosure(L_, LG_thread_join, 1); // L_: lane join()
746 lua_insert(L_, 1); // L_: join() lane
747 lua_call(L_, 1, LUA_MULTRET); // L_: join() results
748 return lua_gettop(L_);
749}
750#endif // LUA_VERSION_NUM >= 504
751
752// #################################################################################################
753
736// = thread_gc( lane_ud ) 754// = thread_gc( lane_ud )
737// 755//
738// Cleanup for a thread userdata. If the thread is still executing, leave it 756// Cleanup for a thread userdata. If the thread is still executing, leave it
@@ -744,7 +762,7 @@ static void lane_main(Lane* lane_)
744// and the issue of canceling/killing threads at gc is not very nice, either 762// and the issue of canceling/killing threads at gc is not very nice, either
745// (would easily cause waits at gc cycle, which we don't want). 763// (would easily cause waits at gc cycle, which we don't want).
746// 764//
747[[nodiscard]] static int lane_gc(lua_State* L_) 765static LUAG_FUNC(lane_gc)
748{ 766{
749 bool _have_gc_cb{ false }; 767 bool _have_gc_cb{ false };
750 Lane* const _lane{ ToLane(L_, 1) }; // L_: ud 768 Lane* const _lane{ ToLane(L_, 1) }; // L_: ud
@@ -859,7 +877,10 @@ void Lane::changeDebugName(int const nameIdx_)
859namespace { 877namespace {
860 namespace local { 878 namespace local {
861 static struct luaL_Reg const sLaneFunctions[] = { 879 static struct luaL_Reg const sLaneFunctions[] = {
862 { "__gc", lane_gc }, 880#if LUA_VERSION_NUM >= 504
881 { "__close", LG_lane_close },
882#endif // LUA_VERSION_NUM >= 504
883 { "__gc", LG_lane_gc },
863 { "__index", LG_thread_index }, 884 { "__index", LG_thread_index },
864 { "cancel", LG_thread_cancel }, 885 { "cancel", LG_thread_cancel },
865 { "get_debug_threadname", LG_get_debug_threadname }, 886 { "get_debug_threadname", LG_get_debug_threadname },