diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-03-28 17:25:51 +0100 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-03-28 17:25:51 +0100 |
| commit | 5d365d54efef5dfd0dca814346bfee791eacab90 (patch) | |
| tree | a86b216c2474a590237154944bb2ee70fe9e2ed2 /src/cancel.cpp | |
| parent | 089f68cf6d18799028eb12cc16bbe2f8cf5e57c3 (diff) | |
| download | lanes-5d365d54efef5dfd0dca814346bfee791eacab90.tar.gz lanes-5d365d54efef5dfd0dca814346bfee791eacab90.tar.bz2 lanes-5d365d54efef5dfd0dca814346bfee791eacab90.zip | |
C++ migration: lots of noise, but it's only some minor code cleanup
Diffstat (limited to 'src/cancel.cpp')
| -rw-r--r-- | src/cancel.cpp | 117 |
1 files changed, 56 insertions, 61 deletions
diff --git a/src/cancel.cpp b/src/cancel.cpp index c0867a9..8b8977b 100644 --- a/src/cancel.cpp +++ b/src/cancel.cpp | |||
| @@ -55,9 +55,9 @@ THE SOFTWARE. | |||
| 55 | */ | 55 | */ |
| 56 | static inline CancelRequest cancel_test(lua_State* L) | 56 | static inline CancelRequest cancel_test(lua_State* L) |
| 57 | { | 57 | { |
| 58 | Lane* const s = get_lane_from_registry( L); | 58 | Lane* const lane{ get_lane_from_registry(L) }; |
| 59 | // 's' is nullptr for the original main state (and no-one can cancel that) | 59 | // 's' is nullptr for the original main state (and no-one can cancel that) |
| 60 | return s ? s->cancel_request : CancelRequest::None; | 60 | return lane ? lane->cancel_request : CancelRequest::None; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | // ################################################################################################ | 63 | // ################################################################################################ |
| @@ -111,38 +111,36 @@ static void cancel_hook(lua_State* L, [[maybe_unused]] lua_Debug* ar) | |||
| 111 | 111 | ||
| 112 | // ################################################################################################ | 112 | // ################################################################################################ |
| 113 | 113 | ||
| 114 | static CancelResult thread_cancel_soft(Lane* s, double secs_, bool wake_lindas_) | 114 | static CancelResult thread_cancel_soft(Lane* lane_, double secs_, bool wake_lindas_) |
| 115 | { | 115 | { |
| 116 | s->cancel_request = CancelRequest::Soft; // it's now signaled to stop | 116 | lane_->cancel_request = CancelRequest::Soft; // it's now signaled to stop |
| 117 | // negative timeout: we don't want to truly abort the lane, we just want it to react to cancel_test() on its own | 117 | // negative timeout: we don't want to truly abort the lane, we just want it to react to cancel_test() on its own |
| 118 | if( wake_lindas_) // wake the thread so that execution returns from any pending linda operation if desired | 118 | if (wake_lindas_) // wake the thread so that execution returns from any pending linda operation if desired |
| 119 | { | 119 | { |
| 120 | SIGNAL_T* waiting_on = s->waiting_on; | 120 | SIGNAL_T* const waiting_on{ lane_->waiting_on }; |
| 121 | if( s->status == WAITING && waiting_on != nullptr) | 121 | if (lane_->status == WAITING && waiting_on != nullptr) |
| 122 | { | 122 | { |
| 123 | SIGNAL_ALL( waiting_on); | 123 | SIGNAL_ALL( waiting_on); |
| 124 | } | 124 | } |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | return THREAD_WAIT(&s->thread, secs_, &s->done_signal, &s->done_lock, &s->status) ? CancelResult::Cancelled : CancelResult::Timeout; | 127 | return THREAD_WAIT(&lane_->thread, secs_, &lane_->done_signal, &lane_->done_lock, &lane_->status) ? CancelResult::Cancelled : CancelResult::Timeout; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | // ################################################################################################ | 130 | // ################################################################################################ |
| 131 | 131 | ||
| 132 | static CancelResult thread_cancel_hard(lua_State* L, Lane* s, double secs_, bool force_, double waitkill_timeout_) | 132 | static CancelResult thread_cancel_hard(lua_State* L, Lane* lane_, double secs_, bool force_, double waitkill_timeout_) |
| 133 | { | 133 | { |
| 134 | CancelResult result; | 134 | lane_->cancel_request = CancelRequest::Hard; // it's now signaled to stop |
| 135 | |||
| 136 | s->cancel_request = CancelRequest::Hard; // it's now signaled to stop | ||
| 137 | { | 135 | { |
| 138 | SIGNAL_T* waiting_on = s->waiting_on; | 136 | SIGNAL_T* waiting_on = lane_->waiting_on; |
| 139 | if( s->status == WAITING && waiting_on != nullptr) | 137 | if (lane_->status == WAITING && waiting_on != nullptr) |
| 140 | { | 138 | { |
| 141 | SIGNAL_ALL( waiting_on); | 139 | SIGNAL_ALL( waiting_on); |
| 142 | } | 140 | } |
| 143 | } | 141 | } |
| 144 | 142 | ||
| 145 | result = THREAD_WAIT(&s->thread, secs_, &s->done_signal, &s->done_lock, &s->status) ? CancelResult::Cancelled : CancelResult::Timeout; | 143 | CancelResult result{ THREAD_WAIT(&lane_->thread, secs_, &lane_->done_signal, &lane_->done_lock, &lane_->status) ? CancelResult::Cancelled : CancelResult::Timeout }; |
| 146 | 144 | ||
| 147 | if ((result == CancelResult::Timeout) && force_) | 145 | if ((result == CancelResult::Timeout) && force_) |
| 148 | { | 146 | { |
| @@ -151,11 +149,11 @@ static CancelResult thread_cancel_hard(lua_State* L, Lane* s, double secs_, bool | |||
| 151 | // would be use of "cancellation cleanup handlers" that at least | 149 | // would be use of "cancellation cleanup handlers" that at least |
| 152 | // PThread seems to have). | 150 | // PThread seems to have). |
| 153 | // | 151 | // |
| 154 | THREAD_KILL( &s->thread); | 152 | THREAD_KILL(&lane_->thread); |
| 155 | #if THREADAPI == THREADAPI_PTHREAD | 153 | #if THREADAPI == THREADAPI_PTHREAD |
| 156 | // pthread: make sure the thread is really stopped! | 154 | // pthread: make sure the thread is really stopped! |
| 157 | // note that this may block forever if the lane doesn't call a cancellation point and pthread doesn't honor PTHREAD_CANCEL_ASYNCHRONOUS | 155 | // note that this may block forever if the lane doesn't call a cancellation point and pthread doesn't honor PTHREAD_CANCEL_ASYNCHRONOUS |
| 158 | result = THREAD_WAIT(&s->thread, waitkill_timeout_, &s->done_signal, &s->done_lock, &s->status) ? CancelResult::Killed : CancelResult::Timeout; | 156 | result = THREAD_WAIT(&lane_->thread, waitkill_timeout_, &lane_->done_signal, &lane_->done_lock, &lane_->status) ? CancelResult::Killed : CancelResult::Timeout; |
| 159 | if (result == CancelResult::Timeout) | 157 | if (result == CancelResult::Timeout) |
| 160 | { | 158 | { |
| 161 | std::ignore = luaL_error( L, "force-killed lane failed to terminate within %f second%s", waitkill_timeout_, waitkill_timeout_ > 1 ? "s" : ""); | 159 | std::ignore = luaL_error( L, "force-killed lane failed to terminate within %f second%s", waitkill_timeout_, waitkill_timeout_ > 1 ? "s" : ""); |
| @@ -164,8 +162,8 @@ static CancelResult thread_cancel_hard(lua_State* L, Lane* s, double secs_, bool | |||
| 164 | (void) waitkill_timeout_; // unused | 162 | (void) waitkill_timeout_; // unused |
| 165 | (void) L; // unused | 163 | (void) L; // unused |
| 166 | #endif // THREADAPI == THREADAPI_PTHREAD | 164 | #endif // THREADAPI == THREADAPI_PTHREAD |
| 167 | s->mstatus = ThreadStatus::Killed; // mark 'gc' to wait for it | 165 | lane_->mstatus = ThreadStatus::Killed; // mark 'gc' to wait for it |
| 168 | // note that s->status value must remain to whatever it was at the time of the kill | 166 | // note that lane_->status value must remain to whatever it was at the time of the kill |
| 169 | // because we need to know if we can lua_close() the Lua State or not. | 167 | // because we need to know if we can lua_close() the Lua State or not. |
| 170 | result = CancelResult::Killed; | 168 | result = CancelResult::Killed; |
| 171 | } | 169 | } |
| @@ -174,16 +172,16 @@ static CancelResult thread_cancel_hard(lua_State* L, Lane* s, double secs_, bool | |||
| 174 | 172 | ||
| 175 | // ################################################################################################ | 173 | // ################################################################################################ |
| 176 | 174 | ||
| 177 | CancelResult thread_cancel(lua_State* L, Lane* s, CancelOp op_, double secs_, bool force_, double waitkill_timeout_) | 175 | CancelResult thread_cancel(lua_State* L, Lane* lane_, CancelOp op_, double secs_, bool force_, double waitkill_timeout_) |
| 178 | { | 176 | { |
| 179 | // remember that lanes are not transferable: only one thread can cancel a lane, so no multithreading issue here | 177 | // remember that lanes are not transferable: only one thread can cancel a lane, so no multithreading issue here |
| 180 | // We can read 's->status' without locks, but not wait for it (if Posix no PTHREAD_TIMEDJOIN) | 178 | // We can read 'lane_->status' without locks, but not wait for it (if Posix no PTHREAD_TIMEDJOIN) |
| 181 | if (s->mstatus == ThreadStatus::Killed) | 179 | if (lane_->mstatus == ThreadStatus::Killed) |
| 182 | { | 180 | { |
| 183 | return CancelResult::Killed; | 181 | return CancelResult::Killed; |
| 184 | } | 182 | } |
| 185 | 183 | ||
| 186 | if( s->status >= DONE) | 184 | if (lane_->status >= DONE) |
| 187 | { | 185 | { |
| 188 | // say "ok" by default, including when lane is already done | 186 | // say "ok" by default, including when lane is already done |
| 189 | return CancelResult::Cancelled; | 187 | return CancelResult::Cancelled; |
| @@ -191,12 +189,12 @@ CancelResult thread_cancel(lua_State* L, Lane* s, CancelOp op_, double secs_, bo | |||
| 191 | 189 | ||
| 192 | // signal the linda the wake up the thread so that it can react to the cancel query | 190 | // signal the linda the wake up the thread so that it can react to the cancel query |
| 193 | // let us hope we never land here with a pointer on a linda that has been destroyed... | 191 | // let us hope we never land here with a pointer on a linda that has been destroyed... |
| 194 | if( op_ == CO_Soft) | 192 | if (op_ == CO_Soft) |
| 195 | { | 193 | { |
| 196 | return thread_cancel_soft( s, secs_, force_); | 194 | return thread_cancel_soft(lane_, secs_, force_); |
| 197 | } | 195 | } |
| 198 | 196 | ||
| 199 | return thread_cancel_hard( L, s, secs_, force_, waitkill_timeout_); | 197 | return thread_cancel_hard(L, lane_, secs_, force_, waitkill_timeout_); |
| 200 | } | 198 | } |
| 201 | 199 | ||
| 202 | // ################################################################################################ | 200 | // ################################################################################################ |
| @@ -247,54 +245,51 @@ static CancelOp which_op( lua_State* L, int idx_) | |||
| 247 | // ################################################################################################ | 245 | // ################################################################################################ |
| 248 | 246 | ||
| 249 | // bool[,reason] = lane_h:cancel( [mode, hookcount] [, timeout] [, force [, forcekill_timeout]]) | 247 | // bool[,reason] = lane_h:cancel( [mode, hookcount] [, timeout] [, force [, forcekill_timeout]]) |
| 250 | LUAG_FUNC( thread_cancel) | 248 | LUAG_FUNC(thread_cancel) |
| 251 | { | 249 | { |
| 252 | Lane* s = lua_toLane( L, 1); | 250 | Lane* const lane{ lua_toLane(L, 1) }; |
| 253 | double secs = 0.0; | 251 | CancelOp const op{ which_op(L, 2) }; // this removes the op string from the stack |
| 254 | CancelOp op = which_op( L, 2); // this removes the op string from the stack | ||
| 255 | 252 | ||
| 256 | if( op > 0) // hook is requested | 253 | if (op > 0) // hook is requested |
| 257 | { | 254 | { |
| 258 | int hook_count = (int) lua_tointeger( L, 2); | 255 | int hook_count = (int) lua_tointeger(L, 2); |
| 259 | lua_remove( L, 2); // argument is processed, remove it | 256 | lua_remove(L, 2); // argument is processed, remove it |
| 260 | if( hook_count < 1) | 257 | if (hook_count < 1) |
| 261 | { | 258 | { |
| 262 | return luaL_error( L, "hook count cannot be < 1"); | 259 | return luaL_error(L, "hook count cannot be < 1"); |
| 263 | } | 260 | } |
| 264 | lua_sethook( s->L, cancel_hook, op, hook_count); | 261 | lua_sethook(lane->L, cancel_hook, op, hook_count); |
| 265 | } | 262 | } |
| 266 | 263 | ||
| 267 | if( lua_type( L, 2) == LUA_TNUMBER) | 264 | double secs{ 0.0 }; |
| 265 | if (lua_type(L, 2) == LUA_TNUMBER) | ||
| 268 | { | 266 | { |
| 269 | secs = lua_tonumber( L, 2); | 267 | secs = lua_tonumber(L, 2); |
| 270 | lua_remove( L, 2); // argument is processed, remove it | 268 | lua_remove(L, 2); // argument is processed, remove it |
| 271 | if( secs < 0.0) | 269 | if (secs < 0.0) |
| 272 | { | 270 | { |
| 273 | return luaL_error( L, "cancel timeout cannot be < 0"); | 271 | return luaL_error(L, "cancel timeout cannot be < 0"); |
| 274 | } | 272 | } |
| 275 | } | 273 | } |
| 276 | 274 | ||
| 275 | bool const force{ lua_toboolean(L, 2) ? true : false }; // false if nothing there | ||
| 276 | double const forcekill_timeout{ luaL_optnumber(L, 3, 0.0) }; | ||
| 277 | switch (thread_cancel(L, lane, op, secs, force, forcekill_timeout)) | ||
| 277 | { | 278 | { |
| 278 | bool const force = lua_toboolean( L, 2) ? true : false; // false if nothing there | 279 | case CancelResult::Timeout: |
| 279 | double forcekill_timeout = luaL_optnumber( L, 3, 0.0); | 280 | lua_pushboolean(L, 0); |
| 280 | 281 | lua_pushstring(L, "timeout"); | |
| 281 | switch( thread_cancel( L, s, op, secs, force, forcekill_timeout)) | 282 | return 2; |
| 282 | { | 283 | |
| 283 | case CancelResult::Timeout: | 284 | case CancelResult::Cancelled: |
| 284 | lua_pushboolean( L, 0); | 285 | lua_pushboolean(L, 1); |
| 285 | lua_pushstring( L, "timeout"); | 286 | push_thread_status(L, lane); |
| 286 | return 2; | 287 | return 2; |
| 287 | 288 | ||
| 288 | case CancelResult::Cancelled: | 289 | case CancelResult::Killed: |
| 289 | lua_pushboolean( L, 1); | 290 | lua_pushboolean(L, 1); |
| 290 | push_thread_status( L, s); | 291 | push_thread_status(L, lane); |
| 291 | return 2; | 292 | return 2; |
| 292 | |||
| 293 | case CancelResult::Killed: | ||
| 294 | lua_pushboolean( L, 1); | ||
| 295 | push_thread_status( L, s); | ||
| 296 | return 2; | ||
| 297 | } | ||
| 298 | } | 293 | } |
| 299 | // should never happen, only here to prevent the compiler from complaining of "not all control paths returning a value" | 294 | // should never happen, only here to prevent the compiler from complaining of "not all control paths returning a value" |
| 300 | return 0; | 295 | return 0; |
