aboutsummaryrefslogtreecommitdiff
path: root/src/cancel.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/cancel.cpp55
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*/
56static inline enum e_cancel_request cancel_test( lua_State* L) 56static 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//
71LUAG_FUNC( cancel_test) 71LUAG_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
81static void cancel_hook( lua_State* L, lua_Debug* ar) 81static 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
115static cancel_result thread_cancel_soft( Lane* s, double secs_, bool wake_lindas_) 114static 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
133static cancel_result thread_cancel_hard( lua_State* L, Lane* s, double secs_, bool force_, double waitkill_timeout_) 132static 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
178cancel_result thread_cancel( lua_State* L, Lane* s, CancelOp op_, double secs_, bool force_, double waitkill_timeout_) 177CancelResult 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;