use a shared mutex to lock the dimmer data
This commit is contained in:
parent
b7ca5c36f5
commit
f1d3fe0256
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue