Skip to content

Commit

Permalink
add locked reference
Browse files Browse the repository at this point in the history
  • Loading branch information
facontidavide committed Nov 16, 2023
1 parent b9e73d9 commit 66e3385
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 0 deletions.
15 changes: 15 additions & 0 deletions data_tamer/include/data_tamer/channel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "data_tamer/values.hpp"
#include "data_tamer/data_sink.hpp"
#include "data_tamer/details/mutex.hpp"
#include "data_tamer/details/locked_reference.hpp"

#include <atomic>
#include <chrono>
Expand Down Expand Up @@ -59,6 +60,8 @@ class LoggedValue {
/// @brief get the stored value.
T get();

LockedRef<T, Mutex> getLockedReference();

/// @brief Disabling a LoggedValue means that we will not record it in the snapshot
void setEnabled(bool enabled);

Expand Down Expand Up @@ -362,4 +365,16 @@ T LoggedValue<T>::get()
return value_;
}

template<typename T> inline
LockedRef<T, Mutex> LoggedValue<T>::getLockedReference()
{
Mutex* mutex_ptr = nullptr;
if(auto chan = channel_.lock())
{
mutex_ptr = &chan->writeMutex();
}
return LockedRef<T, Mutex>(&value_, mutex_ptr);
}


} // namespace DataTamer
79 changes: 79 additions & 0 deletions data_tamer/include/data_tamer/details/locked_reference.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#pragma once

#include <memory>
#include <mutex>

namespace DataTamer
{
/**
* @brief The LockedRef class is used to share a pointer to an object
* and a mutex that protects the read/write access to that object.
*
* As long as the object remains in scope, the mutex is locked, therefore
* you must destroy this object as soon as the pointer was used.
*/
template <typename T, class Mutex>
class LockedRef {
public:

LockedRef() = default;

LockedRef(T* obj, Mutex* obj_mutex):
ref_(obj), mutex_(obj_mutex) {
mutex_->lock();
}

~LockedRef() {
if(mutex_) {
mutex_->unlock();
}
}

LockedRef(LockedRef const&) = delete;
LockedRef& operator=(LockedRef const&) = delete;

LockedRef(LockedRef && other) {
std::swap(ref_, other.ref_);
std::swap(mutex_, other.mutex_);
}

LockedRef& operator=(LockedRef&& other) {
std::swap(ref_, other.ref_);
std::swap(mutex_, other.mutex_);
}

operator bool() const {
return ref_ != nullptr;
}

void lock() {
if(mutex_) {
mutex_->lock();
}
}

void unlock() {
if(mutex_) {
mutex_->unlock();
}
}

bool empty() const {
return ref_ == nullptr;
}

const T& operator()() const{
return *ref_;
}

T& operator()() {
return *ref_;
}

private:
T* ref_ = nullptr;
Mutex* mutex_ = nullptr;
};


}

0 comments on commit 66e3385

Please sign in to comment.