Files
DataStruct/include/mutex/shared_mutex.h

167 lines
4.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 版权所有 (c) ling 保留所有权利。
// 除非另行说明否则仅允许在DataStruct中使用此文件中的代码。
//
// 由 ling 创建于 24-7-10.
//
#ifndef DATASTRUCT_SHARED_MUTEX_H_04
#define DATASTRUCT_SHARED_MUTEX_H_04
#include <shared_mutex>
namespace ling {
template<typename T>
class ResourceReadOnly;
template<typename T>
class ResourceCompletely;
/// 强制执行的读写锁
/// 当获取共享锁时,返回资源的只读代理
/// 仅在获取独占锁时,才返回资源的完全代理
/// 不管获取哪一个代理,都会在代理被释放时自动解除锁定
template<typename T, typename CT = const T>
class shared_mutex {
private:
std::shared_mutex mutex;
T resource;
public:
explicit shared_mutex(T &&value) : resource(value) {
}
shared_mutex(const shared_mutex &) = delete;
shared_mutex &operator=(const shared_mutex &) = delete;
ResourceReadOnly<CT> lock_shared() {
mutex.lock_shared();
return ResourceReadOnly<CT>(&mutex, &resource);
}
ResourceReadOnly<CT> try_lock_shared() {
if (mutex.try_lock_shared()) {
return ResourceReadOnly<CT>(&mutex, &resource);
}
return ResourceReadOnly<CT>();
}
ResourceCompletely<T> lock() {
mutex.lock();
return ResourceCompletely<T>(&mutex, &resource);
}
ResourceCompletely<T> try_lock() {
if (mutex.try_lock()) {
return ResourceCompletely<T>(&mutex, &resource);
}
return ResourceCompletely<T>();
}
};
/// 资源的读写代理
template<typename T>
class ResourceCompletely {
private:
std::shared_mutex *mutex;
T *resource;
public:
ResourceCompletely(std::shared_mutex *mutex, T *resource)
: mutex(mutex), resource(resource) {
}
ResourceCompletely()
: mutex(nullptr), resource(nullptr) {
}
ResourceCompletely(const ResourceCompletely &) = delete;
ResourceCompletely(ResourceCompletely &&) = delete;
ResourceCompletely &operator=(const ResourceCompletely &) = delete;
ResourceCompletely &operator=(ResourceCompletely &&) = delete;
~ResourceCompletely() {
if (mutex != nullptr)
mutex->unlock();
}
void unlock() {
mutex->unlock();
mutex = nullptr;
resource = nullptr;
}
[[nodiscard]] bool isResource() const {
return resource != nullptr;
}
explicit operator bool() const noexcept {
return isResource();
}
T *operator->() {
return resource;
}
};
/// 资源的只读代理
template<typename T>
class ResourceReadOnly {
private:
std::shared_mutex *mutex;
T *resource;
public:
ResourceReadOnly(std::shared_mutex *mutex, const T *const resource)
: mutex(mutex), resource(resource) {
}
ResourceReadOnly()
: mutex(nullptr), resource(nullptr) {
}
ResourceReadOnly(const ResourceReadOnly &) = delete;
ResourceReadOnly(ResourceReadOnly &&) = delete;
ResourceReadOnly &operator=(const ResourceReadOnly &) = delete;
ResourceReadOnly &operator=(ResourceReadOnly &&) = delete;
~ResourceReadOnly() {
if (mutex != nullptr)
mutex->unlock_shared();
}
void unlock_shared() {
mutex->unlock_shared();
mutex = nullptr;
resource = nullptr;
}
[[nodiscard]] bool isResource() const {
return resource != nullptr;
}
explicit operator bool() const noexcept {
return isResource();
}
const T *operator->() const {
return resource;
}
};
} // ling
#endif //DATASTRUCT_SHARED_MUTEX_H_04