-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathClassLevelLock.h
More file actions
105 lines (89 loc) · 2.9 KB
/
ClassLevelLock.h
File metadata and controls
105 lines (89 loc) · 2.9 KB
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
101
102
103
104
105
/*
* ClassLevelLock.h
*
* Created on: Nov 13, 2021
* Author: <a href="mailto:damirlj@yahoo.com">Damir Ljubic</a>
*/
#ifndef AIRPLAYSERVICE_CLASSLEVELLOCK_H
#define AIRPLAYSERVICE_CLASSLEVELLOCK_H
#include <mutex>
namespace utils::locking
{
/**
*
* Policy-based design.
* For a different type of the host provides different type of class-level lock.
* All instances of the class shared the same locking mechanism (mutex).
*
* usage:
*
* template <typename LockingPolicy>
* class Host : private LockingPolicy
* {
* public:
* void f()
* {
* typename LockingPolicy::Lock lock{*this};
* ...
* }
* };
*
*/
class ClassLevelLock
{
private:
class Initializer
{
public:
using lock_type = std::mutex;
static Initializer& get()
{
static Initializer initializer;
return initializer;
}
lock_type& locker() { return m_mutex; }
Initializer(const Initializer&) = delete;
Initializer& operator=(const Initializer&) = delete;
Initializer(Initializer&& ) = delete;
Initializer& operator=(Initializer&&) = delete;
private:
Initializer() = default;
private:
mutable lock_type m_mutex;
};
public:
class Lock;
friend class Lock;
/**
* All policy implementations refer the same inner Lock class (T::Lock).
* Internal class which implements java-like the common interface for all
* locking policies, so that can be instantiated as
* `typename T::Lock lock{};`, and used as scope lock - RAII idiom, or
* in case used with other locking policy
* `typename T::Lock lock{*this};`
*
*/
class Lock final
{
public:
Lock()
{
auto& initializer = Initializer::get();
initializer.locker().lock();
}
/**
* For being consistent with other
* locking policies
*/
explicit Lock(const ClassLevelLock& ) : Lock()
{
}
~Lock()
{
auto& initializer = Initializer::get();
initializer.locker().unlock();
}
};//Lock
};//
}//namespace
#endif //AIRPLAYSERVICE_CLASSLEVELLOCK_H