aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2025-06-25 14:09:19 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2025-06-25 14:09:19 +0200
commitc3b0c5f50fe7950c84f6e9c482cfe1f8883cffc5 (patch)
treef3e1a2872cbd8fbc7e5dfd9b40a75d7e91502172 /src
parent41dcaf101368350a49e756abc41f3e9c3c22ec66 (diff)
downloadlanes-c3b0c5f50fe7950c84f6e9c482cfe1f8883cffc5.tar.gz
lanes-c3b0c5f50fe7950c84f6e9c482cfe1f8883cffc5.tar.bz2
lanes-c3b0c5f50fe7950c84f6e9c482cfe1f8883cffc5.zip
Minor code refacto (Lane::waitForCompletion)
Diffstat (limited to 'src')
-rw-r--r--src/lane.cpp40
-rw-r--r--src/lane.hpp2
2 files changed, 15 insertions, 27 deletions
diff --git a/src/lane.cpp b/src/lane.cpp
index cb20930..c6ea358 100644
--- a/src/lane.cpp
+++ b/src/lane.cpp
@@ -130,7 +130,7 @@ static LUAG_FUNC(lane_join)
130 } 130 }
131 131
132 lua_settop(L_, 1); // L_: lane 132 lua_settop(L_, 1); // L_: lane
133 bool const _done{ !_lane->thread.joinable() || _lane->waitForCompletion(_until) }; 133 bool const _done{ !_lane->thread.joinable() || _lane->waitForCompletion(_until, true) };
134 134
135 if (!_done) { 135 if (!_done) {
136 lua_pushnil(L_); // L_: lane nil 136 lua_pushnil(L_); // L_: lane nil
@@ -210,23 +210,13 @@ LUAG_FUNC(lane_resume)
210 Lane* const _lane{ ToLane(L_, kIdxSelf) }; 210 Lane* const _lane{ ToLane(L_, kIdxSelf) };
211 lua_State* const _L2{ _lane->L }; 211 lua_State* const _L2{ _lane->L };
212 212
213 // wait until the lane yields 213// wait until the lane yields or returns
214 std::optional<Lane::Status> _hadToWait{}; // for debugging, if we ever raise the error just below 214 std::ignore = _lane->waitForCompletion(std::chrono::time_point<std::chrono::steady_clock>::max(), true);
215 { 215
216 std::unique_lock _guard{ _lane->doneMutex };
217 Lane::Status const _status{ _lane->status.load(std::memory_order_acquire) };
218 if (_status == Lane::Pending || _status == Lane::Running || _status == Lane::Resuming) {
219 _hadToWait = _status;
220 _lane->doneCondVar.wait(_guard, [_lane]() { return _lane->status.load(std::memory_order_acquire) == Lane::Suspended; });
221 }
222 }
223 if (_lane->status.load(std::memory_order_acquire) != Lane::Suspended) { 216 if (_lane->status.load(std::memory_order_acquire) != Lane::Suspended) {
224 if (_hadToWait) { 217 raise_luaL_error(L_, "cannot resume non-suspended coroutine Lane");
225 raise_luaL_error(L_, "INTERNAL ERROR: Lane status is %s instead of 'suspended'", _lane->threadStatusString().data());
226 } else {
227 raise_luaL_error(L_, "Can't resume a non-suspended coroutine-type Lane");
228 }
229 } 218 }
219
230 int const _nargs{ lua_gettop(L_) - 1 }; 220 int const _nargs{ lua_gettop(L_) - 1 };
231 int const _nresults{ lua_gettop(_L2) }; 221 int const _nresults{ lua_gettop(_L2) };
232 STACK_CHECK_START_ABS(L_, 1 + _nargs); // L_: self args... _L2: results... 222 STACK_CHECK_START_ABS(L_, 1 + _nargs); // L_: self args... _L2: results...
@@ -270,7 +260,7 @@ static int lane_index_number(lua_State* L_)
270 lua_pop(L_, 1); // L_: lane 260 lua_pop(L_, 1); // L_: lane
271 261
272 std::chrono::time_point<std::chrono::steady_clock> _until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; 262 std::chrono::time_point<std::chrono::steady_clock> _until{ std::chrono::time_point<std::chrono::steady_clock>::max() };
273 if (!_lane->waitForCompletion(_until)) { 263 if (!_lane->waitForCompletion(_until, true)) {
274 raise_luaL_error(L_, "INTERNAL ERROR: Failed to join"); 264 raise_luaL_error(L_, "INTERNAL ERROR: Failed to join");
275 } 265 }
276 266
@@ -983,7 +973,7 @@ CancelResult Lane::internalCancel(CancelRequest const rq_, std::chrono::time_poi
983 } 973 }
984 } 974 }
985 // wait until the lane stops working with its state (either Suspended or Done+) 975 // wait until the lane stops working with its state (either Suspended or Done+)
986 CancelResult const result{ waitForCompletion(until_) ? CancelResult::Cancelled : CancelResult::Timeout }; 976 CancelResult const result{ waitForCompletion(until_, true) ? CancelResult::Cancelled : CancelResult::Timeout };
987 return result; 977 return result;
988} 978}
989 979
@@ -1340,17 +1330,15 @@ std::string_view Lane::threadStatusString() const
1340 1330
1341// ################################################################################################# 1331// #################################################################################################
1342 1332
1343bool Lane::waitForCompletion(std::chrono::time_point<std::chrono::steady_clock> until_) 1333bool Lane::waitForCompletion(std::chrono::time_point<std::chrono::steady_clock> until_, bool const _acceptSuspended)
1344{ 1334{
1345 std::unique_lock _guard{ doneMutex }; 1335 std::unique_lock _guard{ doneMutex };
1346 // std::stop_token token{ thread.get_stop_token() }; 1336 // std::stop_token token{ thread.get_stop_token() };
1347 // return doneCondVar.wait_until(lock, token, secs_, [this](){ return status >= Lane::Done; }); 1337 // return doneCondVar.wait_until(lock, token, secs_, [this](){ return status >= Lane::Done; });
1348 1338
1349 // wait until the lane stops working with its state (either Suspended or Done+) 1339 // wait until the lane exits lane_main (which is the only place where status can become one of the 3 tested values)
1350 return doneCondVar.wait_until(_guard, until_, [this]() 1340 return doneCondVar.wait_until(_guard, until_, [this, suspended = _acceptSuspended ? Lane::Suspended : Lane::Done]() {
1351 { 1341 auto const _status{ status.load(std::memory_order_acquire) };
1352 auto const _status{ status.load(std::memory_order_acquire) }; 1342 return _status == Lane::Done || _status == Lane::Error || _status == Lane::Cancelled || _status == suspended;
1353 return _status == Lane::Suspended || _status >= Lane::Done; 1343 });
1354 }
1355 );
1356} 1344}
diff --git a/src/lane.hpp b/src/lane.hpp
index 917606f..fd46d68 100644
--- a/src/lane.hpp
+++ b/src/lane.hpp
@@ -212,7 +212,7 @@ class Lane final
212 std::string_view threadStatusString() const; 212 std::string_view threadStatusString() const;
213 // wait until the lane stops working with its state (either Suspended or Done+) 213 // wait until the lane stops working with its state (either Suspended or Done+)
214 [[nodiscard]] 214 [[nodiscard]]
215 bool waitForCompletion(std::chrono::time_point<std::chrono::steady_clock> until_); 215 bool waitForCompletion(std::chrono::time_point<std::chrono::steady_clock> until_, bool const _acceptSuspended);
216}; 216};
217 217
218// ################################################################################################# 218// #################################################################################################