diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-03-20 18:03:00 +0100 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-03-20 18:03:00 +0100 |
| commit | 0b13436b835ea96ecdf930a380e9e5c8add8cb45 (patch) | |
| tree | e286ce8d2dff20cfed685ff1d66312dcae9b5483 /src | |
| parent | 9b05d1d26d358bf836a7ad0b23c244836cb30a06 (diff) | |
| download | lanes-0b13436b835ea96ecdf930a380e9e5c8add8cb45.tar.gz lanes-0b13436b835ea96ecdf930a380e9e5c8add8cb45.tar.bz2 lanes-0b13436b835ea96ecdf930a380e9e5c8add8cb45.zip | |
C++ migration: ThreadStatus, CancelRequest and CancelResult are enum class
Diffstat (limited to 'src')
| -rw-r--r-- | src/cancel.cpp | 55 | ||||
| -rw-r--r-- | src/cancel.h | 18 | ||||
| -rw-r--r-- | src/lanes.cpp | 18 | ||||
| -rw-r--r-- | src/lanes_private.h | 12 | ||||
| -rw-r--r-- | src/linda.cpp | 34 |
5 files changed, 68 insertions, 69 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; |
diff --git a/src/cancel.h b/src/cancel.h index be4d781..9a20774 100644 --- a/src/cancel.h +++ b/src/cancel.h | |||
| @@ -20,18 +20,18 @@ struct Lane; // forward | |||
| 20 | /* | 20 | /* |
| 21 | * Lane cancellation request modes | 21 | * Lane cancellation request modes |
| 22 | */ | 22 | */ |
| 23 | enum e_cancel_request | 23 | enum class CancelRequest |
| 24 | { | 24 | { |
| 25 | CANCEL_NONE, // no pending cancel request | 25 | None, // no pending cancel request |
| 26 | CANCEL_SOFT, // user wants the lane to cancel itself manually on cancel_test() | 26 | Soft, // user wants the lane to cancel itself manually on cancel_test() |
| 27 | CANCEL_HARD // user wants the lane to be interrupted (meaning code won't return from those functions) from inside linda:send/receive calls | 27 | Hard // user wants the lane to be interrupted (meaning code won't return from those functions) from inside linda:send/receive calls |
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | enum cancel_result | 30 | enum class CancelResult |
| 31 | { | 31 | { |
| 32 | CR_Timeout, | 32 | Timeout, |
| 33 | CR_Cancelled, | 33 | Cancelled, |
| 34 | CR_Killed | 34 | Killed |
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | enum CancelOp | 37 | enum CancelOp |
| @@ -51,7 +51,7 @@ static constexpr UniqueKey CANCEL_ERROR{ 0xe97d41626cc97577ull }; // 'cancel_err | |||
| 51 | // crc64/we of string "CANCEL_TEST_KEY" generated at http://www.nitrxgen.net/hashgen/ | 51 | // crc64/we of string "CANCEL_TEST_KEY" generated at http://www.nitrxgen.net/hashgen/ |
| 52 | static constexpr UniqueKey CANCEL_TEST_KEY{ 0xe66f5960c57d133aull }; // used as registry key | 52 | static constexpr UniqueKey CANCEL_TEST_KEY{ 0xe66f5960c57d133aull }; // used as registry key |
| 53 | 53 | ||
| 54 | cancel_result thread_cancel( lua_State* L, Lane* s, CancelOp op_, double secs_, bool force_, double waitkill_timeout_); | 54 | CancelResult thread_cancel(lua_State* L, Lane* s, CancelOp op_, double secs_, bool force_, double waitkill_timeout_); |
| 55 | 55 | ||
| 56 | static inline int cancel_error( lua_State* L) | 56 | static inline int cancel_error( lua_State* L) |
| 57 | { | 57 | { |
diff --git a/src/lanes.cpp b/src/lanes.cpp index e3f53c0..acfa0dc 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp | |||
| @@ -456,7 +456,7 @@ static int selfdestruct_gc( lua_State* L) | |||
| 456 | while( s != SELFDESTRUCT_END) | 456 | while( s != SELFDESTRUCT_END) |
| 457 | { | 457 | { |
| 458 | // attempt a regular unforced hard cancel with a small timeout | 458 | // attempt a regular unforced hard cancel with a small timeout |
| 459 | bool const cancelled = THREAD_ISNULL( s->thread) || thread_cancel( L, s, CO_Hard, 0.0001, false, 0.0); | 459 | bool const cancelled = THREAD_ISNULL( s->thread) || thread_cancel( L, s, CO_Hard, 0.0001, false, 0.0) != CancelResult::Timeout; |
| 460 | // if we failed, and we know the thread is waiting on a linda | 460 | // if we failed, and we know the thread is waiting on a linda |
| 461 | if( cancelled == false && s->status == WAITING && s->waiting_on != nullptr) | 461 | if( cancelled == false && s->status == WAITING && s->waiting_on != nullptr) |
| 462 | { | 462 | { |
| @@ -501,7 +501,7 @@ static int selfdestruct_gc( lua_State* L) | |||
| 501 | Lane* s = U->selfdestruct_first; | 501 | Lane* s = U->selfdestruct_first; |
| 502 | while( s != SELFDESTRUCT_END) | 502 | while( s != SELFDESTRUCT_END) |
| 503 | { | 503 | { |
| 504 | if( s->cancel_request == CANCEL_HARD) | 504 | if (s->cancel_request == CancelRequest::Hard) |
| 505 | ++ n; | 505 | ++ n; |
| 506 | s = s->selfdestruct_next; | 506 | s = s->selfdestruct_next; |
| 507 | } | 507 | } |
| @@ -1239,13 +1239,13 @@ LUAG_FUNC( lane_new) | |||
| 1239 | s->status = PENDING; | 1239 | s->status = PENDING; |
| 1240 | s->waiting_on = nullptr; | 1240 | s->waiting_on = nullptr; |
| 1241 | s->debug_name = "<unnamed>"; | 1241 | s->debug_name = "<unnamed>"; |
| 1242 | s->cancel_request = CANCEL_NONE; | 1242 | s->cancel_request = CancelRequest::None; |
| 1243 | 1243 | ||
| 1244 | #if THREADWAIT_METHOD == THREADWAIT_CONDVAR | 1244 | #if THREADWAIT_METHOD == THREADWAIT_CONDVAR |
| 1245 | MUTEX_INIT( &s->done_lock); | 1245 | MUTEX_INIT( &s->done_lock); |
| 1246 | SIGNAL_INIT( &s->done_signal); | 1246 | SIGNAL_INIT( &s->done_signal); |
| 1247 | #endif // THREADWAIT_METHOD == THREADWAIT_CONDVAR | 1247 | #endif // THREADWAIT_METHOD == THREADWAIT_CONDVAR |
| 1248 | s->mstatus = NORMAL; | 1248 | s->mstatus = ThreadStatus::Normal; |
| 1249 | s->selfdestruct_next = nullptr; | 1249 | s->selfdestruct_next = nullptr; |
| 1250 | #if HAVE_LANE_TRACKING() | 1250 | #if HAVE_LANE_TRACKING() |
| 1251 | s->tracking_next = nullptr; | 1251 | s->tracking_next = nullptr; |
| @@ -1322,8 +1322,8 @@ LUAG_FUNC( thread_gc) | |||
| 1322 | } | 1322 | } |
| 1323 | 1323 | ||
| 1324 | // We can read 's->status' without locks, but not wait for it | 1324 | // We can read 's->status' without locks, but not wait for it |
| 1325 | // test KILLED state first, as it doesn't need to enter the selfdestruct chain | 1325 | // test Killed state first, as it doesn't need to enter the selfdestruct chain |
| 1326 | if( s->mstatus == KILLED) | 1326 | if (s->mstatus == ThreadStatus::Killed) |
| 1327 | { | 1327 | { |
| 1328 | // Make sure a kill has proceeded, before cleaning up the data structure. | 1328 | // Make sure a kill has proceeded, before cleaning up the data structure. |
| 1329 | // | 1329 | // |
| @@ -1392,7 +1392,7 @@ static char const * thread_status_string( Lane* s) | |||
| 1392 | { | 1392 | { |
| 1393 | enum e_status st = s->status; // read just once (volatile) | 1393 | enum e_status st = s->status; // read just once (volatile) |
| 1394 | char const* str = | 1394 | char const* str = |
| 1395 | (s->mstatus == KILLED) ? "killed" : // new to v3.3.0! | 1395 | (s->mstatus == ThreadStatus::Killed) ? "killed" : // new to v3.3.0! |
| 1396 | (st == PENDING) ? "pending" : | 1396 | (st == PENDING) ? "pending" : |
| 1397 | (st == RUNNING) ? "running" : // like in 'co.status()' | 1397 | (st == RUNNING) ? "running" : // like in 'co.status()' |
| 1398 | (st == WAITING) ? "waiting" : | 1398 | (st == WAITING) ? "waiting" : |
| @@ -1438,7 +1438,7 @@ LUAG_FUNC( thread_join) | |||
| 1438 | STACK_CHECK( L, 0); | 1438 | STACK_CHECK( L, 0); |
| 1439 | // Thread is DONE/ERROR_ST/CANCELLED; all ours now | 1439 | // Thread is DONE/ERROR_ST/CANCELLED; all ours now |
| 1440 | 1440 | ||
| 1441 | if( s->mstatus == KILLED) // OS thread was killed if thread_cancel was forced | 1441 | if (s->mstatus == ThreadStatus::Killed) // OS thread was killed if thread_cancel was forced |
| 1442 | { | 1442 | { |
| 1443 | // in that case, even if the thread was killed while DONE/ERROR_ST/CANCELLED, ignore regular return values | 1443 | // in that case, even if the thread was killed while DONE/ERROR_ST/CANCELLED, ignore regular return values |
| 1444 | STACK_GROW( L, 2); | 1444 | STACK_GROW( L, 2); |
| @@ -1548,7 +1548,7 @@ LUAG_FUNC( thread_index) | |||
| 1548 | switch( s->status) | 1548 | switch( s->status) |
| 1549 | { | 1549 | { |
| 1550 | default: | 1550 | default: |
| 1551 | if( s->mstatus != KILLED) | 1551 | if (s->mstatus != ThreadStatus::Killed) |
| 1552 | { | 1552 | { |
| 1553 | // this is an internal error, we probably never get here | 1553 | // this is an internal error, we probably never get here |
| 1554 | lua_settop( L, 0); | 1554 | lua_settop( L, 0); |
diff --git a/src/lanes_private.h b/src/lanes_private.h index cd0c388..75607b9 100644 --- a/src/lanes_private.h +++ b/src/lanes_private.h | |||
| @@ -4,10 +4,10 @@ | |||
| 4 | #include "cancel.h" | 4 | #include "cancel.h" |
| 5 | #include "universe.h" | 5 | #include "universe.h" |
| 6 | 6 | ||
| 7 | enum ThreadStatus | 7 | enum class ThreadStatus |
| 8 | { | 8 | { |
| 9 | NORMAL, // normal master side state | 9 | Normal, // normal master side state |
| 10 | KILLED // issued an OS kill | 10 | Killed // issued an OS kill |
| 11 | }; | 11 | }; |
| 12 | 12 | ||
| 13 | // NOTE: values to be changed by either thread, during execution, without | 13 | // NOTE: values to be changed by either thread, during execution, without |
| @@ -37,7 +37,7 @@ struct Lane | |||
| 37 | // | 37 | // |
| 38 | // When status is WAITING, points on the linda's signal the thread waits on, else nullptr | 38 | // When status is WAITING, points on the linda's signal the thread waits on, else nullptr |
| 39 | 39 | ||
| 40 | volatile enum e_cancel_request cancel_request; | 40 | volatile CancelRequest cancel_request; |
| 41 | // | 41 | // |
| 42 | // M: sets to false, flags true for cancel request | 42 | // M: sets to false, flags true for cancel request |
| 43 | // S: reads to see if cancel is requested | 43 | // S: reads to see if cancel is requested |
| @@ -54,9 +54,9 @@ struct Lane | |||
| 54 | // lane status changes to DONE/ERROR_ST/CANCELLED. | 54 | // lane status changes to DONE/ERROR_ST/CANCELLED. |
| 55 | #endif // THREADWAIT_METHOD == THREADWAIT_CONDVAR | 55 | #endif // THREADWAIT_METHOD == THREADWAIT_CONDVAR |
| 56 | 56 | ||
| 57 | volatile enum ThreadStatus mstatus; | 57 | volatile ThreadStatus mstatus; |
| 58 | // | 58 | // |
| 59 | // M: sets to NORMAL, if issued a kill changes to KILLED | 59 | // M: sets to Normal, if issued a kill changes to Killed |
| 60 | // S: not used | 60 | // S: not used |
| 61 | 61 | ||
| 62 | Lane* volatile selfdestruct_next; | 62 | Lane* volatile selfdestruct_next; |
diff --git a/src/linda.cpp b/src/linda.cpp index 10ee08b..ff3d543 100644 --- a/src/linda.cpp +++ b/src/linda.cpp | |||
| @@ -53,7 +53,7 @@ struct s_Linda | |||
| 53 | SIGNAL_T write_happened; | 53 | SIGNAL_T write_happened; |
| 54 | Universe* U; // the universe this linda belongs to | 54 | Universe* U; // the universe this linda belongs to |
| 55 | ptrdiff_t group; // a group to control keeper allocation between lindas | 55 | ptrdiff_t group; // a group to control keeper allocation between lindas |
| 56 | enum e_cancel_request simulate_cancel; | 56 | CancelRequest simulate_cancel; |
| 57 | char name[1]; | 57 | char name[1]; |
| 58 | }; | 58 | }; |
| 59 | #define LINDA_KEEPER_HASHSEED( linda) (linda->group ? linda->group : (ptrdiff_t)linda) | 59 | #define LINDA_KEEPER_HASHSEED( linda) (linda->group ? linda->group : (ptrdiff_t)linda) |
| @@ -122,7 +122,7 @@ LUAG_FUNC( linda_send) | |||
| 122 | { | 122 | { |
| 123 | struct s_Linda* linda = lua_toLinda( L, 1); | 123 | struct s_Linda* linda = lua_toLinda( L, 1); |
| 124 | bool ret{ false }; | 124 | bool ret{ false }; |
| 125 | enum e_cancel_request cancel = CANCEL_NONE; | 125 | CancelRequest cancel{ CancelRequest::None }; |
| 126 | int pushed; | 126 | int pushed; |
| 127 | time_d timeout = -1.0; | 127 | time_d timeout = -1.0; |
| 128 | int key_i = 2; // index of first key, if timeout not there | 128 | int key_i = 2; // index of first key, if timeout not there |
| @@ -178,9 +178,9 @@ LUAG_FUNC( linda_send) | |||
| 178 | { | 178 | { |
| 179 | cancel = s->cancel_request; | 179 | cancel = s->cancel_request; |
| 180 | } | 180 | } |
| 181 | cancel = (cancel != CANCEL_NONE) ? cancel : linda->simulate_cancel; | 181 | cancel = (cancel != CancelRequest::None) ? cancel : linda->simulate_cancel; |
| 182 | // if user wants to cancel, or looped because of a timeout, the call returns without sending anything | 182 | // if user wants to cancel, or looped because of a timeout, the call returns without sending anything |
| 183 | if( !try_again || cancel != CANCEL_NONE) | 183 | if (!try_again || cancel != CancelRequest::None) |
| 184 | { | 184 | { |
| 185 | pushed = 0; | 185 | pushed = 0; |
| 186 | break; | 186 | break; |
| @@ -241,12 +241,12 @@ LUAG_FUNC( linda_send) | |||
| 241 | 241 | ||
| 242 | switch( cancel) | 242 | switch( cancel) |
| 243 | { | 243 | { |
| 244 | case CANCEL_SOFT: | 244 | case CancelRequest::Soft: |
| 245 | // if user wants to soft-cancel, the call returns lanes.cancel_error | 245 | // if user wants to soft-cancel, the call returns lanes.cancel_error |
| 246 | CANCEL_ERROR.push(L); | 246 | CANCEL_ERROR.push(L); |
| 247 | return 1; | 247 | return 1; |
| 248 | 248 | ||
| 249 | case CANCEL_HARD: | 249 | case CancelRequest::Hard: |
| 250 | // raise an error interrupting execution only in case of hard cancel | 250 | // raise an error interrupting execution only in case of hard cancel |
| 251 | return cancel_error( L); // raises an error and doesn't return | 251 | return cancel_error( L); // raises an error and doesn't return |
| 252 | 252 | ||
| @@ -273,7 +273,7 @@ LUAG_FUNC( linda_receive) | |||
| 273 | { | 273 | { |
| 274 | struct s_Linda* linda = lua_toLinda( L, 1); | 274 | struct s_Linda* linda = lua_toLinda( L, 1); |
| 275 | int pushed, expected_pushed_min, expected_pushed_max; | 275 | int pushed, expected_pushed_min, expected_pushed_max; |
| 276 | enum e_cancel_request cancel = CANCEL_NONE; | 276 | CancelRequest cancel{ CancelRequest::None }; |
| 277 | keeper_api_t keeper_receive; | 277 | keeper_api_t keeper_receive; |
| 278 | 278 | ||
| 279 | time_d timeout = -1.0; | 279 | time_d timeout = -1.0; |
| @@ -335,9 +335,9 @@ LUAG_FUNC( linda_receive) | |||
| 335 | { | 335 | { |
| 336 | cancel = s->cancel_request; | 336 | cancel = s->cancel_request; |
| 337 | } | 337 | } |
| 338 | cancel = (cancel != CANCEL_NONE) ? cancel : linda->simulate_cancel; | 338 | cancel = (cancel != CancelRequest::None) ? cancel : linda->simulate_cancel; |
| 339 | // if user wants to cancel, or looped because of a timeout, the call returns without sending anything | 339 | // if user wants to cancel, or looped because of a timeout, the call returns without sending anything |
| 340 | if( !try_again || cancel != CANCEL_NONE) | 340 | if (!try_again || cancel != CancelRequest::None) |
| 341 | { | 341 | { |
| 342 | pushed = 0; | 342 | pushed = 0; |
| 343 | break; | 343 | break; |
| @@ -395,12 +395,12 @@ LUAG_FUNC( linda_receive) | |||
| 395 | 395 | ||
| 396 | switch( cancel) | 396 | switch( cancel) |
| 397 | { | 397 | { |
| 398 | case CANCEL_SOFT: | 398 | case CancelRequest::Soft: |
| 399 | // if user wants to soft-cancel, the call returns CANCEL_ERROR | 399 | // if user wants to soft-cancel, the call returns CANCEL_ERROR |
| 400 | CANCEL_ERROR.push(L); | 400 | CANCEL_ERROR.push(L); |
| 401 | return 1; | 401 | return 1; |
| 402 | 402 | ||
| 403 | case CANCEL_HARD: | 403 | case CancelRequest::Hard: |
| 404 | // raise an error interrupting execution only in case of hard cancel | 404 | // raise an error interrupting execution only in case of hard cancel |
| 405 | return cancel_error( L); // raises an error and doesn't return | 405 | return cancel_error( L); // raises an error and doesn't return |
| 406 | 406 | ||
| @@ -430,7 +430,7 @@ LUAG_FUNC( linda_set) | |||
| 430 | { | 430 | { |
| 431 | Keeper* K = which_keeper( linda->U->keepers, LINDA_KEEPER_HASHSEED( linda)); | 431 | Keeper* K = which_keeper( linda->U->keepers, LINDA_KEEPER_HASHSEED( linda)); |
| 432 | 432 | ||
| 433 | if( linda->simulate_cancel == CANCEL_NONE) | 433 | if (linda->simulate_cancel == CancelRequest::None) |
| 434 | { | 434 | { |
| 435 | if( has_value) | 435 | if( has_value) |
| 436 | { | 436 | { |
| @@ -511,7 +511,7 @@ LUAG_FUNC( linda_get) | |||
| 511 | { | 511 | { |
| 512 | Keeper* K = which_keeper( linda->U->keepers, LINDA_KEEPER_HASHSEED( linda)); | 512 | Keeper* K = which_keeper( linda->U->keepers, LINDA_KEEPER_HASHSEED( linda)); |
| 513 | 513 | ||
| 514 | if( linda->simulate_cancel == CANCEL_NONE) | 514 | if (linda->simulate_cancel == CancelRequest::None) |
| 515 | { | 515 | { |
| 516 | pushed = keeper_call( linda->U, K->L, KEEPER_API( get), L, linda, 2); | 516 | pushed = keeper_call( linda->U, K->L, KEEPER_API( get), L, linda, 2); |
| 517 | if( pushed > 0) | 517 | if( pushed > 0) |
| @@ -557,7 +557,7 @@ LUAG_FUNC( linda_limit) | |||
| 557 | { | 557 | { |
| 558 | Keeper* K = which_keeper( linda->U->keepers, LINDA_KEEPER_HASHSEED( linda)); | 558 | Keeper* K = which_keeper( linda->U->keepers, LINDA_KEEPER_HASHSEED( linda)); |
| 559 | 559 | ||
| 560 | if( linda->simulate_cancel == CANCEL_NONE) | 560 | if (linda->simulate_cancel == CancelRequest::None) |
| 561 | { | 561 | { |
| 562 | pushed = keeper_call( linda->U, K->L, KEEPER_API( limit), L, linda, 2); | 562 | pushed = keeper_call( linda->U, K->L, KEEPER_API( limit), L, linda, 2); |
| 563 | ASSERT_L( pushed == 0 || pushed == 1); // no error, optional boolean value saying if we should wake blocked writer threads | 563 | ASSERT_L( pushed == 0 || pushed == 1); // no error, optional boolean value saying if we should wake blocked writer threads |
| @@ -592,7 +592,7 @@ LUAG_FUNC( linda_cancel) | |||
| 592 | // make sure we got 3 arguments: the linda, a key and a limit | 592 | // make sure we got 3 arguments: the linda, a key and a limit |
| 593 | luaL_argcheck( L, lua_gettop( L) <= 2, 2, "wrong number of arguments"); | 593 | luaL_argcheck( L, lua_gettop( L) <= 2, 2, "wrong number of arguments"); |
| 594 | 594 | ||
| 595 | linda->simulate_cancel = CANCEL_SOFT; | 595 | linda->simulate_cancel = CancelRequest::Soft; |
| 596 | if( strcmp( who, "both") == 0) // tell everyone writers to wake up | 596 | if( strcmp( who, "both") == 0) // tell everyone writers to wake up |
| 597 | { | 597 | { |
| 598 | SIGNAL_ALL( &linda->write_happened); | 598 | SIGNAL_ALL( &linda->write_happened); |
| @@ -600,7 +600,7 @@ LUAG_FUNC( linda_cancel) | |||
| 600 | } | 600 | } |
| 601 | else if( strcmp( who, "none") == 0) // reset flag | 601 | else if( strcmp( who, "none") == 0) // reset flag |
| 602 | { | 602 | { |
| 603 | linda->simulate_cancel = CANCEL_NONE; | 603 | linda->simulate_cancel = CancelRequest::None; |
| 604 | } | 604 | } |
| 605 | else if( strcmp( who, "read") == 0) // tell blocked readers to wake up | 605 | else if( strcmp( who, "read") == 0) // tell blocked readers to wake up |
| 606 | { | 606 | { |
| @@ -802,7 +802,7 @@ static void* linda_id( lua_State* L, DeepOp op_) | |||
| 802 | SIGNAL_INIT( &s->read_happened); | 802 | SIGNAL_INIT( &s->read_happened); |
| 803 | SIGNAL_INIT( &s->write_happened); | 803 | SIGNAL_INIT( &s->write_happened); |
| 804 | s->U = universe_get( L); | 804 | s->U = universe_get( L); |
| 805 | s->simulate_cancel = CANCEL_NONE; | 805 | s->simulate_cancel = CancelRequest::None; |
| 806 | s->group = linda_group << KEEPER_MAGIC_SHIFT; | 806 | s->group = linda_group << KEEPER_MAGIC_SHIFT; |
| 807 | s->name[0] = 0; | 807 | s->name[0] = 0; |
| 808 | memcpy( s->name, linda_name, name_len ? name_len + 1 : 0); | 808 | memcpy( s->name, linda_name, name_len ? name_len + 1 : 0); |
