diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/_pch.h | 5 | ||||
-rw-r--r-- | src/compat.h | 6 | ||||
-rw-r--r-- | src/intercopycontext.cpp | 2 | ||||
-rw-r--r-- | src/lane.cpp | 35 | ||||
-rw-r--r-- | src/lane.h | 4 | ||||
-rw-r--r-- | src/lanes.cpp | 9 |
6 files changed, 39 insertions, 22 deletions
@@ -6,15 +6,18 @@ | |||
6 | #include <bit> | 6 | #include <bit> |
7 | #include <cassert> | 7 | #include <cassert> |
8 | #include <chrono> | 8 | #include <chrono> |
9 | #include <compare> | ||
9 | #include <condition_variable> | 10 | #include <condition_variable> |
10 | #include <functional> | 11 | #include <functional> |
11 | #include <iostream> | 12 | #include <iostream> |
13 | #ifndef __PROSPERO__ | ||
12 | #include <latch> | 14 | #include <latch> |
15 | #endif // __PROSPERO__ | ||
13 | #include <mutex> | 16 | #include <mutex> |
14 | #include <optional> | 17 | #include <optional> |
15 | #include <ranges> | 18 | #include <ranges> |
16 | #include <source_location> | 19 | #include <source_location> |
17 | #include <stop_token> | 20 | //#include <stop_token> |
18 | #include <string_view> | 21 | #include <string_view> |
19 | #include <thread> | 22 | #include <thread> |
20 | #include <tuple> | 23 | #include <tuple> |
diff --git a/src/compat.h b/src/compat.h index 6458307..3b0ebf4 100644 --- a/src/compat.h +++ b/src/compat.h | |||
@@ -166,7 +166,7 @@ struct Wrap | |||
166 | // ################################################################################################# | 166 | // ################################################################################################# |
167 | 167 | ||
168 | template <int VERSION> | 168 | template <int VERSION> |
169 | struct Wrap<VERSION, typename std::enable_if<VERSION == 503>::type> | 169 | struct Wrap<VERSION, typename std::enable_if_t<VERSION == 503>> |
170 | { | 170 | { |
171 | static inline int lua_dump(lua_State* L_, lua_Writer writer_, void* data_, int strip_) | 171 | static inline int lua_dump(lua_State* L_, lua_Writer writer_, void* data_, int strip_) |
172 | { | 172 | { |
@@ -200,7 +200,7 @@ struct Wrap<VERSION, typename std::enable_if<VERSION == 503>::type> | |||
200 | // ################################################################################################# | 200 | // ################################################################################################# |
201 | 201 | ||
202 | template <int VERSION> | 202 | template <int VERSION> |
203 | struct Wrap<VERSION, typename std::enable_if<VERSION == 502>::type> | 203 | struct Wrap<VERSION, typename std::enable_if_t<VERSION == 502>> |
204 | { | 204 | { |
205 | static inline int lua_dump(lua_State* const L_, lua_Writer const writer_, void* const data_, [[maybe_unused]] int const strip_) | 205 | static inline int lua_dump(lua_State* const L_, lua_Writer const writer_, void* const data_, [[maybe_unused]] int const strip_) |
206 | { | 206 | { |
@@ -235,7 +235,7 @@ struct Wrap<VERSION, typename std::enable_if<VERSION == 502>::type> | |||
235 | // ################################################################################################# | 235 | // ################################################################################################# |
236 | 236 | ||
237 | template <int VERSION> | 237 | template <int VERSION> |
238 | struct Wrap<VERSION, typename std::enable_if<VERSION == 501>::type> | 238 | struct Wrap<VERSION, typename std::enable_if_t<VERSION == 501>> |
239 | { | 239 | { |
240 | static inline int lua_dump(lua_State* const L_, lua_Writer const writer_, void* const data_, [[maybe_unused]] int const strip_) | 240 | static inline int lua_dump(lua_State* const L_, lua_Writer const writer_, void* const data_, [[maybe_unused]] int const strip_) |
241 | { | 241 | { |
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index 8c9a026..190e15e 100644 --- a/src/intercopycontext.cpp +++ b/src/intercopycontext.cpp | |||
@@ -101,7 +101,7 @@ THE SOFTWARE. | |||
101 | lua_rawget(L1, -2); // L1: ... v ... {} "f.q.n" | 101 | lua_rawget(L1, -2); // L1: ... v ... {} "f.q.n" |
102 | } | 102 | } |
103 | std::string_view _fqn{ luaG_tostring(L1, -1) }; | 103 | std::string_view _fqn{ luaG_tostring(L1, -1) }; |
104 | DEBUGSPEW_CODE(DebugSpew(Universe::Get(L1)) << "function [C] " << _fqn << std::endl); | 104 | DEBUGSPEW_CODE(DebugSpew(U) << "function [C] " << _fqn << std::endl); |
105 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database | 105 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database |
106 | lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ... | 106 | lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ... |
107 | STACK_CHECK(L1, 0); | 107 | STACK_CHECK(L1, 0); |
diff --git a/src/lane.cpp b/src/lane.cpp index 6f4935e..c2cbbac 100644 --- a/src/lane.cpp +++ b/src/lane.cpp | |||
@@ -671,17 +671,23 @@ static void PrepareLaneHelpers(Lane* lane_) | |||
671 | 671 | ||
672 | // ################################################################################################# | 672 | // ################################################################################################# |
673 | 673 | ||
674 | static void lane_main(Lane* lane_) | 674 | static void lane_main(Lane* const lane_) |
675 | { | 675 | { |
676 | lua_State* const _L{ lane_->L }; | ||
677 | // wait until the launching thread has finished preparing L | 676 | // wait until the launching thread has finished preparing L |
677 | #ifndef __PROSPERO__ | ||
678 | lane_->ready.wait(); | 678 | lane_->ready.wait(); |
679 | #else // __PROSPERO__ | ||
680 | while (!lane_->ready._My_flag) { | ||
681 | std::this_thread::yield(); | ||
682 | } | ||
683 | #endif // __PROSPERO__ | ||
684 | |||
685 | lua_State* const _L{ lane_->L }; | ||
679 | LuaError _rc{ LuaError::ERRRUN }; | 686 | LuaError _rc{ LuaError::ERRRUN }; |
680 | if (lane_->status == Lane::Pending) { // nothing wrong happened during preparation, we can work | 687 | if (lane_->status == Lane::Pending) { // nothing wrong happened during preparation, we can work |
681 | // At this point, the lane function and arguments are on the stack, possibly preceded by the error handler | 688 | // At this point, the lane function and arguments are on the stack, possibly preceded by the error handler |
682 | int const _errorHandlerCount{ lane_->errorTraceLevel == Lane::Minimal ? 0 : 1}; | 689 | int const _errorHandlerCount{ lane_->errorTraceLevel == Lane::Minimal ? 0 : 1}; |
683 | int const _nargs{ lua_gettop(_L) - 1 - _errorHandlerCount }; | 690 | int const _nargs{ lua_gettop(_L) - 1 - _errorHandlerCount }; |
684 | DEBUGSPEW_CODE(Universe* _U = Universe::Get(_L)); | ||
685 | lane_->status = Lane::Running; // Pending -> Running | 691 | lane_->status = Lane::Running; // Pending -> Running |
686 | 692 | ||
687 | PrepareLaneHelpers(lane_); | 693 | PrepareLaneHelpers(lane_); |
@@ -695,11 +701,11 @@ static void lane_main(Lane* lane_) | |||
695 | // in case of error and if it exists, fetch stack trace from registry and push it | 701 | // in case of error and if it exists, fetch stack trace from registry and push it |
696 | push_stack_trace(_L, lane_->errorTraceLevel, _rc, 1); // L: retvals|error [trace] | 702 | push_stack_trace(_L, lane_->errorTraceLevel, _rc, 1); // L: retvals|error [trace] |
697 | 703 | ||
698 | DEBUGSPEW_CODE(DebugSpew(_U) << "Lane " << _L << " body: " << GetErrcodeName(_rc) << " (" << (kCancelError.equals(_L, 1) ? "cancelled" : luaG_typename(_L, 1)) << ")" << std::endl); | 704 | DEBUGSPEW_CODE(DebugSpew(lane_->U) << "Lane " << _L << " body: " << GetErrcodeName(_rc) << " (" << (kCancelError.equals(_L, 1) ? "cancelled" : luaG_typename(_L, 1)) << ")" << std::endl); |
699 | // Call finalizers, if the script has set them up. | 705 | // Call finalizers, if the script has set them up. |
700 | // | 706 | // |
701 | LuaError const _rc2{ run_finalizers(_L, lane_->errorTraceLevel, _rc) }; | 707 | LuaError const _rc2{ run_finalizers(_L, lane_->errorTraceLevel, _rc) }; |
702 | DEBUGSPEW_CODE(DebugSpew(_U) << "Lane " << _L << " finalizer: " << GetErrcodeName(_rc2) << std::endl); | 708 | DEBUGSPEW_CODE(DebugSpew(lane_->U) << "Lane " << _L << " finalizer: " << GetErrcodeName(_rc2) << std::endl); |
703 | if (_rc2 != LuaError::OK) { // Error within a finalizer! | 709 | if (_rc2 != LuaError::OK) { // Error within a finalizer! |
704 | // the finalizer generated an error, and left its own error message [and stack trace] on the stack | 710 | // the finalizer generated an error, and left its own error message [and stack trace] on the stack |
705 | _rc = _rc2; // we're overruling the earlier script error or normal return | 711 | _rc = _rc2; // we're overruling the earlier script error or normal return |
@@ -716,21 +722,16 @@ static void lane_main(Lane* lane_) | |||
716 | // 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 | 722 | // 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 |
717 | lane_->thread.detach(); | 723 | lane_->thread.detach(); |
718 | delete lane_; | 724 | delete lane_; |
719 | lane_ = nullptr; | 725 | return; |
720 | } | 726 | } |
721 | } | 727 | } |
722 | if (lane_) { | ||
723 | // leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them | ||
724 | 728 | ||
725 | Lane::Status const _st{ (_rc == LuaError::OK) ? Lane::Done : kCancelError.equals(_L, 1) ? Lane::Cancelled : Lane::Error }; | 729 | // leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them |
726 | 730 | Lane::Status const _st{ (_rc == LuaError::OK) ? Lane::Done : kCancelError.equals(_L, 1) ? Lane::Cancelled : Lane::Error }; | |
727 | { | 731 | // 'doneMutex' protects the -> Done|Error|Cancelled state change |
728 | // 'doneMutex' protects the -> Done|Error|Cancelled state change | 732 | std::lock_guard _guard{ lane_->doneMutex }; |
729 | std::lock_guard _guard{ lane_->doneMutex }; | 733 | lane_->status = _st; |
730 | lane_->status = _st; | 734 | lane_->doneCondVar.notify_one(); // wake up master (while 'lane_->doneMutex' is on) |
731 | lane_->doneCondVar.notify_one(); // wake up master (while 'lane_->doneMutex' is on) | ||
732 | } | ||
733 | } | ||
734 | } | 735 | } |
735 | 736 | ||
736 | // ################################################################################################# | 737 | // ################################################################################################# |
@@ -69,8 +69,12 @@ class Lane | |||
69 | 69 | ||
70 | // the thread | 70 | // the thread |
71 | std::jthread thread; | 71 | std::jthread thread; |
72 | #ifndef __PROSPERO__ | ||
72 | // a latch to wait for the lua_State to be ready | 73 | // a latch to wait for the lua_State to be ready |
73 | std::latch ready{ 1 }; | 74 | std::latch ready{ 1 }; |
75 | #else // __PROSPERO__ | ||
76 | std::atomic_flag ready{}; | ||
77 | #endif // __PROSPERO__ | ||
74 | // to wait for stop requests through thread's stop_source | 78 | // to wait for stop requests through thread's stop_source |
75 | std::mutex doneMutex; | 79 | std::mutex doneMutex; |
76 | std::condition_variable doneCondVar; // use condition_variable_any if waiting for a stop_token | 80 | std::condition_variable doneCondVar; // use condition_variable_any if waiting for a stop_token |
diff --git a/src/lanes.cpp b/src/lanes.cpp index 8b693c3..7196b72 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp | |||
@@ -308,7 +308,11 @@ LUAG_FUNC(lane_new) | |||
308 | lane->status = Lane::Running; | 308 | lane->status = Lane::Running; |
309 | } | 309 | } |
310 | // unblock the thread so that it can terminate gracefully | 310 | // unblock the thread so that it can terminate gracefully |
311 | #ifndef __PROSPERO__ | ||
311 | lane->ready.count_down(); | 312 | lane->ready.count_down(); |
313 | #else // __PROSPERO__ | ||
314 | lane->ready.test_and_set(); | ||
315 | #endif // __PROSPERO__ | ||
312 | } | 316 | } |
313 | } | 317 | } |
314 | 318 | ||
@@ -366,7 +370,12 @@ LUAG_FUNC(lane_new) | |||
366 | void success() | 370 | void success() |
367 | { | 371 | { |
368 | prepareUserData(); | 372 | prepareUserData(); |
373 | // unblock the thread so that it can terminate gracefully | ||
374 | #ifndef __PROSPERO__ | ||
369 | lane->ready.count_down(); | 375 | lane->ready.count_down(); |
376 | #else // __PROSPERO__ | ||
377 | lane->ready.test_and_set(); | ||
378 | #endif // __PROSPERO__ | ||
370 | lane = nullptr; | 379 | lane = nullptr; |
371 | } | 380 | } |
372 | } _onExit{ L_, _lane}; | 381 | } _onExit{ L_, _lane}; |