-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlocked_resource.h
100 lines (80 loc) · 1.57 KB
/
locked_resource.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#ifndef __LOCKED_RESOURCE_H__
#define __LOCKED_RESOURCE_H__
#include <mutex>
#include <assert.h>
namespace zy{
template<typename T>
class ResourceHolder;
template<typename T>
class LockedResource
{
public:
template<typename ...Args>
LockedResource(Args&& ...args) : resource(std::forward<Args>(args)...)
{ }
ResourceHolder<T> get_resource_holder()
{
return ResourceHolder<T>(&lock, &resource);
}
protected:
std::mutex lock;
T resource;
};
template<typename T>
class ResourceHolder
{
public:
T* operator ->(){ return resource; }
public:
ResourceHolder(std::mutex* _lock, T* _resource) :
lock(_lock), resource(_resource)
{
assert(lock);
assert(resource);
lock->lock();
}
~ResourceHolder()
{
if (lock)
lock->unlock();
}
ResourceHolder(const ResourceHolder&) = delete;
ResourceHolder& operator=(const ResourceHolder&) = delete;
ResourceHolder(ResourceHolder&& rhs)
{
*this = std::move(rhs);
}
ResourceHolder& operator=(ResourceHolder&& rhs)
{
this->lock = rhs.lock;
rhs.lock = nullptr;
this->resource = rhs.resource;
rhs.resource = nullptr;
return *this;
}
protected:
std::mutex* lock;
T* resource;
};
template<typename T>
class LockedVariable
{
public:
T get()
{
std::lock_guard<std::mutex> lock_guard(lock);
return value;
}
template<typename U,
typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
void set(U&& _value)
{
std::lock_guard<std::mutex> lock_guard(lock);
value = std::forward<U>(_value);
}
protected:
T value;
std::mutex lock;
};
} /*namespace zy*/
#endif /*__LOCKED_RESOURCE_H__*/