aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.cpp')
-rw-r--r--src/lanes.cpp46
1 files changed, 26 insertions, 20 deletions
diff --git a/src/lanes.cpp b/src/lanes.cpp
index 90f0f9f..d211b6a 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -169,17 +169,12 @@ Lane::Lane(Universe* U_, lua_State* L_)
169 169
170// ################################################################################################# 170// #################################################################################################
171 171
172bool Lane::waitForCompletion(lua_Duration duration_) 172bool Lane::waitForCompletion(std::chrono::time_point<std::chrono::steady_clock> until_)
173{ 173{
174 std::chrono::time_point<std::chrono::steady_clock> until{ std::chrono::time_point<std::chrono::steady_clock>::max() };
175 if (duration_.count() >= 0.0) {
176 until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration_);
177 }
178
179 std::unique_lock lock{ doneMutex }; 174 std::unique_lock lock{ doneMutex };
180 // std::stop_token token{ thread.get_stop_token() }; 175 // std::stop_token token{ thread.get_stop_token() };
181 // return doneCondVar.wait_until(lock, token, secs_, [this](){ return status >= Lane::Done; }); 176 // return doneCondVar.wait_until(lock, token, secs_, [this](){ return status >= Lane::Done; });
182 return doneCondVar.wait_until(lock, until, [this]() { return status >= Lane::Done; }); 177 return doneCondVar.wait_until(lock, until_, [this]() { return status >= Lane::Done; });
183} 178}
184 179
185// ################################################################################################# 180// #################################################################################################
@@ -1209,22 +1204,33 @@ void Lane::pushThreadStatus(lua_State* L_)
1209LUAG_FUNC(thread_join) 1204LUAG_FUNC(thread_join)
1210{ 1205{
1211 Lane* const lane{ ToLane(L_, 1) }; 1206 Lane* const lane{ ToLane(L_, 1) };
1212 lua_Duration const duration{ luaL_optnumber(L_, 2, -1.0) };
1213 lua_State* const L2{ lane->L }; 1207 lua_State* const L2{ lane->L };
1214 1208
1215 bool const done{ !lane->thread.joinable() || lane->waitForCompletion(duration) }; 1209 std::chrono::time_point<std::chrono::steady_clock> until{ std::chrono::time_point<std::chrono::steady_clock>::max() };
1210 if (lua_type(L_, 2) == LUA_TNUMBER) { // we don't want to use lua_isnumber() because of autocoercion
1211 lua_Duration const duration{ lua_tonumber(L_, 2) };
1212 if (duration.count() >= 0.0) {
1213 until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration);
1214 } else {
1215 raise_luaL_argerror(L_, 2, "duration cannot be < 0");
1216 }
1217
1218 } else if (!lua_isnoneornil(L_, 2)) { // alternate explicit "infinite timeout" by passing nil before the key
1219 raise_luaL_argerror(L_, 2, "incorrect duration type");
1220 }
1221
1222 bool const done{ !lane->thread.joinable() || lane->waitForCompletion(until) };
1223 lua_settop(L_, 1); // L_: lane
1216 if (!done || !L2) { 1224 if (!done || !L2) {
1217 STACK_GROW(L_, 2); 1225 lua_pushnil(L_); // L_: lane nil
1218 lua_pushnil(L_); // L_: lane timeout? nil 1226 lua_pushliteral(L_, "timeout"); // L_: lane nil "timeout"
1219 lua_pushliteral(L_, "timeout"); // L_: lane timeout? nil "timeout"
1220 return 2; 1227 return 2;
1221 } 1228 }
1222 1229
1223 STACK_CHECK_START_REL(L_, 0); 1230 STACK_CHECK_START_REL(L_, 0); // L_: lane
1224 // Thread is Done/Error/Cancelled; all ours now 1231 // Thread is Done/Error/Cancelled; all ours now
1225 1232
1226 int ret{ 0 }; 1233 int ret{ 0 };
1227 Universe* const U{ lane->U };
1228 // debugName is a pointer to string possibly interned in the lane's state, that no longer exists when the state is closed 1234 // debugName is a pointer to string possibly interned in the lane's state, that no longer exists when the state is closed
1229 // so store it in the userdata uservalue at a key that can't possibly collide 1235 // so store it in the userdata uservalue at a key that can't possibly collide
1230 lane->securizeDebugName(L_); 1236 lane->securizeDebugName(L_);
@@ -1234,8 +1240,8 @@ LUAG_FUNC(thread_join)
1234 int const n{ lua_gettop(L2) }; // whole L2 stack 1240 int const n{ lua_gettop(L2) }; // whole L2 stack
1235 if ( 1241 if (
1236 (n > 0) && 1242 (n > 0) &&
1237 (InterCopyContext{ U, DestState{ L_ }, SourceState{ L2 }, {}, {}, {}, {}, {} }.inter_move(n) != InterCopyResult::Success) 1243 (InterCopyContext{ lane->U, DestState{ L_ }, SourceState{ L2 }, {}, {}, {}, {}, {} }.inter_move(n) != InterCopyResult::Success)
1238 ) { // L_: lane timeout? results L2: 1244 ) { // L_: lane results L2:
1239 raise_luaL_error(L_, "tried to copy unsupported types"); 1245 raise_luaL_error(L_, "tried to copy unsupported types");
1240 } 1246 }
1241 ret = n; 1247 ret = n;
@@ -1244,12 +1250,12 @@ LUAG_FUNC(thread_join)
1244 1250
1245 case Lane::Error: 1251 case Lane::Error:
1246 { 1252 {
1247 int const n{ lua_gettop(L2) }; // L_: lane timeout? L2: "err" [trace] 1253 int const n{ lua_gettop(L2) }; // L_: lane L2: "err" [trace]
1248 STACK_GROW(L_, 3); 1254 STACK_GROW(L_, 3);
1249 lua_pushnil(L_); // L_: lane timeout? nil 1255 lua_pushnil(L_); // L_: lane nil
1250 // even when ERROR_FULL_STACK, if the error is not LUA_ERRRUN, the handler wasn't called, and we only have 1 error message on the stack ... 1256 // even when ERROR_FULL_STACK, if the error is not LUA_ERRRUN, the handler wasn't called, and we only have 1 error message on the stack ...
1251 InterCopyContext c{ U, DestState{ L_ }, SourceState{ L2 }, {}, {}, {}, {}, {} }; 1257 InterCopyContext c{ lane->U, DestState{ L_ }, SourceState{ L2 }, {}, {}, {}, {}, {} };
1252 if (c.inter_move(n) != InterCopyResult::Success) { // L_: lane timeout? nil "err" [trace] L2: 1258 if (c.inter_move(n) != InterCopyResult::Success) { // L_: lane nil "err" [trace] L2:
1253 raise_luaL_error(L_, "tried to copy unsupported types: %s", lua_tostring(L_, -n)); 1259 raise_luaL_error(L_, "tried to copy unsupported types: %s", lua_tostring(L_, -n));
1254 } 1260 }
1255 ret = 1 + n; 1261 ret = 1 + n;