diff options
Diffstat (limited to 'src/cancel.cpp')
-rw-r--r-- | src/cancel.cpp | 86 |
1 files changed, 33 insertions, 53 deletions
diff --git a/src/cancel.cpp b/src/cancel.cpp index 82c6def..e80c0b5 100644 --- a/src/cancel.cpp +++ b/src/cancel.cpp | |||
@@ -43,14 +43,14 @@ THE SOFTWARE. | |||
43 | // ################################################################################################# | 43 | // ################################################################################################# |
44 | 44 | ||
45 | /* | 45 | /* |
46 | * Check if the thread in question ('L') has been signalled for cancel. | 46 | * Check if the thread in question ('L') has been signalled for cancel. |
47 | * | 47 | * |
48 | * Called by cancellation hooks and/or pending Linda operations (because then | 48 | * Called by cancellation hooks and/or pending Linda operations (because then |
49 | * the check won't affect performance). | 49 | * the check won't affect performance). |
50 | * | 50 | * |
51 | * Returns CANCEL_SOFT/HARD if any locks are to be exited, and 'raise_cancel_error()' called, | 51 | * Returns CANCEL_SOFT/HARD if any locks are to be exited, and 'raise_cancel_error()' called, |
52 | * to make execution of the lane end. | 52 | * to make execution of the lane end. |
53 | */ | 53 | */ |
54 | [[nodiscard]] static inline CancelRequest cancel_test(lua_State* L_) | 54 | [[nodiscard]] static inline CancelRequest cancel_test(lua_State* L_) |
55 | { | 55 | { |
56 | Lane* const lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L_) }; | 56 | Lane* const lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L_) }; |
@@ -76,11 +76,10 @@ LUAG_FUNC(cancel_test) | |||
76 | // ################################################################################################# | 76 | // ################################################################################################# |
77 | // ################################################################################################# | 77 | // ################################################################################################# |
78 | 78 | ||
79 | [[nodiscard]] static void cancel_hook(lua_State* L_, [[maybe_unused]] lua_Debug* ar) | 79 | [[nodiscard]] static void cancel_hook(lua_State* L_, [[maybe_unused]] lua_Debug* ar_) |
80 | { | 80 | { |
81 | DEBUGSPEW_CODE(fprintf(stderr, "cancel_hook\n")); | 81 | DEBUGSPEW_CODE(fprintf(stderr, "cancel_hook\n")); |
82 | if (cancel_test(L_) != CancelRequest::None) | 82 | if (cancel_test(L_) != CancelRequest::None) { |
83 | { | ||
84 | lua_sethook(L_, nullptr, 0, 0); | 83 | lua_sethook(L_, nullptr, 0, 0); |
85 | raise_cancel_error(L_); | 84 | raise_cancel_error(L_); |
86 | } | 85 | } |
@@ -108,15 +107,14 @@ LUAG_FUNC(cancel_test) | |||
108 | 107 | ||
109 | // ################################################################################################# | 108 | // ################################################################################################# |
110 | 109 | ||
111 | [[nodiscard]] static CancelResult thread_cancel_soft(Lane* lane_, lua_Duration duration_, bool wake_lane_) | 110 | [[nodiscard]] static CancelResult thread_cancel_soft(Lane* lane_, lua_Duration duration_, bool wakeLane_) |
112 | { | 111 | { |
113 | lane_->cancel_request = CancelRequest::Soft; // it's now signaled to stop | 112 | lane_->cancel_request = CancelRequest::Soft; // it's now signaled to stop |
114 | // negative timeout: we don't want to truly abort the lane, we just want it to react to cancel_test() on its own | 113 | // negative timeout: we don't want to truly abort the lane, we just want it to react to cancel_test() on its own |
115 | if (wake_lane_) // wake the thread so that execution returns from any pending linda operation if desired | 114 | if (wakeLane_) // wake the thread so that execution returns from any pending linda operation if desired |
116 | { | 115 | { |
117 | std::condition_variable* const waiting_on{ lane_->m_waiting_on }; | 116 | std::condition_variable* const waiting_on{ lane_->m_waiting_on }; |
118 | if (lane_->m_status == Lane::Waiting && waiting_on != nullptr) | 117 | if (lane_->m_status == Lane::Waiting && waiting_on != nullptr) { |
119 | { | ||
120 | waiting_on->notify_all(); | 118 | waiting_on->notify_all(); |
121 | } | 119 | } |
122 | } | 120 | } |
@@ -126,15 +124,14 @@ LUAG_FUNC(cancel_test) | |||
126 | 124 | ||
127 | // ################################################################################################# | 125 | // ################################################################################################# |
128 | 126 | ||
129 | [[nodiscard]] static CancelResult thread_cancel_hard(Lane* lane_, lua_Duration duration_, bool wake_lane_) | 127 | [[nodiscard]] static CancelResult thread_cancel_hard(Lane* lane_, lua_Duration duration_, bool wakeLane_) |
130 | { | 128 | { |
131 | lane_->cancel_request = CancelRequest::Hard; // it's now signaled to stop | 129 | lane_->cancel_request = CancelRequest::Hard; // it's now signaled to stop |
132 | //lane_->m_thread.get_stop_source().request_stop(); | 130 | // lane_->m_thread.get_stop_source().request_stop(); |
133 | if (wake_lane_) // wake the thread so that execution returns from any pending linda operation if desired | 131 | if (wakeLane_) // wake the thread so that execution returns from any pending linda operation if desired |
134 | { | 132 | { |
135 | std::condition_variable* waiting_on = lane_->m_waiting_on; | 133 | std::condition_variable* waiting_on = lane_->m_waiting_on; |
136 | if (lane_->m_status == Lane::Waiting && waiting_on != nullptr) | 134 | if (lane_->m_status == Lane::Waiting && waiting_on != nullptr) { |
137 | { | ||
138 | waiting_on->notify_all(); | 135 | waiting_on->notify_all(); |
139 | } | 136 | } |
140 | } | 137 | } |
@@ -145,58 +142,43 @@ LUAG_FUNC(cancel_test) | |||
145 | 142 | ||
146 | // ################################################################################################# | 143 | // ################################################################################################# |
147 | 144 | ||
148 | CancelResult thread_cancel(Lane* lane_, CancelOp op_, int hook_count_, lua_Duration duration_, bool wake_lane_) | 145 | CancelResult thread_cancel(Lane* lane_, CancelOp op_, int hookCount_, lua_Duration duration_, bool wakeLane_) |
149 | { | 146 | { |
150 | // remember that lanes are not transferable: only one thread can cancel a lane, so no multithreading issue here | 147 | // remember that lanes are not transferable: only one thread can cancel a lane, so no multithreading issue here |
151 | // We can read 'lane_->status' without locks, but not wait for it (if Posix no PTHREAD_TIMEDJOIN) | 148 | // We can read 'lane_->status' without locks, but not wait for it (if Posix no PTHREAD_TIMEDJOIN) |
152 | if (lane_->m_status >= Lane::Done) | 149 | if (lane_->m_status >= Lane::Done) { |
153 | { | ||
154 | // say "ok" by default, including when lane is already done | 150 | // say "ok" by default, including when lane is already done |
155 | return CancelResult::Cancelled; | 151 | return CancelResult::Cancelled; |
156 | } | 152 | } |
157 | 153 | ||
158 | // signal the linda the wake up the thread so that it can react to the cancel query | 154 | // signal the linda the wake up the thread so that it can react to the cancel query |
159 | // let us hope we never land here with a pointer on a linda that has been destroyed... | 155 | // let us hope we never land here with a pointer on a linda that has been destroyed... |
160 | if (op_ == CancelOp::Soft) | 156 | if (op_ == CancelOp::Soft) { |
161 | { | 157 | return thread_cancel_soft(lane_, duration_, wakeLane_); |
162 | return thread_cancel_soft(lane_, duration_, wake_lane_); | 158 | } else if (static_cast<int>(op_) > static_cast<int>(CancelOp::Soft)) { |
163 | } | 159 | lua_sethook(lane_->L, cancel_hook, static_cast<int>(op_), hookCount_); |
164 | else if (static_cast<int>(op_) > static_cast<int>(CancelOp::Soft)) | ||
165 | { | ||
166 | lua_sethook(lane_->L, cancel_hook, static_cast<int>(op_), hook_count_); | ||
167 | } | 160 | } |
168 | 161 | ||
169 | return thread_cancel_hard(lane_, duration_, wake_lane_); | 162 | return thread_cancel_hard(lane_, duration_, wakeLane_); |
170 | } | 163 | } |
171 | 164 | ||
172 | // ################################################################################################# | 165 | // ################################################################################################# |
173 | // ################################################################################################# | 166 | // ################################################################################################# |
174 | 167 | ||
175 | CancelOp which_cancel_op(char const* op_string_) | 168 | CancelOp which_cancel_op(char const* opString_) |
176 | { | 169 | { |
177 | CancelOp op{ CancelOp::Invalid }; | 170 | CancelOp op{ CancelOp::Invalid }; |
178 | if (strcmp(op_string_, "hard") == 0) | 171 | if (strcmp(opString_, "hard") == 0) { |
179 | { | ||
180 | op = CancelOp::Hard; | 172 | op = CancelOp::Hard; |
181 | } | 173 | } else if (strcmp(opString_, "soft") == 0) { |
182 | else if (strcmp(op_string_, "soft") == 0) | ||
183 | { | ||
184 | op = CancelOp::Soft; | 174 | op = CancelOp::Soft; |
185 | } | 175 | } else if (strcmp(opString_, "call") == 0) { |
186 | else if (strcmp(op_string_, "call") == 0) | ||
187 | { | ||
188 | op = CancelOp::MaskCall; | 176 | op = CancelOp::MaskCall; |
189 | } | 177 | } else if (strcmp(opString_, "ret") == 0) { |
190 | else if (strcmp(op_string_, "ret") == 0) | ||
191 | { | ||
192 | op = CancelOp::MaskRet; | 178 | op = CancelOp::MaskRet; |
193 | } | 179 | } else if (strcmp(opString_, "line") == 0) { |
194 | else if (strcmp(op_string_, "line") == 0) | ||
195 | { | ||
196 | op = CancelOp::MaskLine; | 180 | op = CancelOp::MaskLine; |
197 | } | 181 | } else if (strcmp(opString_, "count") == 0) { |
198 | else if (strcmp(op_string_, "count") == 0) | ||
199 | { | ||
200 | op = CancelOp::MaskCount; | 182 | op = CancelOp::MaskCount; |
201 | } | 183 | } |
202 | return op; | 184 | return op; |
@@ -206,13 +188,11 @@ CancelOp which_cancel_op(char const* op_string_) | |||
206 | 188 | ||
207 | [[nodiscard]] static CancelOp which_cancel_op(lua_State* L_, int idx_) | 189 | [[nodiscard]] static CancelOp which_cancel_op(lua_State* L_, int idx_) |
208 | { | 190 | { |
209 | if (lua_type(L_, idx_) == LUA_TSTRING) | 191 | if (lua_type(L_, idx_) == LUA_TSTRING) { |
210 | { | ||
211 | char const* const str{ lua_tostring(L_, idx_) }; | 192 | char const* const str{ lua_tostring(L_, idx_) }; |
212 | CancelOp op{ which_cancel_op(str) }; | 193 | CancelOp op{ which_cancel_op(str) }; |
213 | lua_remove(L_, idx_); // argument is processed, remove it | 194 | lua_remove(L_, idx_); // argument is processed, remove it |
214 | if (op == CancelOp::Invalid) | 195 | if (op == CancelOp::Invalid) { |
215 | { | ||
216 | raise_luaL_error(L_, "invalid hook option %s", str); | 196 | raise_luaL_error(L_, "invalid hook option %s", str); |
217 | } | 197 | } |
218 | return op; | 198 | return op; |