diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-06-11 11:36:15 +0200 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-06-11 11:36:15 +0200 |
commit | 84294d0b5462d0a05fb5d53df5a64f7ee624a726 (patch) | |
tree | 16b79e505db565c5712b442cdfb3f3bb15be7884 /src | |
parent | 17f98b33ed26338094a08d25e9fbf25b71c58f16 (diff) | |
download | lanes-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.cpp | 14 |
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) { |