aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-06-11 11:36:15 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-06-11 11:36:15 +0200
commit84294d0b5462d0a05fb5d53df5a64f7ee624a726 (patch)
tree16b79e505db565c5712b442cdfb3f3bb15be7884 /src
parent17f98b33ed26338094a08d25e9fbf25b71c58f16 (diff)
downloadlanes-84294d0b5462d0a05fb5d53df5a64f7ee624a726.tar.gz
lanes-84294d0b5462d0a05fb5d53df5a64f7ee624a726.tar.bz2
lanes-84294d0b5462d0a05fb5d53df5a64f7ee624a726.zip
Fixes and improvements to lane:join()
* fix: returns nil,cancel_error when lane was cancelled * improvement: enforce non-nil first return value of lane body when using lane:join() to obtain the results
Diffstat (limited to 'src')
-rw-r--r--src/lane.cpp14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/lane.cpp b/src/lane.cpp
index 3bb98b9..eaf1c1e 100644
--- a/src/lane.cpp
+++ b/src/lane.cpp
@@ -135,7 +135,11 @@ 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 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))) {
141 raise_luaL_error(L_, "First return value must be non-nil when using join()");
142 }
139 if ( 143 if (
140 (_n > 0) && 144 (_n > 0) &&
141 (InterCopyContext{ _lane->U, DestState{ L_ }, SourceState{ _L2 }, {}, {}, {}, {}, {} }.inter_move(_n) != InterCopyResult::Success) 145 (InterCopyContext{ _lane->U, DestState{ L_ }, SourceState{ _L2 }, {}, {}, {}, {}, {} }.inter_move(_n) != InterCopyResult::Success)
@@ -161,7 +165,11 @@ static LUAG_FUNC(thread_join)
161 break; 165 break;
162 166
163 case Lane::Cancelled: 167 case Lane::Cancelled:
164 _ret = 0; 168 // we should have a single value, kCancelError, in the stack of _L2
169 LUA_ASSERT(L_, lua_gettop(_L2) == 1 && kCancelError.equals(_L2, 1));
170 lua_pushnil(L_); // L_: lane nil
171 kCancelError.pushKey(L_); // L_: lane nil cancel_error
172 _ret = 2;
165 break; 173 break;
166 174
167 default: 175 default:
@@ -207,8 +215,10 @@ static int thread_index_number(lua_State* L_)
207 lua_pushinteger(L_, 0); // L_: lane n {uv} 0 215 lua_pushinteger(L_, 0); // L_: lane n {uv} 0
208 lua_pushboolean(L_, 1); // L_: lane n {uv} 0 true 216 lua_pushboolean(L_, 1); // L_: lane n {uv} 0 true
209 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
219 lua_pushboolean(L_, 1); // L_: lane n {uv} true
210 // 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
211 lua_pushcfunction(L_, LG_thread_join); // L_: lane n {uv} join 221 lua_pushcclosure(L_, LG_thread_join, 1); // L_: lane n {uv} join
212 lua_pushvalue(L_, kSelf); // L_: lane n {uv} join lane 222 lua_pushvalue(L_, kSelf); // L_: lane n {uv} join lane
213 lua_call(L_, 1, LUA_MULTRET); // lane:join() // L_: lane n {uv} ... 223 lua_call(L_, 1, LUA_MULTRET); // lane:join() // L_: lane n {uv} ...
214 switch (_lane->status) { 224 switch (_lane->status) {