引入强制执行的读写锁

This commit is contained in:
2024-07-10 02:58:42 +08:00
parent 90106f5abe
commit d52f02225f
4 changed files with 222 additions and 0 deletions

View File

@@ -0,0 +1,166 @@
// 版权所有 (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