1
0
Fork 0

use a shared mutex to lock the dimmer data

This commit is contained in:
Kevin Matz 2022-12-09 10:28:02 -05:00
parent b7ca5c36f5
commit f1d3fe0256
4 changed files with 31 additions and 24 deletions

View File

@ -23,6 +23,8 @@
*/
#include "universe.h"
#include <mutex>
namespace DMX {
@ -90,10 +92,10 @@ uint8_t Universe::status()
*/
uint8_t Universe::slot(const uint16_t address)
{
std::lock_guard<std::mutex> lck (null_start_mutex);
std::shared_lock lck(null_start_mutex);
try {
return null_start_data.at(address);
} catch (std::out_of_range const&) {
} catch (...) {
return 0;
}
}
@ -129,9 +131,10 @@ void Universe::setValue(const uint16_t start, const uint16_t footprint,
if (start < 1 || start + footprint > null_start_data.size())
return;
null_start_mutex.lock();
std::copy_n(data, footprint, null_start_data.begin() + start);
null_start_mutex.unlock();
{
std::unique_lock lk_data(null_start_mutex);
std::copy_n(data, footprint, null_start_data.begin() + start);
}
setStatus(DMX_ACTIVE);
last_updated_ = std::chrono::system_clock::now();
@ -167,15 +170,14 @@ void Universe::setData(const std::vector<uint8_t>& data)
// accept variable lenth input, but never more than the limit
const auto max_length = null_start_data.size();
const auto length = data.size() < max_length ? data.size() : max_length;
null_start_mutex.lock(); // take the lock
if (length < max_length)
null_start_data.fill(0); // wipe old data
std::copy_n(data.cbegin(), length, null_start_data.begin()); // copy new data
null_start_mutex.unlock(); // free the lock
rx_timeout_(true); // update rx times
do_callbacks_(cb_dataChange); // run callbacks
{
std::unique_lock lk_data(null_start_mutex);
if (length < max_length)
null_start_data.fill(0); // wipe old data
std::copy_n(data.cbegin(), length, null_start_data.begin()); // copy new data
}
rx_timeout_(true); // update rx times
do_callbacks_(cb_dataChange); // run callbacks
}

View File

@ -29,7 +29,7 @@
#include <cstdint>
#include <functional>
#include <memory>
#include <mutex>
#include <shared_mutex>
#include <queue>
#include <vector>
@ -76,7 +76,7 @@ class Universe {
inline void doStatusCallbacks() {do_callbacks_(cb_statusChange);} //!< Status Change Callbacks
DimmerData null_start_data; //!< NULL Start Code data
mutable std::mutex null_start_mutex; //!< memory protect Null Start data
mutable std::shared_mutex null_start_mutex; //!< memory protect Null Start data
std::chrono::system_clock::time_point last_updated_; //!< time of the latest update
private:

View File

@ -230,9 +230,10 @@ void Universe::setValue (const uint16_t start, const uint16_t footprint,
// get a copy of the current values
uint8_t og[footprint];
null_start_mutex.lock();
std::copy_n(std::begin(null_start_data) + start, footprint, og);
null_start_mutex.unlock();
{
std::unique_lock lk_data(null_start_mutex);
std::copy_n(std::begin(null_start_data) + start, footprint, og);
}
// data not changed!
if (memcmp(data, og, footprint) == 0)

View File

@ -25,6 +25,8 @@
#include "universe.h"
#include "source.h"
#include <shared_mutex>
namespace sACN {
/**
@ -139,15 +141,14 @@ void UniverseSender::loop_()
if (enable_)
{
mUniverse->setStatus(Universe::DMX_ACTIVE);
mUniverse->null_start_mutex.lock();
new_data = (mUniverse->null_start_data != last_null_data);
std::shared_lock lk_data(mUniverse->null_start_mutex);
new_data = (mUniverse->null_start_data != last_data_);
if (new_data)
{
last_null_data = mUniverse->null_start_data;
last_data_ = mUniverse->null_start_data;
retransmission_count = 0;
update_dmp_();
}
mUniverse->null_start_mutex.unlock();
if (++retransmission_count > 3)
{
retransmission_count = 3; // prevent counter from overflowing
@ -197,7 +198,10 @@ void UniverseSender::update_dmp_()
// property data
std::vector<octet> pd;
std::copy_n(mUniverse->null_start_data.begin(), pr.count, std::back_inserter(pd));
{
std::shared_lock lk_data(mUniverse->null_start_mutex);
std::copy_n(mUniverse->null_start_data.begin(), pr.count, std::back_inserter(pd));
}
// data segment
auto addrlst = std::make_shared<ACN::DMP::address_pair_list>(*addrtyp);