167 lines
4.0 KiB
C++
167 lines
4.0 KiB
C++
// 版权所有 (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
|