Refactored template class for synchronised resources

This commit is contained in:
Nav
2023-06-02 00:16:58 +01:00
parent 10611d3ad3
commit 80cf6930cc
9 changed files with 146 additions and 135 deletions

View File

@@ -1,42 +0,0 @@
#pragma once
#include <mutex>
namespace Bloom
{
/**
* Template for synchronization safe types.
*
* Just a convenient template that allows us to create thread safe types without having to write
* the bloat of mutexes, unique_locks, etc etc.
*
* @tparam Type
*/
template<typename Type>
class SyncSafe
{
public:
SyncSafe() = default;
explicit SyncSafe(Type value)
: value(value)
{}
void setValue(const Type& value) {
auto lock = std::unique_lock(this->mutex);
this->value = value;
}
Type& getValue() {
return this->value;
}
std::unique_lock<std::mutex> acquireLock() {
return std::unique_lock(this->mutex);
}
private:
Type value;
std::mutex mutex;
};
}

View File

@@ -0,0 +1,78 @@
#pragma once
#include <mutex>
#include <utility>
namespace Bloom
{
/**
* Wrapper for synchronised access to a resource.
*
* @tparam Type
*/
template<typename Type>
class Synchronised
{
public:
class Accessor
{
public:
constexpr Accessor(std::mutex& mutex, Type& value)
: lock(std::unique_lock(mutex))
, value(value)
{}
constexpr Type* operator -> () noexcept {
return &(this->value);
}
constexpr const Type* operator -> () const noexcept {
return &(this->value);
}
constexpr Type& operator * () noexcept {
return this->value;
}
constexpr const Type& operator * () const noexcept {
return this->value;
}
private:
std::unique_lock<std::mutex> lock;
Type& value;
};
Synchronised() = default;
explicit Synchronised(Type value)
: value(std::move(value))
{}
Accessor accessor() {
return Accessor(this->mutex, this->value);
}
/**
* Don't use this unless you already hold a raw (not managed by an Accessor) lock to the contained value.
*
* This should only be used in instances where you need to hold a raw lock, like in the `stop_waiting`
* predicate function for a call to std::condition_variable::wait().
*
* In all other instances, you should use Synchronised::accessor().
*
* @return
*/
Type& unsafeReference() {
return this->value;
}
std::unique_lock<std::mutex> lock() {
return std::unique_lock(this->mutex);
}
private:
Type value;
std::mutex mutex;
};
}