diff options
Diffstat (limited to 'src/lane.cpp')
-rw-r--r-- | src/lane.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/lane.cpp b/src/lane.cpp index 5e018a4..15499fe 100644 --- a/src/lane.cpp +++ b/src/lane.cpp | |||
@@ -39,8 +39,10 @@ static constexpr UniqueKey kCachedError{ 0xD6F35DD608D0A203ull }; | |||
39 | static constexpr UniqueKey kCachedTostring{ 0xAB5EA23BCEA0C35Cull }; | 39 | static constexpr UniqueKey kCachedTostring{ 0xAB5EA23BCEA0C35Cull }; |
40 | 40 | ||
41 | // ################################################################################################# | 41 | // ################################################################################################# |
42 | // ################################################################################################# | ||
42 | // ######################################### Lua API ############################################### | 43 | // ######################################### Lua API ############################################### |
43 | // ################################################################################################# | 44 | // ################################################################################################# |
45 | // ################################################################################################# | ||
44 | 46 | ||
45 | static LUAG_FUNC(get_debug_threadname) | 47 | static LUAG_FUNC(get_debug_threadname) |
46 | { | 48 | { |
@@ -830,6 +832,69 @@ Lane::~Lane() | |||
830 | 832 | ||
831 | // ################################################################################################# | 833 | // ################################################################################################# |
832 | 834 | ||
835 | CancelResult Lane::cancel(CancelOp op_, int hookCount_, std::chrono::time_point<std::chrono::steady_clock> until_, bool wakeLane_) | ||
836 | { | ||
837 | auto _cancel_hook = +[](lua_State* const L_, [[maybe_unused]] lua_Debug* const ar_) { | ||
838 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "cancel_hook" << std::endl); | ||
839 | if (cancel_test(L_) != CancelRequest::None) { | ||
840 | lua_sethook(L_, nullptr, 0, 0); | ||
841 | raise_cancel_error(L_); | ||
842 | } | ||
843 | }; | ||
844 | |||
845 | // remember that lanes are not transferable: only one thread can cancel a lane, so no multithreading issue here | ||
846 | // We can read 'lane_->status' without locks, but not wait for it (if Posix no PTHREAD_TIMEDJOIN) | ||
847 | if (status >= Lane::Done) { | ||
848 | // say "ok" by default, including when lane is already done | ||
849 | return CancelResult::Cancelled; | ||
850 | } | ||
851 | |||
852 | // signal the linda the wake up the thread so that it can react to the cancel query | ||
853 | // let us hope we never land here with a pointer on a linda that has been destroyed... | ||
854 | if (op_ == CancelOp::Soft) { | ||
855 | return cancelSoft(until_, wakeLane_); | ||
856 | } else if (static_cast<int>(op_) > static_cast<int>(CancelOp::Soft)) { | ||
857 | lua_sethook(L, _cancel_hook, static_cast<int>(op_), hookCount_); | ||
858 | } | ||
859 | |||
860 | return cancelHard(until_, wakeLane_); | ||
861 | } | ||
862 | |||
863 | // ################################################################################################# | ||
864 | |||
865 | [[nodiscard]] CancelResult Lane::cancelHard(std::chrono::time_point<std::chrono::steady_clock> until_, bool wakeLane_) | ||
866 | { | ||
867 | cancelRequest = CancelRequest::Hard; // it's now signaled to stop | ||
868 | // lane_->thread.get_stop_source().request_stop(); | ||
869 | if (wakeLane_) { // wake the thread so that execution returns from any pending linda operation if desired | ||
870 | std::condition_variable* const _waiting_on{ waiting_on }; | ||
871 | if (status == Lane::Waiting && _waiting_on != nullptr) { | ||
872 | _waiting_on->notify_all(); | ||
873 | } | ||
874 | } | ||
875 | |||
876 | CancelResult result{ waitForCompletion(until_) ? CancelResult::Cancelled : CancelResult::Timeout }; | ||
877 | return result; | ||
878 | } | ||
879 | |||
880 | // ################################################################################################# | ||
881 | |||
882 | [[nodiscard]] CancelResult Lane::cancelSoft(std::chrono::time_point<std::chrono::steady_clock> until_, bool wakeLane_) | ||
883 | { | ||
884 | cancelRequest = CancelRequest::Soft; // it's now signaled to stop | ||
885 | // negative timeout: we don't want to truly abort the lane, we just want it to react to cancel_test() on its own | ||
886 | if (wakeLane_) { // wake the thread so that execution returns from any pending linda operation if desired | ||
887 | std::condition_variable* const _waiting_on{ waiting_on }; | ||
888 | if (status == Lane::Waiting && _waiting_on != nullptr) { | ||
889 | _waiting_on->notify_all(); | ||
890 | } | ||
891 | } | ||
892 | |||
893 | return waitForCompletion(until_) ? CancelResult::Cancelled : CancelResult::Timeout; | ||
894 | } | ||
895 | |||
896 | // ################################################################################################# | ||
897 | |||
833 | void Lane::changeDebugName(int const nameIdx_) | 898 | void Lane::changeDebugName(int const nameIdx_) |
834 | { | 899 | { |
835 | int const _nameIdx{ luaG_absindex(L, nameIdx_) }; | 900 | int const _nameIdx{ luaG_absindex(L, nameIdx_) }; |