diff options
Diffstat (limited to 'src/lanes.cpp')
-rw-r--r-- | src/lanes.cpp | 66 |
1 files changed, 33 insertions, 33 deletions
diff --git a/src/lanes.cpp b/src/lanes.cpp index 91a2f8b..38fe2b9 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp | |||
@@ -176,10 +176,10 @@ bool Lane::waitForCompletion(lua_Duration duration_) | |||
176 | until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration_); | 176 | until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration_); |
177 | } | 177 | } |
178 | 178 | ||
179 | std::unique_lock lock{ m_done_mutex }; | 179 | std::unique_lock lock{ done_mutex }; |
180 | // std::stop_token token{ m_thread.get_stop_token() }; | 180 | // std::stop_token token{ thread.get_stop_token() }; |
181 | // return m_done_signal.wait_until(lock, token, secs_, [this](){ return m_status >= Lane::Done; }); | 181 | // return done_signal.wait_until(lock, token, secs_, [this](){ return status >= Lane::Done; }); |
182 | return m_done_signal.wait_until(lock, until, [this]() { return m_status >= Lane::Done; }); | 182 | return done_signal.wait_until(lock, until, [this]() { return status >= Lane::Done; }); |
183 | } | 183 | } |
184 | 184 | ||
185 | // ################################################################################################# | 185 | // ################################################################################################# |
@@ -187,9 +187,9 @@ bool Lane::waitForCompletion(lua_Duration duration_) | |||
187 | static void lane_main(Lane* lane); | 187 | static void lane_main(Lane* lane); |
188 | void Lane::startThread(int priority_) | 188 | void Lane::startThread(int priority_) |
189 | { | 189 | { |
190 | m_thread = std::jthread([this]() { lane_main(this); }); | 190 | thread = std::jthread([this]() { lane_main(this); }); |
191 | if (priority_ != kThreadPrioDefault) { | 191 | if (priority_ != kThreadPrioDefault) { |
192 | JTHREAD_SET_PRIORITY(m_thread, priority_, U->m_sudo); | 192 | JTHREAD_SET_PRIORITY(thread, priority_, U->m_sudo); |
193 | } | 193 | } |
194 | } | 194 | } |
195 | 195 | ||
@@ -441,7 +441,7 @@ static void selfdestruct_add(Lane* lane_) | |||
441 | // cancel/kill). | 441 | // cancel/kill). |
442 | // | 442 | // |
443 | if (lane_->selfdestruct_next != nullptr) { | 443 | if (lane_->selfdestruct_next != nullptr) { |
444 | Lane** ref = (Lane**) &lane_->U->selfdestruct_first; | 444 | Lane* volatile* ref = static_cast<Lane* volatile*>(&lane_->U->selfdestruct_first); |
445 | 445 | ||
446 | while (*ref != SELFDESTRUCT_END) { | 446 | while (*ref != SELFDESTRUCT_END) { |
447 | if (*ref == lane_) { | 447 | if (*ref == lane_) { |
@@ -452,7 +452,7 @@ static void selfdestruct_add(Lane* lane_) | |||
452 | found = true; | 452 | found = true; |
453 | break; | 453 | break; |
454 | } | 454 | } |
455 | ref = (Lane**) &((*ref)->selfdestruct_next); | 455 | ref = static_cast<Lane* volatile*>(&((*ref)->selfdestruct_next)); |
456 | } | 456 | } |
457 | assert(found); | 457 | assert(found); |
458 | } | 458 | } |
@@ -479,7 +479,7 @@ static void selfdestruct_add(Lane* lane_) | |||
479 | // attempt the requested cancel with a small timeout. | 479 | // attempt the requested cancel with a small timeout. |
480 | // if waiting on a linda, they will raise a cancel_error. | 480 | // if waiting on a linda, they will raise a cancel_error. |
481 | // if a cancellation hook is desired, it will be installed to try to raise an error | 481 | // if a cancellation hook is desired, it will be installed to try to raise an error |
482 | if (lane->m_thread.joinable()) { | 482 | if (lane->thread.joinable()) { |
483 | std::ignore = thread_cancel(lane, op, 1, timeout, true); | 483 | std::ignore = thread_cancel(lane, op, 1, timeout, true); |
484 | } | 484 | } |
485 | lane = lane->selfdestruct_next; | 485 | lane = lane->selfdestruct_next; |
@@ -532,7 +532,7 @@ static void selfdestruct_add(Lane* lane_) | |||
532 | 532 | ||
533 | // no need to mutex-protect this as all threads in the universe are gone at that point | 533 | // no need to mutex-protect this as all threads in the universe are gone at that point |
534 | if (U->timer_deep != nullptr) { // test ins case some early internal error prevented Lanes from creating the deep timer | 534 | if (U->timer_deep != nullptr) { // test ins case some early internal error prevented Lanes from creating the deep timer |
535 | [[maybe_unused]] int const prev_ref_count{ U->timer_deep->m_refcount.fetch_sub(1, std::memory_order_relaxed) }; | 535 | [[maybe_unused]] int const prev_ref_count{ U->timer_deep->refcount.fetch_sub(1, std::memory_order_relaxed) }; |
536 | LUA_ASSERT(L_, prev_ref_count == 1); // this should be the last reference | 536 | LUA_ASSERT(L_, prev_ref_count == 1); // this should be the last reference |
537 | DeepFactory::DeleteDeepObject(L_, U->timer_deep); | 537 | DeepFactory::DeleteDeepObject(L_, U->timer_deep); |
538 | U->timer_deep = nullptr; | 538 | U->timer_deep = nullptr; |
@@ -784,13 +784,13 @@ static void lane_main(Lane* lane_) | |||
784 | { | 784 | { |
785 | lua_State* const L{ lane_->L }; | 785 | lua_State* const L{ lane_->L }; |
786 | // wait until the launching thread has finished preparing L | 786 | // wait until the launching thread has finished preparing L |
787 | lane_->m_ready.wait(); | 787 | lane_->ready.wait(); |
788 | int rc{ LUA_ERRRUN }; | 788 | int rc{ LUA_ERRRUN }; |
789 | if (lane_->m_status == Lane::Pending) { // nothing wrong happened during preparation, we can work | 789 | if (lane_->status == Lane::Pending) { // nothing wrong happened during preparation, we can work |
790 | // At this point, the lane function and arguments are on the stack | 790 | // At this point, the lane function and arguments are on the stack |
791 | int const nargs{ lua_gettop(L) - 1 }; | 791 | int const nargs{ lua_gettop(L) - 1 }; |
792 | DEBUGSPEW_CODE(Universe* U = universe_get(L)); | 792 | DEBUGSPEW_CODE(Universe* U = universe_get(L)); |
793 | lane_->m_status = Lane::Running; // Pending -> Running | 793 | lane_->status = Lane::Running; // Pending -> Running |
794 | 794 | ||
795 | // Tie "set_finalizer()" to the state | 795 | // Tie "set_finalizer()" to the state |
796 | lua_pushcfunction(L, LG_set_finalizer); | 796 | lua_pushcfunction(L, LG_set_finalizer); |
@@ -838,7 +838,7 @@ static void lane_main(Lane* lane_) | |||
838 | // the finalizer generated an error, and left its own error message [and stack trace] on the stack | 838 | // the finalizer generated an error, and left its own error message [and stack trace] on the stack |
839 | rc = rc2; // we're overruling the earlier script error or normal return | 839 | rc = rc2; // we're overruling the earlier script error or normal return |
840 | } | 840 | } |
841 | lane_->m_waiting_on = nullptr; // just in case | 841 | lane_->waiting_on = nullptr; // just in case |
842 | if (selfdestruct_remove(lane_)) { // check and remove (under lock!) | 842 | if (selfdestruct_remove(lane_)) { // check and remove (under lock!) |
843 | // We're a free-running thread and no-one's there to clean us up. | 843 | // We're a free-running thread and no-one's there to clean us up. |
844 | lua_close(lane_->L); | 844 | lua_close(lane_->L); |
@@ -849,7 +849,7 @@ static void lane_main(Lane* lane_) | |||
849 | lane_->U->selfdestruct_cs.unlock(); | 849 | lane_->U->selfdestruct_cs.unlock(); |
850 | 850 | ||
851 | // we destroy our jthread member from inside the thread body, so we have to detach so that we don't try to join, as this doesn't seem a good idea | 851 | // we destroy our jthread member from inside the thread body, so we have to detach so that we don't try to join, as this doesn't seem a good idea |
852 | lane_->m_thread.detach(); | 852 | lane_->thread.detach(); |
853 | delete lane_; | 853 | delete lane_; |
854 | lane_ = nullptr; | 854 | lane_ = nullptr; |
855 | } | 855 | } |
@@ -860,10 +860,10 @@ static void lane_main(Lane* lane_) | |||
860 | Lane::Status const st = (rc == LUA_OK) ? Lane::Done : kCancelError.equals(L, 1) ? Lane::Cancelled : Lane::Error; | 860 | Lane::Status const st = (rc == LUA_OK) ? Lane::Done : kCancelError.equals(L, 1) ? Lane::Cancelled : Lane::Error; |
861 | 861 | ||
862 | { | 862 | { |
863 | // 'm_done_mutex' protects the -> Done|Error|Cancelled state change | 863 | // 'done_mutex' protects the -> Done|Error|Cancelled state change |
864 | std::lock_guard lock{ lane_->m_done_mutex }; | 864 | std::lock_guard lock{ lane_->done_mutex }; |
865 | lane_->m_status = st; | 865 | lane_->status = st; |
866 | lane_->m_done_signal.notify_one(); // wake up master (while 'lane_->m_done_mutex' is on) | 866 | lane_->done_signal.notify_one(); // wake up master (while 'lane_->done_mutex' is on) |
867 | } | 867 | } |
868 | } | 868 | } |
869 | } | 869 | } |
@@ -994,12 +994,12 @@ LUAG_FUNC(lane_new) | |||
994 | lua_settop(m_lane->L, 0); | 994 | lua_settop(m_lane->L, 0); |
995 | kCancelError.pushKey(m_lane->L); | 995 | kCancelError.pushKey(m_lane->L); |
996 | { | 996 | { |
997 | std::lock_guard lock{ m_lane->m_done_mutex }; | 997 | std::lock_guard lock{ m_lane->done_mutex }; |
998 | m_lane->m_status = Lane::Cancelled; | 998 | m_lane->status = Lane::Cancelled; |
999 | m_lane->m_done_signal.notify_one(); // wake up master (while 'lane->m_done_mutex' is on) | 999 | m_lane->done_signal.notify_one(); // wake up master (while 'lane->done_mutex' is on) |
1000 | } | 1000 | } |
1001 | // unblock the thread so that it can terminate gracefully | 1001 | // unblock the thread so that it can terminate gracefully |
1002 | m_lane->m_ready.count_down(); | 1002 | m_lane->ready.count_down(); |
1003 | } | 1003 | } |
1004 | } | 1004 | } |
1005 | 1005 | ||
@@ -1037,7 +1037,7 @@ LUAG_FUNC(lane_new) | |||
1037 | void success() | 1037 | void success() |
1038 | { | 1038 | { |
1039 | prepareUserData(); | 1039 | prepareUserData(); |
1040 | m_lane->m_ready.count_down(); | 1040 | m_lane->ready.count_down(); |
1041 | m_lane = nullptr; | 1041 | m_lane = nullptr; |
1042 | } | 1042 | } |
1043 | } onExit{ L_, lane, gc_cb_idx DEBUGSPEW_COMMA_PARAM(U) }; | 1043 | } onExit{ L_, lane, gc_cb_idx DEBUGSPEW_COMMA_PARAM(U) }; |
@@ -1214,7 +1214,7 @@ LUAG_FUNC(lane_new) | |||
1214 | } | 1214 | } |
1215 | 1215 | ||
1216 | // We can read 'lane->status' without locks, but not wait for it | 1216 | // We can read 'lane->status' without locks, but not wait for it |
1217 | if (lane->m_status < Lane::Done) { | 1217 | if (lane->status < Lane::Done) { |
1218 | // still running: will have to be cleaned up later | 1218 | // still running: will have to be cleaned up later |
1219 | selfdestruct_add(lane); | 1219 | selfdestruct_add(lane); |
1220 | assert(lane->selfdestruct_next); | 1220 | assert(lane->selfdestruct_next); |
@@ -1272,7 +1272,7 @@ LUAG_FUNC(lane_new) | |||
1272 | 1272 | ||
1273 | void Lane::pushThreadStatus(lua_State* L_) | 1273 | void Lane::pushThreadStatus(lua_State* L_) |
1274 | { | 1274 | { |
1275 | char const* const str{ thread_status_string(m_status) }; | 1275 | char const* const str{ thread_status_string(status) }; |
1276 | LUA_ASSERT(L_, str); | 1276 | LUA_ASSERT(L_, str); |
1277 | 1277 | ||
1278 | lua_pushstring(L_, str); | 1278 | lua_pushstring(L_, str); |
@@ -1294,7 +1294,7 @@ LUAG_FUNC(thread_join) | |||
1294 | lua_Duration const duration{ luaL_optnumber(L_, 2, -1.0) }; | 1294 | lua_Duration const duration{ luaL_optnumber(L_, 2, -1.0) }; |
1295 | lua_State* const L2{ lane->L }; | 1295 | lua_State* const L2{ lane->L }; |
1296 | 1296 | ||
1297 | bool const done{ !lane->m_thread.joinable() || lane->waitForCompletion(duration) }; | 1297 | bool const done{ !lane->thread.joinable() || lane->waitForCompletion(duration) }; |
1298 | if (!done || !L2) { | 1298 | if (!done || !L2) { |
1299 | STACK_GROW(L_, 2); | 1299 | STACK_GROW(L_, 2); |
1300 | lua_pushnil(L_); // L_: lane timeout? nil | 1300 | lua_pushnil(L_); // L_: lane timeout? nil |
@@ -1310,7 +1310,7 @@ LUAG_FUNC(thread_join) | |||
1310 | // debug_name is a pointer to string possibly interned in the lane's state, that no longer exists when the state is closed | 1310 | // debug_name is a pointer to string possibly interned in the lane's state, that no longer exists when the state is closed |
1311 | // so store it in the userdata uservalue at a key that can't possibly collide | 1311 | // so store it in the userdata uservalue at a key that can't possibly collide |
1312 | securize_debug_threadname(L_, lane); | 1312 | securize_debug_threadname(L_, lane); |
1313 | switch (lane->m_status) { | 1313 | switch (lane->status) { |
1314 | case Lane::Done: | 1314 | case Lane::Done: |
1315 | { | 1315 | { |
1316 | int const n{ lua_gettop(L2) }; // whole L2 stack | 1316 | int const n{ lua_gettop(L2) }; // whole L2 stack |
@@ -1343,7 +1343,7 @@ LUAG_FUNC(thread_join) | |||
1343 | break; | 1343 | break; |
1344 | 1344 | ||
1345 | default: | 1345 | default: |
1346 | DEBUGSPEW_CODE(fprintf(stderr, "Status: %d\n", lane->m_status)); | 1346 | DEBUGSPEW_CODE(fprintf(stderr, "Status: %d\n", lane->status)); |
1347 | LUA_ASSERT(L_, false); | 1347 | LUA_ASSERT(L_, false); |
1348 | ret = 0; | 1348 | ret = 0; |
1349 | } | 1349 | } |
@@ -1399,12 +1399,12 @@ LUAG_FUNC(thread_index) | |||
1399 | lua_pushcfunction(L_, LG_thread_join); | 1399 | lua_pushcfunction(L_, LG_thread_join); |
1400 | lua_pushvalue(L_, kSelf); | 1400 | lua_pushvalue(L_, kSelf); |
1401 | lua_call(L_, 1, LUA_MULTRET); // all return values are on the stack, at slots 4+ | 1401 | lua_call(L_, 1, LUA_MULTRET); // all return values are on the stack, at slots 4+ |
1402 | switch (lane->m_status) { | 1402 | switch (lane->status) { |
1403 | default: | 1403 | default: |
1404 | // this is an internal error, we probably never get here | 1404 | // this is an internal error, we probably never get here |
1405 | lua_settop(L_, 0); | 1405 | lua_settop(L_, 0); |
1406 | lua_pushliteral(L_, "Unexpected status: "); | 1406 | lua_pushliteral(L_, "Unexpected status: "); |
1407 | lua_pushstring(L_, thread_status_string(lane->m_status)); | 1407 | lua_pushstring(L_, thread_status_string(lane->status)); |
1408 | lua_concat(L_, 2); | 1408 | lua_concat(L_, 2); |
1409 | raise_lua_error(L_); | 1409 | raise_lua_error(L_); |
1410 | [[fallthrough]]; // fall through if we are killed, as we got nil, "killed" on the stack | 1410 | [[fallthrough]]; // fall through if we are killed, as we got nil, "killed" on the stack |
@@ -1666,7 +1666,7 @@ LUAG_FUNC(configure) | |||
1666 | U->tracking_first = lua_toboolean(L_, -1) ? TRACKING_END : nullptr; | 1666 | U->tracking_first = lua_toboolean(L_, -1) ? TRACKING_END : nullptr; |
1667 | lua_pop(L_, 1); // L_: settings | 1667 | lua_pop(L_, 1); // L_: settings |
1668 | #endif // HAVE_LANE_TRACKING() | 1668 | #endif // HAVE_LANE_TRACKING() |
1669 | // Linked chains handling | 1669 | // Linked chains handling |
1670 | U->selfdestruct_first = SELFDESTRUCT_END; | 1670 | U->selfdestruct_first = SELFDESTRUCT_END; |
1671 | initialize_allocator_function(U, L_); | 1671 | initialize_allocator_function(U, L_); |
1672 | initialize_on_state_create(U, L_); | 1672 | initialize_on_state_create(U, L_); |
@@ -1682,7 +1682,7 @@ LUAG_FUNC(configure) | |||
1682 | // Proxy userdata contents is only a 'DeepPrelude*' pointer | 1682 | // Proxy userdata contents is only a 'DeepPrelude*' pointer |
1683 | U->timer_deep = *lua_tofulluserdata<DeepPrelude*>(L_, -1); | 1683 | U->timer_deep = *lua_tofulluserdata<DeepPrelude*>(L_, -1); |
1684 | // increment refcount so that this linda remains alive as long as the universe exists. | 1684 | // increment refcount so that this linda remains alive as long as the universe exists. |
1685 | U->timer_deep->m_refcount.fetch_add(1, std::memory_order_relaxed); | 1685 | U->timer_deep->refcount.fetch_add(1, std::memory_order_relaxed); |
1686 | lua_pop(L_, 1); // L_: settings | 1686 | lua_pop(L_, 1); // L_: settings |
1687 | } | 1687 | } |
1688 | STACK_CHECK(L_, 1); | 1688 | STACK_CHECK(L_, 1); |