Add MutexProtectedObject
This commit is contained in:
111
openVulkanoCpp/Data/Concurent/MutexProtectedObject.hpp
Normal file
111
openVulkanoCpp/Data/Concurent/MutexProtectedObject.hpp
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Spintex.hpp"
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
|
||||
namespace openVulkanoCpp
|
||||
{
|
||||
template<typename T, typename MUTEX = std::mutex>
|
||||
class MutexProtectedObject
|
||||
{
|
||||
protected:
|
||||
T object;
|
||||
MUTEX mutex;
|
||||
|
||||
public:
|
||||
class Accessor
|
||||
{
|
||||
std::unique_lock<MUTEX> lock;
|
||||
T& ref;
|
||||
|
||||
public:
|
||||
Accessor(MUTEX& m, T& obj)
|
||||
: lock(m), ref(obj)
|
||||
{}
|
||||
|
||||
T* operator->() { return &ref; }
|
||||
|
||||
T& Get() { return ref; }
|
||||
};
|
||||
|
||||
MutexProtectedObject() = default;
|
||||
|
||||
MutexProtectedObject(const T& initValue) : object(initValue) {}
|
||||
|
||||
template<typename... Args>
|
||||
MutexProtectedObject(Args&&... args)
|
||||
: object(std::forward<Args>(args)...)
|
||||
{}
|
||||
|
||||
MutexProtectedObject(const MutexProtectedObject&) = delete;
|
||||
|
||||
Accessor Access()
|
||||
{
|
||||
return Accessor(mutex, object);
|
||||
}
|
||||
|
||||
MutexProtectedObject& operator =(const T& value)
|
||||
{
|
||||
Accessor accessor = Access();
|
||||
object = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator T()
|
||||
{
|
||||
Accessor accessor = Access();
|
||||
return accessor.Get();
|
||||
}
|
||||
|
||||
const T& UnsafeAccess() const { return object; }
|
||||
};
|
||||
|
||||
template<typename T> using SpintexProtectedObject = MutexProtectedObject<T, Spintex>;
|
||||
|
||||
template<typename T, typename MUTEX = std::shared_mutex>
|
||||
class SharedMutexProtectedObject : public MutexProtectedObject<T, MUTEX>
|
||||
{
|
||||
public:
|
||||
class SharedAccessor
|
||||
{
|
||||
std::shared_lock<MUTEX> lock;
|
||||
T& ref;
|
||||
public:
|
||||
SharedAccessor(MUTEX& m, T& obj)
|
||||
: lock(m), ref(obj)
|
||||
{}
|
||||
|
||||
|
||||
const T* operator->() const { return &ref; }
|
||||
|
||||
const T& Get() const { return ref; }
|
||||
|
||||
T* operator->() { return &ref; }
|
||||
|
||||
T& Get() { return ref; }
|
||||
};
|
||||
|
||||
SharedMutexProtectedObject() = default;
|
||||
|
||||
SharedMutexProtectedObject(const T& initValue) : MutexProtectedObject<T, MUTEX>(initValue) {}
|
||||
|
||||
template<typename... Args>
|
||||
SharedMutexProtectedObject(Args&&... args)
|
||||
: MutexProtectedObject<T, MUTEX>(std::forward<Args>(args)...)
|
||||
{}
|
||||
|
||||
SharedMutexProtectedObject(const SharedMutexProtectedObject&) = delete;
|
||||
|
||||
SharedAccessor SharedAccess()
|
||||
{
|
||||
return SharedAccessor(MutexProtectedObject<T, MUTEX>::mutex, MutexProtectedObject<T, MUTEX>::object);
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user