diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cancel.cpp | 50 | ||||
-rw-r--r-- | src/cancel.hpp | 27 | ||||
-rw-r--r-- | src/compat.hpp | 10 | ||||
-rw-r--r-- | src/lane.cpp | 6 | ||||
-rw-r--r-- | src/universe.cpp | 6 | ||||
-rw-r--r-- | src/universe.hpp | 2 |
6 files changed, 50 insertions, 51 deletions
diff --git a/src/cancel.cpp b/src/cancel.cpp index 31656c4..73ee6f3 100644 --- a/src/cancel.cpp +++ b/src/cancel.cpp | |||
@@ -81,25 +81,24 @@ CancelRequest CheckCancelRequest(lua_State* const L_) | |||
81 | // ################################################################################################# | 81 | // ################################################################################################# |
82 | // ################################################################################################# | 82 | // ################################################################################################# |
83 | 83 | ||
84 | CancelOp WhichCancelOp(std::string_view const& opString_) | 84 | static std::optional<CancelOp> WhichCancelOp(std::string_view const& opString_) |
85 | { | 85 | { |
86 | auto _op{ CancelOp::Invalid }; | 86 | if (opString_ == "soft") { |
87 | if (opString_ == "hard") { | 87 | return std::make_optional<CancelOp>(CancelRequest::Soft, LuaHookMask::None); |
88 | _op = CancelOp::Hard; | 88 | } else if (opString_ == "hard") { |
89 | } else if (opString_ == "soft") { | 89 | return std::make_optional<CancelOp>(CancelRequest::Hard, LuaHookMask::None); |
90 | _op = CancelOp::Soft; | ||
91 | } else if (opString_== "call") { | 90 | } else if (opString_== "call") { |
92 | _op = CancelOp::MaskCall; | 91 | return std::make_optional<CancelOp>(CancelRequest::Hard, LuaHookMask::Call); |
93 | } else if (opString_ == "ret") { | 92 | } else if (opString_ == "ret") { |
94 | _op = CancelOp::MaskRet; | 93 | return std::make_optional<CancelOp>(CancelRequest::Hard, LuaHookMask::Ret); |
95 | } else if (opString_ == "line") { | 94 | } else if (opString_ == "line") { |
96 | _op = CancelOp::MaskLine; | 95 | return std::make_optional<CancelOp>(CancelRequest::Hard, LuaHookMask::Line); |
97 | } else if (opString_ == "count") { | 96 | } else if (opString_ == "count") { |
98 | _op = CancelOp::MaskCount; | 97 | return std::make_optional<CancelOp>(CancelRequest::Hard, LuaHookMask::Count); |
99 | } else if (opString_ == "all") { | 98 | } else if (opString_ == "all") { |
100 | _op = CancelOp::MaskAll; | 99 | return std::make_optional<CancelOp>(CancelRequest::Hard, LuaHookMask::All); |
101 | } | 100 | } |
102 | return _op; | 101 | return std::nullopt; |
103 | } | 102 | } |
104 | 103 | ||
105 | // ################################################################################################# | 104 | // ################################################################################################# |
@@ -109,14 +108,14 @@ static CancelOp WhichCancelOp(lua_State* const L_, StackIndex const idx_) | |||
109 | { | 108 | { |
110 | if (luaG_type(L_, idx_) == LuaType::STRING) { | 109 | if (luaG_type(L_, idx_) == LuaType::STRING) { |
111 | std::string_view const _str{ luaG_tostring(L_, idx_) }; | 110 | std::string_view const _str{ luaG_tostring(L_, idx_) }; |
112 | CancelOp _op{ WhichCancelOp(_str) }; | 111 | auto const _op{ WhichCancelOp(_str) }; |
113 | lua_remove(L_, idx_); // argument is processed, remove it | 112 | lua_remove(L_, idx_); // argument is processed, remove it |
114 | if (_op == CancelOp::Invalid) { | 113 | if (!_op.has_value()) { |
115 | raise_luaL_error(L_, "invalid hook option %s", _str.data()); | 114 | raise_luaL_error(L_, "Invalid cancel option %s", _str.data()); |
116 | } | 115 | } |
117 | return _op; | 116 | return _op.value(); |
118 | } | 117 | } |
119 | return CancelOp::Hard; | 118 | return CancelOp{ CancelRequest::Hard, LuaHookMask::None }; |
120 | } | 119 | } |
121 | 120 | ||
122 | // ################################################################################################# | 121 | // ################################################################################################# |
@@ -133,7 +132,7 @@ static CancelOp WhichCancelOp(lua_State* const L_, StackIndex const idx_) | |||
133 | // | 132 | // |
134 | LUAG_FUNC(cancel_test) | 133 | LUAG_FUNC(cancel_test) |
135 | { | 134 | { |
136 | CancelRequest _test{ CheckCancelRequest(L_) }; | 135 | CancelRequest const _test{ CheckCancelRequest(L_) }; |
137 | lua_pushboolean(L_, _test != CancelRequest::None); | 136 | lua_pushboolean(L_, _test != CancelRequest::None); |
138 | return 1; | 137 | return 1; |
139 | } | 138 | } |
@@ -146,14 +145,17 @@ LUAG_FUNC(lane_cancel) | |||
146 | Lane* const _lane{ ToLane(L_, StackIndex{ 1 }) }; | 145 | Lane* const _lane{ ToLane(L_, StackIndex{ 1 }) }; |
147 | CancelOp const _op{ WhichCancelOp(L_, StackIndex{ 2 }) }; // this removes the cancel_op string from the stack | 146 | CancelOp const _op{ WhichCancelOp(L_, StackIndex{ 2 }) }; // this removes the cancel_op string from the stack |
148 | 147 | ||
149 | int _hook_count{ 0 }; | 148 | int const _hook_count = std::invoke([_op, L_]() { |
150 | if (_op > CancelOp::Soft) { // hook is requested | 149 | if (_op.hookMask == LuaHookMask::None) { |
151 | _hook_count = static_cast<int>(luaL_checkinteger(L_, 2)); | 150 | return 0; |
151 | } | ||
152 | auto const _hook_count{ static_cast<int>(luaL_checkinteger(L_, 2)) }; | ||
152 | lua_remove(L_, 2); // argument is processed, remove it | 153 | lua_remove(L_, 2); // argument is processed, remove it |
153 | if (_hook_count < 1) { | 154 | if (_hook_count < 1) { |
154 | raise_luaL_error(L_, "hook count cannot be < 1"); | 155 | raise_luaL_error(L_, "Hook count cannot be < 1"); |
155 | } | 156 | } |
156 | } | 157 | return _hook_count; |
158 | }); | ||
157 | 159 | ||
158 | std::chrono::time_point<std::chrono::steady_clock> _until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; | 160 | std::chrono::time_point<std::chrono::steady_clock> _until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; |
159 | if (luaG_type(L_, StackIndex{ 2 }) == LuaType::NUMBER) { // we don't want to use lua_isnumber() because of autocoercion | 161 | if (luaG_type(L_, StackIndex{ 2 }) == LuaType::NUMBER) { // we don't want to use lua_isnumber() because of autocoercion |
@@ -169,7 +171,7 @@ LUAG_FUNC(lane_cancel) | |||
169 | } | 171 | } |
170 | 172 | ||
171 | // we wake by default in "hard" mode (remember that hook is hard too), but this can be turned off if desired | 173 | // we wake by default in "hard" mode (remember that hook is hard too), but this can be turned off if desired |
172 | WakeLane _wake_lane{ _op != CancelOp::Soft ? WakeLane::Yes : WakeLane::No }; | 174 | WakeLane _wake_lane{ (_op.mode == CancelRequest::Hard) ? WakeLane::Yes : WakeLane::No }; |
173 | if (lua_gettop(L_) >= 2) { | 175 | if (lua_gettop(L_) >= 2) { |
174 | if (!lua_isboolean(L_, 2)) { | 176 | if (!lua_isboolean(L_, 2)) { |
175 | raise_luaL_error(L_, "wake_lane argument is not a boolean"); | 177 | raise_luaL_error(L_, "wake_lane argument is not a boolean"); |
diff --git a/src/cancel.hpp b/src/cancel.hpp index 8f4cf07..65ccf8d 100644 --- a/src/cancel.hpp +++ b/src/cancel.hpp | |||
@@ -6,36 +6,25 @@ | |||
6 | // ################################################################################################# | 6 | // ################################################################################################# |
7 | 7 | ||
8 | // Lane cancellation request modes | 8 | // Lane cancellation request modes |
9 | enum class CancelRequest | 9 | enum class CancelRequest : uint8_t |
10 | { | 10 | { |
11 | None, // no pending cancel request | 11 | None, // no pending cancel request |
12 | Soft, // user wants the lane to cancel itself manually on cancel_test() | 12 | Soft, // user wants the lane to cancel itself manually on cancel_test() |
13 | Hard // user wants the lane to be interrupted (meaning code won't return from those functions) from inside linda:send/receive calls | 13 | Hard // user wants the lane to be interrupted (meaning code won't return from those functions) from inside linda:send/receive calls |
14 | }; | 14 | }; |
15 | 15 | ||
16 | enum class CancelResult | 16 | struct CancelOp |
17 | { | 17 | { |
18 | Timeout, | 18 | CancelRequest mode; |
19 | Cancelled | 19 | LuaHookMask hookMask; |
20 | }; | 20 | }; |
21 | 21 | ||
22 | enum class CancelOp | 22 | enum class CancelResult : uint8_t |
23 | { | 23 | { |
24 | Invalid = -2, | 24 | Timeout, |
25 | Hard = -1, | 25 | Cancelled |
26 | Soft = 0, | ||
27 | MaskCall = LUA_MASKCALL, | ||
28 | MaskRet = LUA_MASKRET, | ||
29 | MaskLine = LUA_MASKLINE, | ||
30 | MaskCount = LUA_MASKCOUNT, | ||
31 | MaskAll = LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT | ||
32 | }; | 26 | }; |
33 | 27 | ||
34 | inline auto operator<=>(CancelOp const a_, CancelOp const b_) | ||
35 | { | ||
36 | return static_cast<std::underlying_type_t<CancelOp>>(a_) <=> static_cast<std::underlying_type_t<CancelOp>>(b_); | ||
37 | } | ||
38 | |||
39 | // xxh64 of string "kCancelError" generated at https://www.pelock.com/products/hash-calculator | 28 | // xxh64 of string "kCancelError" generated at https://www.pelock.com/products/hash-calculator |
40 | static constexpr UniqueKey kCancelError{ 0x0630345FEF912746ull, "lanes.cancel_error" }; // 'raise_cancel_error' sentinel | 29 | static constexpr UniqueKey kCancelError{ 0x0630345FEF912746ull, "lanes.cancel_error" }; // 'raise_cancel_error' sentinel |
41 | 30 | ||
@@ -43,8 +32,6 @@ static constexpr UniqueKey kCancelError{ 0x0630345FEF912746ull, "lanes.cancel_er | |||
43 | 32 | ||
44 | [[nodiscard]] | 33 | [[nodiscard]] |
45 | CancelRequest CheckCancelRequest(lua_State* L_); | 34 | CancelRequest CheckCancelRequest(lua_State* L_); |
46 | [[nodiscard]] | ||
47 | CancelOp WhichCancelOp(std::string_view const& opString_); | ||
48 | 35 | ||
49 | // ################################################################################################# | 36 | // ################################################################################################# |
50 | 37 | ||
diff --git a/src/compat.hpp b/src/compat.hpp index 81f1665..80bc391 100644 --- a/src/compat.hpp +++ b/src/compat.hpp | |||
@@ -49,6 +49,16 @@ enum class LuaType | |||
49 | CDATA = 10 // LuaJIT CDATA | 49 | CDATA = 10 // LuaJIT CDATA |
50 | }; | 50 | }; |
51 | 51 | ||
52 | enum class LuaHookMask | ||
53 | { | ||
54 | None = 0, | ||
55 | Call = LUA_MASKCALL, | ||
56 | Ret = LUA_MASKRET, | ||
57 | Line = LUA_MASKLINE, | ||
58 | Count = LUA_MASKCOUNT, | ||
59 | All = LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT | ||
60 | }; | ||
61 | |||
52 | // ################################################################################################# | 62 | // ################################################################################################# |
53 | 63 | ||
54 | // add some Lua 5.3-style API when building for Lua 5.1 | 64 | // add some Lua 5.3-style API when building for Lua 5.1 |
diff --git a/src/lane.cpp b/src/lane.cpp index 923eabd..9ab574e 100644 --- a/src/lane.cpp +++ b/src/lane.cpp | |||
@@ -930,10 +930,10 @@ CancelResult Lane::cancel(CancelOp const op_, std::chrono::time_point<std::chron | |||
930 | 930 | ||
931 | // signal the linda to wake up the thread so that it can react to the cancel query | 931 | // signal the linda to wake up the thread so that it can react to the cancel query |
932 | // let us hope we never land here with a pointer on a linda that has been destroyed... | 932 | // let us hope we never land here with a pointer on a linda that has been destroyed... |
933 | if (op_ == CancelOp::Soft) { | 933 | if (op_.mode == CancelRequest::Soft) { |
934 | return internalCancel(CancelRequest::Soft, until_, wakeLane_); | 934 | return internalCancel(CancelRequest::Soft, until_, wakeLane_); |
935 | } else if (op_ > CancelOp::Soft) { | 935 | } else if (op_.hookMask != LuaHookMask::None) { |
936 | lua_sethook(L, _cancelHook, static_cast<int>(op_), hookCount_); | 936 | lua_sethook(L, _cancelHook, static_cast<int>(op_.hookMask), hookCount_); |
937 | } | 937 | } |
938 | 938 | ||
939 | return internalCancel(CancelRequest::Hard, until_, wakeLane_); | 939 | return internalCancel(CancelRequest::Hard, until_, wakeLane_); |
diff --git a/src/universe.cpp b/src/universe.cpp index eab5977..ec7d043 100644 --- a/src/universe.cpp +++ b/src/universe.cpp | |||
@@ -417,9 +417,9 @@ LUAG_FUNC(universe_gc) | |||
417 | 417 | ||
418 | // attempt to terminate all lanes with increasingly stronger cancel methods | 418 | // attempt to terminate all lanes with increasingly stronger cancel methods |
419 | bool const _allLanesTerminated{ | 419 | bool const _allLanesTerminated{ |
420 | _U->terminateFreeRunningLanes(_shutdown_timeout, CancelOp::Soft) | 420 | _U->terminateFreeRunningLanes(_shutdown_timeout, { CancelRequest::Soft, LuaHookMask::None }) |
421 | || _U->terminateFreeRunningLanes(_shutdown_timeout, CancelOp::Hard) | 421 | || _U->terminateFreeRunningLanes(_shutdown_timeout, { CancelRequest::Hard, LuaHookMask::None }) |
422 | || _U->terminateFreeRunningLanes(_shutdown_timeout, CancelOp::MaskAll) | 422 | || _U->terminateFreeRunningLanes(_shutdown_timeout, { CancelRequest::Hard, LuaHookMask::All }) |
423 | }; | 423 | }; |
424 | 424 | ||
425 | // invoke the function installed by lanes.finally() | 425 | // invoke the function installed by lanes.finally() |
diff --git a/src/universe.hpp b/src/universe.hpp index fa1e238..639dcdb 100644 --- a/src/universe.hpp +++ b/src/universe.hpp | |||
@@ -1,6 +1,7 @@ | |||
1 | #pragma once | 1 | #pragma once |
2 | 2 | ||
3 | #include "allocator.hpp" | 3 | #include "allocator.hpp" |
4 | #include "cancel.hpp" | ||
4 | #include "keeper.hpp" | 5 | #include "keeper.hpp" |
5 | #include "lanesconf.h" | 6 | #include "lanesconf.h" |
6 | #include "tracker.hpp" | 7 | #include "tracker.hpp" |
@@ -9,7 +10,6 @@ | |||
9 | // ################################################################################################# | 10 | // ################################################################################################# |
10 | 11 | ||
11 | // forwards | 12 | // forwards |
12 | enum class CancelOp; | ||
13 | struct DeepPrelude; | 13 | struct DeepPrelude; |
14 | class Lane; | 14 | class Lane; |
15 | 15 | ||