diff options
Diffstat (limited to '')
-rw-r--r-- | src/cancel.cpp | 55 |
1 files changed, 27 insertions, 28 deletions
diff --git a/src/cancel.cpp b/src/cancel.cpp index 81f25d5..73e50f5 100644 --- a/src/cancel.cpp +++ b/src/cancel.cpp | |||
@@ -53,11 +53,11 @@ THE SOFTWARE. | |||
53 | * Returns CANCEL_SOFT/HARD if any locks are to be exited, and 'cancel_error()' called, | 53 | * Returns CANCEL_SOFT/HARD if any locks are to be exited, and 'cancel_error()' called, |
54 | * to make execution of the lane end. | 54 | * to make execution of the lane end. |
55 | */ | 55 | */ |
56 | static inline enum e_cancel_request 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 s = 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 : CANCEL_NONE; | 60 | return s ? s->cancel_request : CancelRequest::None; |
61 | } | 61 | } |
62 | 62 | ||
63 | // ################################################################################################ | 63 | // ################################################################################################ |
@@ -70,19 +70,18 @@ static inline enum e_cancel_request cancel_test( lua_State* L) | |||
70 | // | 70 | // |
71 | LUAG_FUNC( cancel_test) | 71 | LUAG_FUNC( cancel_test) |
72 | { | 72 | { |
73 | enum e_cancel_request test = cancel_test( L); | 73 | CancelRequest test{ cancel_test(L) }; |
74 | lua_pushboolean( L, test != CANCEL_NONE); | 74 | lua_pushboolean(L, test != CancelRequest::None); |
75 | return 1; | 75 | return 1; |
76 | } | 76 | } |
77 | 77 | ||
78 | // ################################################################################################ | 78 | // ################################################################################################ |
79 | // ################################################################################################ | 79 | // ################################################################################################ |
80 | 80 | ||
81 | static void cancel_hook( lua_State* L, lua_Debug* ar) | 81 | static void cancel_hook( lua_State* L, [[maybe_unused]] lua_Debug* ar) |
82 | { | 82 | { |
83 | (void)ar; | ||
84 | DEBUGSPEW_CODE( fprintf( stderr, "cancel_hook\n")); | 83 | DEBUGSPEW_CODE( fprintf( stderr, "cancel_hook\n")); |
85 | if( cancel_test( L) != CANCEL_NONE) | 84 | if (cancel_test(L) != CancelRequest::None) |
86 | { | 85 | { |
87 | lua_sethook( L, nullptr, 0, 0); | 86 | lua_sethook( L, nullptr, 0, 0); |
88 | cancel_error( L); | 87 | cancel_error( L); |
@@ -112,40 +111,40 @@ static void cancel_hook( lua_State* L, lua_Debug* ar) | |||
112 | 111 | ||
113 | // ################################################################################################ | 112 | // ################################################################################################ |
114 | 113 | ||
115 | static cancel_result thread_cancel_soft( Lane* s, double secs_, bool wake_lindas_) | 114 | static CancelResult thread_cancel_soft(Lane* s, double secs_, bool wake_lindas_) |
116 | { | 115 | { |
117 | s->cancel_request = CANCEL_SOFT; // it's now signaled to stop | 116 | s->cancel_request = CancelRequest::Soft; // it's now signaled to stop |
118 | // 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 |
119 | 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 |
120 | { | 119 | { |
121 | SIGNAL_T *waiting_on = s->waiting_on; | 120 | SIGNAL_T* waiting_on = s->waiting_on; |
122 | if( s->status == WAITING && waiting_on != nullptr) | 121 | if( s->status == WAITING && waiting_on != nullptr) |
123 | { | 122 | { |
124 | SIGNAL_ALL( waiting_on); | 123 | SIGNAL_ALL( waiting_on); |
125 | } | 124 | } |
126 | } | 125 | } |
127 | 126 | ||
128 | return THREAD_WAIT( &s->thread, secs_, &s->done_signal, &s->done_lock, &s->status) ? CR_Cancelled : CR_Timeout; | 127 | return THREAD_WAIT(&s->thread, secs_, &s->done_signal, &s->done_lock, &s->status) ? CancelResult::Cancelled : CancelResult::Timeout; |
129 | } | 128 | } |
130 | 129 | ||
131 | // ################################################################################################ | 130 | // ################################################################################################ |
132 | 131 | ||
133 | static cancel_result 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* s, double secs_, bool force_, double waitkill_timeout_) |
134 | { | 133 | { |
135 | cancel_result result; | 134 | CancelResult result; |
136 | 135 | ||
137 | s->cancel_request = CANCEL_HARD; // it's now signaled to stop | 136 | s->cancel_request = CancelRequest::Hard; // it's now signaled to stop |
138 | { | 137 | { |
139 | SIGNAL_T *waiting_on = s->waiting_on; | 138 | SIGNAL_T* waiting_on = s->waiting_on; |
140 | if( s->status == WAITING && waiting_on != nullptr) | 139 | if( s->status == WAITING && waiting_on != nullptr) |
141 | { | 140 | { |
142 | SIGNAL_ALL( waiting_on); | 141 | SIGNAL_ALL( waiting_on); |
143 | } | 142 | } |
144 | } | 143 | } |
145 | 144 | ||
146 | result = THREAD_WAIT( &s->thread, secs_, &s->done_signal, &s->done_lock, &s->status) ? CR_Cancelled : CR_Timeout; | 145 | result = THREAD_WAIT(&s->thread, secs_, &s->done_signal, &s->done_lock, &s->status) ? CancelResult::Cancelled : CancelResult::Timeout; |
147 | 146 | ||
148 | if( (result == CR_Timeout) && force_) | 147 | if ((result == CancelResult::Timeout) && force_) |
149 | { | 148 | { |
150 | // Killing is asynchronous; we _will_ wait for it to be done at | 149 | // Killing is asynchronous; we _will_ wait for it to be done at |
151 | // GC, to make sure the data structure can be released (alternative | 150 | // GC, to make sure the data structure can be released (alternative |
@@ -156,8 +155,8 @@ static cancel_result thread_cancel_hard( lua_State* L, Lane* s, double secs_, bo | |||
156 | #if THREADAPI == THREADAPI_PTHREAD | 155 | #if THREADAPI == THREADAPI_PTHREAD |
157 | // pthread: make sure the thread is really stopped! | 156 | // pthread: make sure the thread is really stopped! |
158 | // note that this may block forever if the lane doesn't call a cancellation point and pthread doesn't honor PTHREAD_CANCEL_ASYNCHRONOUS | 157 | // note that this may block forever if the lane doesn't call a cancellation point and pthread doesn't honor PTHREAD_CANCEL_ASYNCHRONOUS |
159 | result = THREAD_WAIT( &s->thread, waitkill_timeout_, &s->done_signal, &s->done_lock, &s->status) ? CR_Killed : CR_Timeout; | 158 | result = THREAD_WAIT(&s->thread, waitkill_timeout_, &s->done_signal, &s->done_lock, &s->status) ? CancelResult::Killed : CancelResult::Timeout; |
160 | if( result == CR_Timeout) | 159 | if (result == CancelResult::Timeout) |
161 | { | 160 | { |
162 | (void) luaL_error( L, "force-killed lane failed to terminate within %f second%s", waitkill_timeout_, waitkill_timeout_ > 1 ? "s" : ""); | 161 | (void) luaL_error( L, "force-killed lane failed to terminate within %f second%s", waitkill_timeout_, waitkill_timeout_ > 1 ? "s" : ""); |
163 | } | 162 | } |
@@ -165,29 +164,29 @@ static cancel_result thread_cancel_hard( lua_State* L, Lane* s, double secs_, bo | |||
165 | (void) waitkill_timeout_; // unused | 164 | (void) waitkill_timeout_; // unused |
166 | (void) L; // unused | 165 | (void) L; // unused |
167 | #endif // THREADAPI == THREADAPI_PTHREAD | 166 | #endif // THREADAPI == THREADAPI_PTHREAD |
168 | s->mstatus = KILLED; // mark 'gc' to wait for it | 167 | s->mstatus = ThreadStatus::Killed; // mark 'gc' to wait for it |
169 | // note that s->status value must remain to whatever it was at the time of the kill | 168 | // note that s->status value must remain to whatever it was at the time of the kill |
170 | // because we need to know if we can lua_close() the Lua State or not. | 169 | // because we need to know if we can lua_close() the Lua State or not. |
171 | result = CR_Killed; | 170 | result = CancelResult::Killed; |
172 | } | 171 | } |
173 | return result; | 172 | return result; |
174 | } | 173 | } |
175 | 174 | ||
176 | // ################################################################################################ | 175 | // ################################################################################################ |
177 | 176 | ||
178 | cancel_result thread_cancel( lua_State* L, Lane* s, CancelOp op_, double secs_, bool force_, double waitkill_timeout_) | 177 | CancelResult thread_cancel(lua_State* L, Lane* s, CancelOp op_, double secs_, bool force_, double waitkill_timeout_) |
179 | { | 178 | { |
180 | // remember that lanes are not transferable: only one thread can cancel a lane, so no multithreading issue here | 179 | // remember that lanes are not transferable: only one thread can cancel a lane, so no multithreading issue here |
181 | // We can read 's->status' without locks, but not wait for it (if Posix no PTHREAD_TIMEDJOIN) | 180 | // We can read 's->status' without locks, but not wait for it (if Posix no PTHREAD_TIMEDJOIN) |
182 | if( s->mstatus == KILLED) | 181 | if (s->mstatus == ThreadStatus::Killed) |
183 | { | 182 | { |
184 | return CR_Killed; | 183 | return CancelResult::Killed; |
185 | } | 184 | } |
186 | 185 | ||
187 | if( s->status >= DONE) | 186 | if( s->status >= DONE) |
188 | { | 187 | { |
189 | // say "ok" by default, including when lane is already done | 188 | // say "ok" by default, including when lane is already done |
190 | return CR_Cancelled; | 189 | return CancelResult::Cancelled; |
191 | } | 190 | } |
192 | 191 | ||
193 | // signal the linda the wake up the thread so that it can react to the cancel query | 192 | // signal the linda the wake up the thread so that it can react to the cancel query |
@@ -281,17 +280,17 @@ LUAG_FUNC( thread_cancel) | |||
281 | 280 | ||
282 | switch( thread_cancel( L, s, op, secs, force, forcekill_timeout)) | 281 | switch( thread_cancel( L, s, op, secs, force, forcekill_timeout)) |
283 | { | 282 | { |
284 | case CR_Timeout: | 283 | case CancelResult::Timeout: |
285 | lua_pushboolean( L, 0); | 284 | lua_pushboolean( L, 0); |
286 | lua_pushstring( L, "timeout"); | 285 | lua_pushstring( L, "timeout"); |
287 | return 2; | 286 | return 2; |
288 | 287 | ||
289 | case CR_Cancelled: | 288 | case CancelResult::Cancelled: |
290 | lua_pushboolean( L, 1); | 289 | lua_pushboolean( L, 1); |
291 | push_thread_status( L, s); | 290 | push_thread_status( L, s); |
292 | return 2; | 291 | return 2; |
293 | 292 | ||
294 | case CR_Killed: | 293 | case CancelResult::Killed: |
295 | lua_pushboolean( L, 1); | 294 | lua_pushboolean( L, 1); |
296 | push_thread_status( L, s); | 295 | push_thread_status( L, s); |
297 | return 2; | 296 | return 2; |