From 8e33d8a2ca89d630f8890332df7e5737fc4608c8 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Thu, 24 Oct 2024 17:36:35 +0200 Subject: Modernized some more trifles --- src/cancel.cpp | 16 ++++++++-------- src/cancel.h | 5 +++++ src/lane.cpp | 12 ++++++------ src/lane.h | 21 +++++++++++++++++---- src/state.cpp | 2 +- src/universe.cpp | 2 +- 6 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/cancel.cpp b/src/cancel.cpp index b14dca6..2d0b807 100644 --- a/src/cancel.cpp +++ b/src/cancel.cpp @@ -138,14 +138,14 @@ LUAG_FUNC(cancel_test) // ################################################################################################# -// bool[,reason] = lane_h:cancel( [mode, hookcount] [, timeout] [, wake_lane]) +// bool[,reason] = lane_h:cancel( [cancel_op, hookcount] [, timeout] [, wake_lane]) LUAG_FUNC(thread_cancel) { Lane* const _lane{ ToLane(L_, StackIndex{ 1 }) }; - CancelOp const _op{ WhichCancelOp(L_, StackIndex{ 2 }) }; // this removes the op string from the stack + CancelOp const _op{ WhichCancelOp(L_, StackIndex{ 2 }) }; // this removes the cancel_op string from the stack int _hook_count{ 0 }; - if (static_cast(_op) > static_cast(CancelOp::Soft)) { // hook is requested + if (_op > CancelOp::Soft) { // hook is requested _hook_count = static_cast(luaL_checkinteger(L_, 2)); lua_remove(L_, 2); // argument is processed, remove it if (_hook_count < 1) { @@ -167,23 +167,23 @@ LUAG_FUNC(thread_cancel) } // we wake by default in "hard" mode (remember that hook is hard too), but this can be turned off if desired - bool _wake_lane{ _op != CancelOp::Soft }; + WakeLane _wake_lane{ _op != CancelOp::Soft ? WakeLane::Yes : WakeLane::No }; if (lua_gettop(L_) >= 2) { if (!lua_isboolean(L_, 2)) { - raise_luaL_error(L_, "wake_lindas argument is not a boolean"); + raise_luaL_error(L_, "wake_lane argument is not a boolean"); } - _wake_lane = lua_toboolean(L_, 2) ? true : false; + _wake_lane = lua_toboolean(L_, 2) ? WakeLane::Yes : WakeLane::No; lua_remove(L_, 2); // argument is processed, remove it } STACK_CHECK_START_REL(L_, 0); - switch (_lane->cancel(_op, _hook_count, _until, _wake_lane)) { + switch (_lane->cancel(_op, _until, _wake_lane, _hook_count)) { default: // should never happen unless we added a case and forgot to handle it raise_luaL_error(L_, "should not get here!"); break; case CancelResult::Timeout: lua_pushboolean(L_, 0); // false - lua_pushstring(L_, "timeout"); // false "timeout" + luaG_pushstring(L_, "timeout"); // false "timeout" break; case CancelResult::Cancelled: diff --git a/src/cancel.h b/src/cancel.h index e62cf0a..6dbea99 100644 --- a/src/cancel.h +++ b/src/cancel.h @@ -32,6 +32,11 @@ enum class CancelOp MaskAll = LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT }; +inline auto operator<=>(CancelOp const a_, CancelOp const b_) +{ + return static_cast>(a_) <=> static_cast>(b_); +} + // xxh64 of string "kCancelError" generated at https://www.pelock.com/products/hash-calculator static constexpr UniqueKey kCancelError{ 0x0630345FEF912746ull, "lanes.cancel_error" }; // 'raise_cancel_error' sentinel diff --git a/src/lane.cpp b/src/lane.cpp index e88a213..9f68c91 100644 --- a/src/lane.cpp +++ b/src/lane.cpp @@ -901,7 +901,7 @@ Lane::~Lane() // ################################################################################################# -CancelResult Lane::cancel(CancelOp const op_, int const hookCount_, std::chrono::time_point const until_, bool const wakeLane_) +CancelResult Lane::cancel(CancelOp const op_, std::chrono::time_point const until_, WakeLane const wakeLane_, int const hookCount_) { // this is a hook installed with lua_sethook: can't capture anything to be convertible to lua_Hook static constexpr lua_Hook _cancelHook{ @@ -915,17 +915,17 @@ CancelResult Lane::cancel(CancelOp const op_, int const hookCount_, std::chrono: }; // remember that lanes are not transferable: only one thread can cancel a lane, so no multithreading issue here - // We can read 'lane_->status' without locks, but not wait for it (if Posix no PTHREAD_TIMEDJOIN) + // We can read status without locks, but not wait for it (if Posix no PTHREAD_TIMEDJOIN) if (status >= Lane::Done) { // say "ok" by default, including when lane is already done return CancelResult::Cancelled; } - // signal the linda the wake up the thread so that it can react to the cancel query + // signal the linda to wake up the thread so that it can react to the cancel query // let us hope we never land here with a pointer on a linda that has been destroyed... if (op_ == CancelOp::Soft) { return internalCancel(CancelRequest::Soft, until_, wakeLane_); - } else if (static_cast(op_) > static_cast(CancelOp::Soft)) { + } else if (op_ > CancelOp::Soft) { lua_sethook(L, _cancelHook, static_cast(op_), hookCount_); } @@ -934,13 +934,13 @@ CancelResult Lane::cancel(CancelOp const op_, int const hookCount_, std::chrono: // ################################################################################################# -[[nodiscard]] CancelResult Lane::internalCancel(CancelRequest const rq_, std::chrono::time_point const until_, bool const wakeLane_) +[[nodiscard]] CancelResult Lane::internalCancel(CancelRequest const rq_, std::chrono::time_point const until_, WakeLane const wakeLane_) { cancelRequest = rq_; // it's now signaled to stop if (rq_ == CancelRequest::Hard) { // lane_->thread.get_stop_source().request_stop(); } - if (wakeLane_) { // wake the thread so that execution returns from any pending linda operation if desired + if (wakeLane_ == WakeLane::Yes) { // wake the thread so that execution returns from any pending linda operation if desired std::condition_variable* const _waiting_on{ waiting_on }; if (status == Lane::Waiting && _waiting_on != nullptr) { _waiting_on->notify_all(); diff --git a/src/lane.h b/src/lane.h index a11b5f5..7f3cea0 100644 --- a/src/lane.h +++ b/src/lane.h @@ -43,6 +43,13 @@ static constexpr std::string_view kLaneMetatableName{ "Lane" }; #define kLanesLibName "lanes" #define kLanesCoreLibName kLanesLibName ".core" +// for cancel() argument +enum class WakeLane +{ + No, + Yes +}; + // NOTE: values to be changed by either thread, during execution, without locking, are marked "volatile" class Lane { @@ -136,20 +143,26 @@ class Lane // this one is for us, to make sure memory is freed by the correct allocator static void operator delete(void* p_) { static_cast(p_)->U->internalAllocator.free(p_, sizeof(Lane)); } - Lane(Universe* U_, lua_State* L_, ErrorTraceLevel errorTraceLevel_, bool asCoroutine_); ~Lane(); + Lane(Universe* U_, lua_State* L_, ErrorTraceLevel errorTraceLevel_, bool asCoroutine_); + + // rule of 5 + Lane(Lane const&) = delete; + Lane(Lane&&) = delete; + Lane& operator=(Lane const&) = delete; + Lane& operator=(Lane&&) = delete; private: - [[nodiscard]] CancelResult internalCancel(CancelRequest rq_, std::chrono::time_point until_, bool wakeLane_); + [[nodiscard]] CancelResult internalCancel(CancelRequest rq_, std::chrono::time_point until_, WakeLane wakeLane_); public: - CancelResult cancel(CancelOp op_, int hookCount_, std::chrono::time_point until_, bool wakeLane_); + CancelResult cancel(CancelOp op_, std::chrono::time_point until_, WakeLane wakeLane_, int hookCount_); void changeDebugName(StackIndex nameIdx_); void closeState() { - lua_State* _L{ S }; + lua_State* const _L{ S }; S = nullptr; L = nullptr; nresults = 0; diff --git a/src/state.cpp b/src/state.cpp index 27e595c..2e551ed 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -239,7 +239,7 @@ namespace state { lua_pop(_L, 1); } else { lua_pushcfunction(_L, luaopen_base); - lua_pushstring(_L, ""); + luaG_pushstring(_L, ""); lua_call(_L, 1, 0); } } diff --git a/src/universe.cpp b/src/universe.cpp index 7630e9c..5ee2255 100644 --- a/src/universe.cpp +++ b/src/universe.cpp @@ -362,7 +362,7 @@ bool Universe::terminateFreeRunningLanes(lua_Duration const shutdownTimeout_, Ca // if waiting on a linda, they will raise a cancel_error. // if a cancellation hook is desired, it will be installed to try to raise an error if (_lane->thread.joinable()) { - std::ignore = _lane->cancel(op_, 1, std::chrono::steady_clock::now() + 1us, true); + std::ignore = _lane->cancel(op_, std::chrono::steady_clock::now() + 1us, WakeLane::Yes, 1); } _lane = _lane->selfdestruct_next; } -- cgit v1.2.3-55-g6feb