From 3589b8e04ecc7e02674547c4738a54954f6758bc Mon Sep 17 00:00:00 2001 From: Benoit Germain <benoit.germain@ubisoft.com> Date: Tue, 11 Jun 2024 14:56:52 +0200 Subject: New lane:__close does a lane:join() --- src/lane.cpp | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'src') 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) switch (_lane->status) { case Lane::Done: { - bool const _calledFromIndex{ lua_toboolean(L_, lua_upvalueindex(1)) ? true : false }; // this upvalue doesn't exist when called from Lua + bool const _calledFromLua{ lua_toboolean(L_, lua_upvalueindex(1)) ? false : true }; // this upvalue doesn't exist when called from Lua int const _n{ lua_gettop(_L2) }; // whole L2 stack - if (!_calledFromIndex && (_n == 0 || lua_isnil(_L2, 1))) { + if (_calledFromLua && (_n == 0 || lua_isnil(_L2, 1))) { raise_luaL_error(L_, "First return value must be non-nil when using join()"); } if ( @@ -216,7 +216,7 @@ static int thread_index_number(lua_State* L_) lua_pushboolean(L_, 1); // L_: lane n {uv} 0 true lua_rawset(L_, kUsr); // L_: lane n {uv} // tell join() that we are called from __index, to avoid raising an error if the first returned value is not nil - lua_pushboolean(L_, 1); // L_: lane n {uv} true + std::ignore = luaG_pushstring(L_, "[]"); // L_: lane n {uv} "[]" // wait until thread has completed, transfer everything from the lane's stack to our side lua_pushcclosure(L_, LG_thread_join, 1); // L_: lane n {uv} join lua_pushvalue(L_, kSelf); // L_: lane n {uv} join lane @@ -733,6 +733,24 @@ static void lane_main(Lane* lane_) // ################################################################################################# +#if LUA_VERSION_NUM >= 504 +static LUAG_FUNC(lane_close) +{ + [[maybe_unused]] Lane* const _lane{ ToLane(L_, 1) }; // L_: lane err|nil + // drop the error if any + lua_settop(L_, 1); // L_: lane + + // no error if the lane body doesn't return a non-nil first value + std::ignore = luaG_pushstring(L_, "close"); // L_: lane "close" + lua_pushcclosure(L_, LG_thread_join, 1); // L_: lane join() + lua_insert(L_, 1); // L_: join() lane + lua_call(L_, 1, LUA_MULTRET); // L_: join() results + return lua_gettop(L_); +} +#endif // LUA_VERSION_NUM >= 504 + +// ################################################################################################# + // = thread_gc( lane_ud ) // // Cleanup for a thread userdata. If the thread is still executing, leave it @@ -744,7 +762,7 @@ static void lane_main(Lane* lane_) // and the issue of canceling/killing threads at gc is not very nice, either // (would easily cause waits at gc cycle, which we don't want). // -[[nodiscard]] static int lane_gc(lua_State* L_) +static LUAG_FUNC(lane_gc) { bool _have_gc_cb{ false }; Lane* const _lane{ ToLane(L_, 1) }; // L_: ud @@ -859,7 +877,10 @@ void Lane::changeDebugName(int const nameIdx_) namespace { namespace local { static struct luaL_Reg const sLaneFunctions[] = { - { "__gc", lane_gc }, +#if LUA_VERSION_NUM >= 504 + { "__close", LG_lane_close }, +#endif // LUA_VERSION_NUM >= 504 + { "__gc", LG_lane_gc }, { "__index", LG_thread_index }, { "cancel", LG_thread_cancel }, { "get_debug_threadname", LG_get_debug_threadname }, -- cgit v1.2.3-55-g6feb