From 97ef3d50780123404dc29b1166b3556aa223ec10 Mon Sep 17 00:00:00 2001 From: Kevin Matz Date: Tue, 6 Dec 2022 15:38:20 -0500 Subject: [PATCH] allocate loop control variables before the loop --- protocol/esta/sacn/universe.cpp | 55 +++++++++++++++++---------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/protocol/esta/sacn/universe.cpp b/protocol/esta/sacn/universe.cpp index 0e118f9..14bdd0b 100644 --- a/protocol/esta/sacn/universe.cpp +++ b/protocol/esta/sacn/universe.cpp @@ -414,9 +414,6 @@ void Universe::tx_loop_() if (!isEditable()) return; - // run at least 1 loop - bool enable = true; - /// \cite sACN 6.2.6 E1.31 Data Packet: Options - Stream_Terminated /// Three packets containing this bit ... shall be sent by sources upon terminating /// sourcing of a universe. @@ -446,14 +443,17 @@ void Universe::tx_loop_() /// > intervals of between 800mS and 1000mS. std::chrono::milliseconds keep_alive_interval(800); - // I don't fully understand the semantics of std::conditional_variable, - // but it requires this mutex in the sleeping thread. - std::mutex mtx; + // allocate the control variables used by the loop + bool enable = true; // at least 1 loop + bool new_data; + std::chrono::nanoseconds elapsed; + std::chrono::microseconds sleep; + std::mutex mtx; // std::conditional_variable requires in the sleeping thread. Why?? while (enable || terminated_resend > 0) { // enforce strict minimum update times - auto elapsed = std::chrono::system_clock::now() - last_updated_; + elapsed = std::chrono::system_clock::now() - last_updated_; if (elapsed < minimum_update_time) std::this_thread::sleep_for(minimum_update_time - elapsed); @@ -463,29 +463,30 @@ void Universe::tx_loop_() tx_control_mutex_.unlock(); if (enable) - setStatus(DMX_ACTIVE); + { + setStatus(DMX_ACTIVE); + null_start_mutex.lock(); + new_data = (null_start_data != last_null_data); + if (new_data) + { + last_null_data = null_start_data; + retransmission_count = 0; + } + null_start_mutex.unlock(); + if (++retransmission_count > 3) + { + retransmission_count = 3; // prevent counter from overflowing + sleep = keep_alive_interval; + } + else + sleep = minimum_update_time; + } else { + setStatus(sACN_TERMINATED); // note the changed operating status provenance_->options.stream_terminated = true; // set the stream_terminated bit - setStatus(sACN_TERMINATED); // note the changed operating status - --terminated_resend; // stream_terminated must be sent 3 times - retransmission_count = 0; // stay throttled up through the termination sequence - } - - // see if this is new data or re-transmitting - null_start_mutex.lock(); - bool new_data = (null_start_data != last_null_data); - null_start_mutex.unlock(); - auto sleep = minimum_update_time; - if (new_data) - { - retransmission_count = 0; - last_null_data = null_start_data; - } - else if (++retransmission_count >= 2) - { - sleep = keep_alive_interval; - retransmission_count = 3; // prevent counter from overflowing + --terminated_resend; // stream_terminated must be sent 3 times + sleep = minimum_update_time; // stay throttled up through the termination sequence } // send the sACN message