allocate loop control variables before the loop

This commit is contained in:
Kevin Matz 2022-12-06 15:38:20 -05:00
parent b07d505bce
commit 97ef3d5078

View File

@ -414,9 +414,6 @@ void Universe::tx_loop_()
if (!isEditable()) if (!isEditable())
return; return;
// run at least 1 loop
bool enable = true;
/// \cite sACN 6.2.6 E1.31 Data Packet: Options - Stream_Terminated /// \cite sACN 6.2.6 E1.31 Data Packet: Options - Stream_Terminated
/// Three packets containing this bit ... shall be sent by sources upon terminating /// Three packets containing this bit ... shall be sent by sources upon terminating
/// sourcing of a universe. /// sourcing of a universe.
@ -446,14 +443,17 @@ void Universe::tx_loop_()
/// > intervals of between 800mS and 1000mS. /// > intervals of between 800mS and 1000mS.
std::chrono::milliseconds keep_alive_interval(800); std::chrono::milliseconds keep_alive_interval(800);
// I don't fully understand the semantics of std::conditional_variable, // allocate the control variables used by the loop
// but it requires this mutex in the sleeping thread. bool enable = true; // at least 1 loop
std::mutex mtx; 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) while (enable || terminated_resend > 0)
{ {
// enforce strict minimum update times // 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) if (elapsed < minimum_update_time)
std::this_thread::sleep_for(minimum_update_time - elapsed); std::this_thread::sleep_for(minimum_update_time - elapsed);
@ -463,29 +463,30 @@ void Universe::tx_loop_()
tx_control_mutex_.unlock(); tx_control_mutex_.unlock();
if (enable) 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 else
{ {
setStatus(sACN_TERMINATED); // note the changed operating status
provenance_->options.stream_terminated = true; // set the stream_terminated bit 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
--terminated_resend; // stream_terminated must be sent 3 times sleep = minimum_update_time; // stay throttled up through the termination sequence
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
} }
// send the sACN message // send the sACN message