aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lane.cpp44
-rw-r--r--src/lane.h2
-rw-r--r--src/lanes.cpp8
-rw-r--r--src/lanes.h4
4 files changed, 30 insertions, 28 deletions
diff --git a/src/lane.cpp b/src/lane.cpp
index e38c4bb..baba0fa 100644
--- a/src/lane.cpp
+++ b/src/lane.cpp
@@ -480,7 +480,7 @@ int Lane::LuaErrorHandler(lua_State* L_)
480// ########################################## Finalizer ############################################ 480// ########################################## Finalizer ############################################
481// ################################################################################################# 481// #################################################################################################
482 482
483static [[nodiscard]] int push_stack_trace(lua_State* const L_, Lane::ErrorTraceLevel const errorTraceLevel_, LuaError const rc_, [[maybe_unused]] int const stk_base_) 483[[nodiscard]] static int PushStackTrace(lua_State* const L_, Lane::ErrorTraceLevel const errorTraceLevel_, LuaError const rc_, [[maybe_unused]] int const stk_base_)
484{ 484{
485 // Lua 5.1 error handler is limited to one return value; it stored the stack trace in the registry 485 // Lua 5.1 error handler is limited to one return value; it stored the stack trace in the registry
486 int const _top{ lua_gettop(L_) }; 486 int const _top{ lua_gettop(L_) };
@@ -532,7 +532,7 @@ static [[nodiscard]] int push_stack_trace(lua_State* const L_, Lane::ErrorTraceL
532// TBD: should we add stack trace on failing finalizer, wouldn't be hard.. 532// TBD: should we add stack trace on failing finalizer, wouldn't be hard..
533// 533//
534 534
535[[nodiscard]] static LuaError run_finalizers(Lane* const lane_, Lane::ErrorTraceLevel errorTraceLevel_, LuaError lua_rc_) 535[[nodiscard]] static LuaError run_finalizers(Lane* const lane_, Lane::ErrorTraceLevel const errorTraceLevel_, LuaError const lua_rc_)
536{ 536{
537 // if we are a coroutine, we can't run the finalizers in the coroutine state! 537 // if we are a coroutine, we can't run the finalizers in the coroutine state!
538 lua_State* const _L{ lane_->S }; 538 lua_State* const _L{ lane_->S };
@@ -581,7 +581,7 @@ static [[nodiscard]] int push_stack_trace(lua_State* const L_, Lane::ErrorTraceL
581 // if no error from the main body, finalizer doesn't receive any argument, else it gets the error message and optional stack trace 581 // if no error from the main body, finalizer doesn't receive any argument, else it gets the error message and optional stack trace
582 _rc = ToLuaError(lua_pcall(_L, _args, 0, _error_handler)); // _L: ... finalizers error_handler() err_msg2? 582 _rc = ToLuaError(lua_pcall(_L, _args, 0, _error_handler)); // _L: ... finalizers error_handler() err_msg2?
583 if (_rc != LuaError::OK) { 583 if (_rc != LuaError::OK) {
584 _finalizer_pushed = 1 + push_stack_trace(_L, errorTraceLevel_, _rc, lua_gettop(_L)); // _L: ... finalizers error_handler() err_msg2? trace 584 _finalizer_pushed = 1 + PushStackTrace(_L, errorTraceLevel_, _rc, lua_gettop(_L)); // _L: ... finalizers error_handler() err_msg2? trace
585 // If one finalizer fails, don't run the others. Return this 585 // If one finalizer fails, don't run the others. Return this
586 // as the 'real' error, replacing what we could have had (or not) 586 // as the 'real' error, replacing what we could have had (or not)
587 // from the actual code. 587 // from the actual code.
@@ -622,35 +622,35 @@ static [[nodiscard]] int push_stack_trace(lua_State* const L_, Lane::ErrorTraceL
622 * Add the lane to selfdestruct chain; the ones still running at the end of the 622 * Add the lane to selfdestruct chain; the ones still running at the end of the
623 * whole process will be cancelled. 623 * whole process will be cancelled.
624 */ 624 */
625static void selfdestruct_add(Lane* lane_) 625void Lane::selfdestructAdd()
626{ 626{
627 std::lock_guard<std::mutex> _guard{ lane_->U->selfdestructMutex }; 627 std::lock_guard<std::mutex> _guard{ U->selfdestructMutex };
628 assert(lane_->selfdestruct_next == nullptr); 628 assert(selfdestruct_next == nullptr);
629 629
630 lane_->selfdestruct_next = lane_->U->selfdestructFirst; 630 selfdestruct_next = U->selfdestructFirst;
631 lane_->U->selfdestructFirst = lane_; 631 U->selfdestructFirst = this;
632} 632}
633 633
634// ################################################################################################# 634// #################################################################################################
635 635
636// A free-running lane has ended; remove it from selfdestruct chain 636// A free-running lane has ended; remove it from selfdestruct chain
637[[nodiscard]] static bool selfdestruct_remove(Lane* lane_) 637[[nodiscard]] bool Lane::selfdestructRemove()
638{ 638{
639 bool _found{ false }; 639 bool _found{ false };
640 std::lock_guard<std::mutex> _guard{ lane_->U->selfdestructMutex }; 640 std::lock_guard<std::mutex> _guard{ U->selfdestructMutex };
641 // Make sure (within the MUTEX) that we actually are in the chain 641 // Make sure (within the MUTEX) that we actually are in the chain
642 // still (at process exit they will remove us from chain and then 642 // still (at process exit they will remove us from chain and then
643 // cancel/kill). 643 // cancel/kill).
644 // 644 //
645 if (lane_->selfdestruct_next != nullptr) { 645 if (selfdestruct_next != nullptr) {
646 Lane* volatile* _ref = static_cast<Lane* volatile*>(&lane_->U->selfdestructFirst); 646 Lane* volatile* _ref = static_cast<Lane* volatile*>(&U->selfdestructFirst);
647 647
648 while (*_ref != SELFDESTRUCT_END) { 648 while (*_ref != SELFDESTRUCT_END) {
649 if (*_ref == lane_) { 649 if (*_ref == this) {
650 *_ref = lane_->selfdestruct_next; 650 *_ref = selfdestruct_next;
651 lane_->selfdestruct_next = nullptr; 651 selfdestruct_next = nullptr;
652 // the terminal shutdown should wait until the lane is done with its lua_close() 652 // the terminal shutdown should wait until the lane is done with its lua_close()
653 lane_->U->selfdestructingCount.fetch_add(1, std::memory_order_release); 653 U->selfdestructingCount.fetch_add(1, std::memory_order_release);
654 _found = true; 654 _found = true;
655 break; 655 break;
656 } 656 }
@@ -665,7 +665,7 @@ static void selfdestruct_add(Lane* lane_)
665// ########################################## Main ################################################# 665// ########################################## Main #################################################
666// ################################################################################################# 666// #################################################################################################
667 667
668static void PrepareLaneHelpers(Lane* lane_) 668static void PrepareLaneHelpers(Lane* const lane_)
669{ 669{
670 lua_State* const _L{ lane_->L }; 670 lua_State* const _L{ lane_->L };
671 // Tie "set_finalizer()" to the state 671 // Tie "set_finalizer()" to the state
@@ -752,7 +752,7 @@ static void lane_main(Lane* const lane_)
752 } 752 }
753 753
754 // in case of error and if it exists, fetch stack trace from registry and push it 754 // in case of error and if it exists, fetch stack trace from registry and push it
755 lane_->nresults += push_stack_trace(_L, lane_->errorTraceLevel, _rc, 1); // L: retvals|error [trace] 755 lane_->nresults += PushStackTrace(_L, lane_->errorTraceLevel, _rc, 1); // L: retvals|error [trace]
756 756
757 DEBUGSPEW_CODE(DebugSpew(lane_->U) << "Lane " << _L << " body: " << GetErrcodeName(_rc) << " (" << (kCancelError.equals(_L, 1) ? "cancelled" : luaG_typename(_L, 1)) << ")" << std::endl); 757 DEBUGSPEW_CODE(DebugSpew(lane_->U) << "Lane " << _L << " body: " << GetErrcodeName(_rc) << " (" << (kCancelError.equals(_L, 1) ? "cancelled" : luaG_typename(_L, 1)) << ")" << std::endl);
758 // Call finalizers, if the script has set them up. 758 // Call finalizers, if the script has set them up.
@@ -765,7 +765,7 @@ static void lane_main(Lane* const lane_)
765 _rc = _rc2; // we're overruling the earlier script error or normal return 765 _rc = _rc2; // we're overruling the earlier script error or normal return
766 } 766 }
767 lane_->waiting_on = nullptr; // just in case 767 lane_->waiting_on = nullptr; // just in case
768 if (selfdestruct_remove(lane_)) { // check and remove (under lock!) 768 if (lane_->selfdestructRemove()) { // check and remove (under lock!)
769 // We're a free-running thread and no-one is there to clean us up. 769 // We're a free-running thread and no-one is there to clean us up.
770 lane_->closeState(); 770 lane_->closeState();
771 lane_->U->selfdestructMutex.lock(); 771 lane_->U->selfdestructMutex.lock();
@@ -809,7 +809,7 @@ static LUAG_FUNC(lane_close)
809 809
810// ################################################################################################# 810// #################################################################################################
811 811
812// = thread_gc( lane_ud ) 812// = lane_gc( lane_ud )
813// 813//
814// Cleanup for a thread userdata. If the thread is still executing, leave it 814// Cleanup for a thread userdata. If the thread is still executing, leave it
815// alive as a free-running thread (will clean up itself). 815// alive as a free-running thread (will clean up itself).
@@ -823,7 +823,7 @@ static LUAG_FUNC(lane_close)
823static LUAG_FUNC(lane_gc) 823static LUAG_FUNC(lane_gc)
824{ 824{
825 bool _have_gc_cb{ false }; 825 bool _have_gc_cb{ false };
826 Lane* const _lane{ ToLane(L_, 1) }; // L_: ud 826 Lane* const _lane{ ToLane(L_, 1) }; // L_: ud
827 827
828 // if there a gc callback? 828 // if there a gc callback?
829 lua_getiuservalue(L_, 1, 1); // L_: ud uservalue 829 lua_getiuservalue(L_, 1, 1); // L_: ud uservalue
@@ -840,7 +840,7 @@ static LUAG_FUNC(lane_gc)
840 // We can read 'lane->status' without locks, but not wait for it 840 // We can read 'lane->status' without locks, but not wait for it
841 if (_lane->status < Lane::Done) { 841 if (_lane->status < Lane::Done) {
842 // still running: will have to be cleaned up later 842 // still running: will have to be cleaned up later
843 selfdestruct_add(_lane); 843 _lane->selfdestructAdd();
844 assert(_lane->selfdestruct_next); 844 assert(_lane->selfdestruct_next);
845 if (_have_gc_cb) { 845 if (_have_gc_cb) {
846 luaG_pushstring(L_, "selfdestruct"); // L_: ud gc_cb name status 846 luaG_pushstring(L_, "selfdestruct"); // L_: ud gc_cb name status
diff --git a/src/lane.h b/src/lane.h
index a7a348b..85994a0 100644
--- a/src/lane.h
+++ b/src/lane.h
@@ -174,6 +174,8 @@ class Lane
174 void pushStatusString(lua_State* L_) const; 174 void pushStatusString(lua_State* L_) const;
175 void pushIndexedResult(lua_State* L_, int key_) const; 175 void pushIndexedResult(lua_State* L_, int key_) const;
176 void resetResultsStorage(lua_State* const L_, int gc_cb_idx_); 176 void resetResultsStorage(lua_State* const L_, int gc_cb_idx_);
177 void selfdestructAdd();
178 [[nodiscard]] bool selfdestructRemove();
177 void securizeDebugName(lua_State* L_); 179 void securizeDebugName(lua_State* L_);
178 void startThread(int priority_); 180 void startThread(int priority_);
179 [[nodiscard]] int storeResults(lua_State* L_); 181 [[nodiscard]] int storeResults(lua_State* L_);
diff --git a/src/lanes.cpp b/src/lanes.cpp
index b096774..c820568 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -836,7 +836,7 @@ static void EnableCrashingOnCrashes(void)
836 836
837// ################################################################################################# 837// #################################################################################################
838 838
839LANES_API int luaopen_lanes_core(lua_State* L_) 839LANES_API int luaopen_lanes_core(lua_State* const L_)
840{ 840{
841#if defined PLATFORM_WIN32 && !defined NDEBUG 841#if defined PLATFORM_WIN32 && !defined NDEBUG
842 EnableCrashingOnCrashes(); 842 EnableCrashingOnCrashes();
@@ -879,7 +879,7 @@ LANES_API int luaopen_lanes_core(lua_State* L_)
879 879
880// ################################################################################################# 880// #################################################################################################
881 881
882[[nodiscard]] static int default_luaopen_lanes(lua_State* L_) 882[[nodiscard]] static int default_luaopen_lanes(lua_State* const L_)
883{ 883{
884 LuaError const _rc{ luaL_loadfile(L_, "lanes.lua") || lua_pcall(L_, 0, 1, 0) }; 884 LuaError const _rc{ luaL_loadfile(L_, "lanes.lua") || lua_pcall(L_, 0, 1, 0) };
885 if (_rc != LuaError::OK) { 885 if (_rc != LuaError::OK) {
@@ -891,7 +891,7 @@ LANES_API int luaopen_lanes_core(lua_State* L_)
891// ################################################################################################# 891// #################################################################################################
892 892
893// call this instead of luaopen_lanes_core() when embedding Lua and Lanes in a custom application 893// call this instead of luaopen_lanes_core() when embedding Lua and Lanes in a custom application
894LANES_API void luaopen_lanes_embedded(lua_State* L_, lua_CFunction _luaopen_lanes) 894LANES_API void luaopen_lanes_embedded(lua_State* const L_, lua_CFunction const luaopen_lanes_)
895{ 895{
896 STACK_CHECK_START_REL(L_, 0); 896 STACK_CHECK_START_REL(L_, 0);
897 // pre-require lanes.core so that when lanes.lua calls require "lanes.core" it finds it is already loaded 897 // pre-require lanes.core so that when lanes.lua calls require "lanes.core" it finds it is already loaded
@@ -899,6 +899,6 @@ LANES_API void luaopen_lanes_embedded(lua_State* L_, lua_CFunction _luaopen_lane
899 lua_pop(L_, 1); // L_: ... 899 lua_pop(L_, 1); // L_: ...
900 STACK_CHECK(L_, 0); 900 STACK_CHECK(L_, 0);
901 // call user-provided function that runs the chunk "lanes.lua" from wherever they stored it 901 // call user-provided function that runs the chunk "lanes.lua" from wherever they stored it
902 luaL_requiref(L_, kLanesLibName, _luaopen_lanes ? _luaopen_lanes : default_luaopen_lanes, 0); // L_: ... lanes 902 luaL_requiref(L_, kLanesLibName, luaopen_lanes_ ? luaopen_lanes_ : default_luaopen_lanes, 0); // L_: ... lanes
903 STACK_CHECK(L_, 1); 903 STACK_CHECK(L_, 1);
904} 904}
diff --git a/src/lanes.h b/src/lanes.h
index 925db59..a3731e4 100644
--- a/src/lanes.h
+++ b/src/lanes.h
@@ -12,9 +12,9 @@
12#define LANES_VERSION_GREATER_THAN(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR > MAJOR) || (LANES_VERSION_MAJOR == MAJOR && (LANES_VERSION_MINOR > MINOR || (LANES_VERSION_MINOR == MINOR && LANES_VERSION_PATCH > PATCH)))) 12#define LANES_VERSION_GREATER_THAN(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR > MAJOR) || (LANES_VERSION_MAJOR == MAJOR && (LANES_VERSION_MINOR > MINOR || (LANES_VERSION_MINOR == MINOR && LANES_VERSION_PATCH > PATCH))))
13#define LANES_VERSION_GREATER_OR_EQUAL(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR > MAJOR) || (LANES_VERSION_MAJOR == MAJOR && (LANES_VERSION_MINOR > MINOR || (LANES_VERSION_MINOR == MINOR && LANES_VERSION_PATCH >= PATCH)))) 13#define LANES_VERSION_GREATER_OR_EQUAL(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR > MAJOR) || (LANES_VERSION_MAJOR == MAJOR && (LANES_VERSION_MINOR > MINOR || (LANES_VERSION_MINOR == MINOR && LANES_VERSION_PATCH >= PATCH))))
14 14
15LANES_API [[nodiscard]] int luaopen_lanes_core(lua_State* L_); 15LANES_API int luaopen_lanes_core(lua_State* L_);
16 16
17// Call this to work with embedded Lanes instead of calling luaopen_lanes_core() 17// Call this to work with embedded Lanes instead of calling luaopen_lanes_core()
18LANES_API void luaopen_lanes_embedded(lua_State* L_, lua_CFunction _luaopen_lanes); 18LANES_API void luaopen_lanes_embedded(lua_State* L_, lua_CFunction luaopen_lanes_);
19using luaopen_lanes_embedded_t = void (*)(lua_State* L_, lua_CFunction luaopen_lanes_); 19using luaopen_lanes_embedded_t = void (*)(lua_State* L_, lua_CFunction luaopen_lanes_);
20static_assert(std::is_same_v<decltype(&luaopen_lanes_embedded), luaopen_lanes_embedded_t>, "signature changed: check all uses of luaopen_lanes_embedded_t"); 20static_assert(std::is_same_v<decltype(&luaopen_lanes_embedded), luaopen_lanes_embedded_t>, "signature changed: check all uses of luaopen_lanes_embedded_t");