aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.cpp')
-rw-r--r--src/lanes.cpp91
1 files changed, 8 insertions, 83 deletions
diff --git a/src/lanes.cpp b/src/lanes.cpp
index 9c9d7d1..f8efa42 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -104,67 +104,12 @@ THE SOFTWARE.
104 104
105// ################################################################################################# 105// #################################################################################################
106 106
107#if HAVE_LANE_TRACKING()
108
109// The chain is ended by '(Lane*)(-1)', not nullptr:
110// 'trackingFirst -> ... -> ... -> (-1)'
111#define TRACKING_END ((Lane*) (-1))
112
113/*
114 * Add the lane to tracking chain; the ones still running at the end of the
115 * whole process will be cancelled.
116 */
117static void tracking_add(Lane* lane_)
118{
119 std::lock_guard<std::mutex> _guard{ lane_->U->trackingMutex };
120 assert(lane_->tracking_next == nullptr);
121
122 lane_->tracking_next = lane_->U->trackingFirst;
123 lane_->U->trackingFirst = lane_;
124}
125
126// #################################################################################################
127
128/*
129 * A free-running lane has ended; remove it from tracking chain
130 */
131[[nodiscard]] static bool tracking_remove(Lane* lane_)
132{
133 bool _found{ false };
134 std::lock_guard<std::mutex> _guard{ lane_->U->trackingMutex };
135 // Make sure (within the MUTEX) that we actually are in the chain
136 // still (at process exit they will remove us from chain and then
137 // cancel/kill).
138 //
139 if (lane_->tracking_next != nullptr) {
140 Lane** _ref = (Lane**) &lane_->U->trackingFirst;
141
142 while (*_ref != TRACKING_END) {
143 if (*_ref == lane_) {
144 *_ref = lane_->tracking_next;
145 lane_->tracking_next = nullptr;
146 _found = true;
147 break;
148 }
149 _ref = (Lane**) &((*_ref)->tracking_next);
150 }
151 assert(_found);
152 }
153 return _found;
154}
155
156#endif // HAVE_LANE_TRACKING()
157
158// #################################################################################################
159
160Lane::Lane(Universe* U_, lua_State* L_) 107Lane::Lane(Universe* U_, lua_State* L_)
161: U{ U_ } 108: U{ U_ }
162, L{ L_ } 109, L{ L_ }
163{ 110{
164#if HAVE_LANE_TRACKING() 111#if HAVE_LANE_TRACKING()
165 if (U->trackingFirst) { 112 U->tracker.tracking_add(this);
166 tracking_add(this);
167 }
168#endif // HAVE_LANE_TRACKING() 113#endif // HAVE_LANE_TRACKING()
169} 114}
170 115
@@ -241,10 +186,7 @@ Lane::~Lane()
241 // Clean up after a (finished) thread 186 // Clean up after a (finished) thread
242 // 187 //
243#if HAVE_LANE_TRACKING() 188#if HAVE_LANE_TRACKING()
244 if (U->trackingFirst != nullptr) { 189 std::ignore = U->tracker.tracking_remove(this);
245 // Lane was cleaned up, no need to handle at process termination
246 std::ignore = tracking_remove(this);
247 }
248#endif // HAVE_LANE_TRACKING() 190#endif // HAVE_LANE_TRACKING()
249} 191}
250 192
@@ -1428,27 +1370,8 @@ LUAG_FUNC(thread_index)
1428// Return a list of all known lanes 1370// Return a list of all known lanes
1429LUAG_FUNC(threads) 1371LUAG_FUNC(threads)
1430{ 1372{
1431 int const _top{ lua_gettop(L_) }; 1373 LaneTracker const& _tracker = universe_get(L_)->tracker;
1432 Universe* const _U{ universe_get(L_) }; 1374 return _tracker.pushThreadsTable(L_);
1433
1434 // List _all_ still running threads
1435 std::lock_guard<std::mutex> _guard{ _U->trackingMutex };
1436 if (_U->trackingFirst && _U->trackingFirst != TRACKING_END) {
1437 Lane* _lane{ _U->trackingFirst };
1438 int _index{ 0 };
1439 lua_newtable(L_); // L_: {}
1440 while (_lane != TRACKING_END) {
1441 // insert a { name='<name>', status='<status>' } tuple, so that several lanes with the same name can't clobber each other
1442 lua_createtable(L_, 0, 2); // L_: {} {}
1443 lua_pushstring(L_, _lane->debugName); // L_: {} {} "name"
1444 lua_setfield(L_, -2, "name"); // L_: {} {}
1445 _lane->pushThreadStatus(L_); // L_: {} {} "status"
1446 lua_setfield(L_, -2, "status"); // L_: {} {}
1447 lua_rawseti(L_, -2, ++_index); // L_: {}
1448 _lane = _lane->tracking_next;
1449 }
1450 }
1451 return lua_gettop(L_) - _top; // L_: 0 or 1
1452} 1375}
1453#endif // HAVE_LANE_TRACKING() 1376#endif // HAVE_LANE_TRACKING()
1454 1377
@@ -1668,7 +1591,9 @@ LUAG_FUNC(configure)
1668 lua_pop(L_, 1); // L_: settings 1591 lua_pop(L_, 1); // L_: settings
1669#if HAVE_LANE_TRACKING() 1592#if HAVE_LANE_TRACKING()
1670 lua_getfield(L_, 1, "track_lanes"); // L_: settings track_lanes 1593 lua_getfield(L_, 1, "track_lanes"); // L_: settings track_lanes
1671 _U->trackingFirst = lua_toboolean(L_, -1) ? TRACKING_END : nullptr; 1594 if (lua_toboolean(L_, -1)) {
1595 _U->tracker.activate();
1596 }
1672 lua_pop(L_, 1); // L_: settings 1597 lua_pop(L_, 1); // L_: settings
1673#endif // HAVE_LANE_TRACKING() 1598#endif // HAVE_LANE_TRACKING()
1674 // Linked chains handling 1599 // Linked chains handling
@@ -1704,7 +1629,7 @@ LUAG_FUNC(configure)
1704 luaG_registerlibfuncs(L_, global::sLanesFunctions); 1629 luaG_registerlibfuncs(L_, global::sLanesFunctions);
1705#if HAVE_LANE_TRACKING() 1630#if HAVE_LANE_TRACKING()
1706 // register core.threads() only if settings say it should be available 1631 // register core.threads() only if settings say it should be available
1707 if (_U->trackingFirst != nullptr) { 1632 if (_U->tracker.isActive()) {
1708 lua_pushcfunction(L_, LG_threads); // L_: settings M LG_threads() 1633 lua_pushcfunction(L_, LG_threads); // L_: settings M LG_threads()
1709 lua_setfield(L_, -2, "threads"); // L_: settings M 1634 lua_setfield(L_, -2, "threads"); // L_: settings M
1710 } 1635 }