diff options
Diffstat (limited to 'src/cancel.cpp')
-rw-r--r-- | src/cancel.cpp | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/src/cancel.cpp b/src/cancel.cpp index dd848a7..fe1623b 100644 --- a/src/cancel.cpp +++ b/src/cancel.cpp | |||
@@ -107,7 +107,7 @@ LUAG_FUNC(cancel_test) | |||
107 | 107 | ||
108 | // ################################################################################################# | 108 | // ################################################################################################# |
109 | 109 | ||
110 | [[nodiscard]] static CancelResult thread_cancel_soft(Lane* lane_, lua_Duration duration_, bool wakeLane_) | 110 | [[nodiscard]] static CancelResult thread_cancel_soft(Lane* lane_, std::chrono::time_point<std::chrono::steady_clock> until_, bool wakeLane_) |
111 | { | 111 | { |
112 | lane_->cancelRequest = CancelRequest::Soft; // it's now signaled to stop | 112 | lane_->cancelRequest = CancelRequest::Soft; // it's now signaled to stop |
113 | // 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 |
@@ -118,12 +118,12 @@ LUAG_FUNC(cancel_test) | |||
118 | } | 118 | } |
119 | } | 119 | } |
120 | 120 | ||
121 | return lane_->waitForCompletion(duration_) ? CancelResult::Cancelled : CancelResult::Timeout; | 121 | return lane_->waitForCompletion(until_) ? CancelResult::Cancelled : CancelResult::Timeout; |
122 | } | 122 | } |
123 | 123 | ||
124 | // ################################################################################################# | 124 | // ################################################################################################# |
125 | 125 | ||
126 | [[nodiscard]] static CancelResult thread_cancel_hard(Lane* lane_, lua_Duration duration_, bool wakeLane_) | 126 | [[nodiscard]] static CancelResult thread_cancel_hard(Lane* lane_, std::chrono::time_point<std::chrono::steady_clock> until_, bool wakeLane_) |
127 | { | 127 | { |
128 | lane_->cancelRequest = CancelRequest::Hard; // it's now signaled to stop | 128 | lane_->cancelRequest = CancelRequest::Hard; // it's now signaled to stop |
129 | // lane_->thread.get_stop_source().request_stop(); | 129 | // lane_->thread.get_stop_source().request_stop(); |
@@ -134,13 +134,13 @@ LUAG_FUNC(cancel_test) | |||
134 | } | 134 | } |
135 | } | 135 | } |
136 | 136 | ||
137 | CancelResult result{ lane_->waitForCompletion(duration_) ? CancelResult::Cancelled : CancelResult::Timeout }; | 137 | CancelResult result{ lane_->waitForCompletion(until_) ? CancelResult::Cancelled : CancelResult::Timeout }; |
138 | return result; | 138 | return result; |
139 | } | 139 | } |
140 | 140 | ||
141 | // ################################################################################################# | 141 | // ################################################################################################# |
142 | 142 | ||
143 | CancelResult thread_cancel(Lane* lane_, CancelOp op_, int hookCount_, lua_Duration duration_, bool wakeLane_) | 143 | CancelResult thread_cancel(Lane* lane_, CancelOp op_, int hookCount_, std::chrono::time_point<std::chrono::steady_clock> until_, bool wakeLane_) |
144 | { | 144 | { |
145 | // remember that lanes are not transferable: only one thread can cancel a lane, so no multithreading issue here | 145 | // remember that lanes are not transferable: only one thread can cancel a lane, so no multithreading issue here |
146 | // We can read 'lane_->status' without locks, but not wait for it (if Posix no PTHREAD_TIMEDJOIN) | 146 | // We can read 'lane_->status' without locks, but not wait for it (if Posix no PTHREAD_TIMEDJOIN) |
@@ -152,12 +152,12 @@ CancelResult thread_cancel(Lane* lane_, CancelOp op_, int hookCount_, lua_Durati | |||
152 | // signal the linda the wake up the thread so that it can react to the cancel query | 152 | // signal the linda the wake up the thread so that it can react to the cancel query |
153 | // let us hope we never land here with a pointer on a linda that has been destroyed... | 153 | // let us hope we never land here with a pointer on a linda that has been destroyed... |
154 | if (op_ == CancelOp::Soft) { | 154 | if (op_ == CancelOp::Soft) { |
155 | return thread_cancel_soft(lane_, duration_, wakeLane_); | 155 | return thread_cancel_soft(lane_, until_, wakeLane_); |
156 | } else if (static_cast<int>(op_) > static_cast<int>(CancelOp::Soft)) { | 156 | } else if (static_cast<int>(op_) > static_cast<int>(CancelOp::Soft)) { |
157 | lua_sethook(lane_->L, cancel_hook, static_cast<int>(op_), hookCount_); | 157 | lua_sethook(lane_->L, cancel_hook, static_cast<int>(op_), hookCount_); |
158 | } | 158 | } |
159 | 159 | ||
160 | return thread_cancel_hard(lane_, duration_, wakeLane_); | 160 | return thread_cancel_hard(lane_, until_, wakeLane_); |
161 | } | 161 | } |
162 | 162 | ||
163 | // ################################################################################################# | 163 | // ################################################################################################# |
@@ -200,7 +200,7 @@ CancelOp which_cancel_op(char const* opString_) | |||
200 | 200 | ||
201 | // ################################################################################################# | 201 | // ################################################################################################# |
202 | 202 | ||
203 | // bool[,reason] = lane_h:cancel( [mode, hookcount] [, timeout] [, wake_lindas]) | 203 | // bool[,reason] = lane_h:cancel( [mode, hookcount] [, timeout] [, wake_lane]) |
204 | LUAG_FUNC(thread_cancel) | 204 | LUAG_FUNC(thread_cancel) |
205 | { | 205 | { |
206 | Lane* const lane{ ToLane(L_, 1) }; | 206 | Lane* const lane{ ToLane(L_, 1) }; |
@@ -215,14 +215,19 @@ LUAG_FUNC(thread_cancel) | |||
215 | } | 215 | } |
216 | } | 216 | } |
217 | 217 | ||
218 | lua_Duration wait_timeout{ 0.0 }; | 218 | std::chrono::time_point<std::chrono::steady_clock> until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; |
219 | if (lua_type(L_, 2) == LUA_TNUMBER) { | 219 | if (lua_type(L_, 2) == LUA_TNUMBER) { // we don't want to use lua_isnumber() because of autocoercion |
220 | wait_timeout = lua_Duration{ lua_tonumber(L_, 2) }; | 220 | lua_Duration const duration{ lua_tonumber(L_, 2) }; |
221 | lua_remove(L_, 2); // argument is processed, remove it | 221 | if (duration.count() >= 0.0) { |
222 | if (wait_timeout.count() < 0.0) { | 222 | until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration); |
223 | raise_luaL_error(L_, "cancel timeout cannot be < 0"); | 223 | } else { |
224 | raise_luaL_argerror(L_, 2, "duration cannot be < 0"); | ||
224 | } | 225 | } |
226 | lua_remove(L_, 2); // argument is processed, remove it | ||
227 | } else if (lua_isnil(L_, 2)) { // alternate explicit "infinite timeout" by passing nil before the key | ||
228 | lua_remove(L_, 2); // argument is processed, remove it | ||
225 | } | 229 | } |
230 | |||
226 | // we wake by default in "hard" mode (remember that hook is hard too), but this can be turned off if desired | 231 | // we wake by default in "hard" mode (remember that hook is hard too), but this can be turned off if desired |
227 | bool wake_lane{ op != CancelOp::Soft }; | 232 | bool wake_lane{ op != CancelOp::Soft }; |
228 | if (lua_gettop(L_) >= 2) { | 233 | if (lua_gettop(L_) >= 2) { |
@@ -233,7 +238,7 @@ LUAG_FUNC(thread_cancel) | |||
233 | lua_remove(L_, 2); // argument is processed, remove it | 238 | lua_remove(L_, 2); // argument is processed, remove it |
234 | } | 239 | } |
235 | STACK_CHECK_START_REL(L_, 0); | 240 | STACK_CHECK_START_REL(L_, 0); |
236 | switch (thread_cancel(lane, op, hook_count, wait_timeout, wake_lane)) { | 241 | switch (thread_cancel(lane, op, hook_count, until, wake_lane)) { |
237 | default: // should never happen unless we added a case and forgot to handle it | 242 | default: // should never happen unless we added a case and forgot to handle it |
238 | LUA_ASSERT(L_, false); | 243 | LUA_ASSERT(L_, false); |
239 | break; | 244 | break; |