Refactored template class for synchronised resources
This commit is contained in:
@@ -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;
|
||||
};
|
||||
}
|
||||
78
src/Helpers/Synchronised.hpp
Normal file
78
src/Helpers/Synchronised.hpp
Normal 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;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user