1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef META_API_LOCKING_H
16 #define META_API_LOCKING_H
17
18 #include <meta/interface/intf_lockable.h>
19
META_BEGIN_NAMESPACE()20 META_BEGIN_NAMESPACE()
21
22 /**
23 * @brief Helper class to acquire write lock and release it end of the scope.
24 */
25 class InterfaceLock {
26 public:
27 META_NO_COPY(InterfaceLock)
28
29 explicit InterfaceLock(LockType type, const CORE_NS::IInterface* t) : type_(type), p_(interface_cast<ILockable>(t))
30 {
31 if (p_) {
32 if (type_ == LockType::UNIQUE_LOCK) {
33 p_->Lock();
34 } else if (type_ == LockType::SHARED_LOCK) {
35 p_->LockShared();
36 }
37 }
38 }
39 explicit InterfaceLock(LockType type, const CORE_NS::IInterface& t) : InterfaceLock(type, &t) {}
40 template<typename Type>
41 explicit InterfaceLock(LockType type, const BASE_NS::shared_ptr<Type>& t) : InterfaceLock(type, t.get())
42 {}
43
44 InterfaceLock(InterfaceLock&& l) noexcept : type_(l.type_), p_(l.p_)
45 {
46 l.p_ = nullptr;
47 }
48
49 InterfaceLock& operator=(InterfaceLock&& l) noexcept
50 {
51 type_ = l.type_;
52 p_ = l.p_;
53 l.p_ = nullptr;
54 return *this;
55 }
56
57 ~InterfaceLock()
58 {
59 if (p_) {
60 if (type_ == LockType::UNIQUE_LOCK) {
61 p_->Unlock();
62 } else if (type_ == LockType::SHARED_LOCK) {
63 p_->UnlockShared();
64 }
65 }
66 }
67
68 explicit operator bool() const
69 {
70 return p_ != nullptr;
71 }
72
73 private:
74 LockType type_;
75 const ILockable* p_;
76 };
77
78 /**
79 * @brief Helper class to acquire write lock and release it end of the scope.
80 */
81 class InterfaceUniqueLock {
82 public:
META_NO_COPY(InterfaceUniqueLock)83 META_NO_COPY(InterfaceUniqueLock)
84
85 explicit InterfaceUniqueLock(const CORE_NS::IInterface* t) : p_(interface_cast<ILockable>(t))
86 {
87 if (p_) {
88 p_->Lock();
89 }
90 }
InterfaceUniqueLock(const CORE_NS::IInterface & t)91 explicit InterfaceUniqueLock(const CORE_NS::IInterface& t) : InterfaceUniqueLock(&t) {}
92 template<typename Type>
InterfaceUniqueLock(const BASE_NS::shared_ptr<Type> & t)93 explicit InterfaceUniqueLock(const BASE_NS::shared_ptr<Type>& t) : InterfaceUniqueLock(t.get())
94 {}
95
InterfaceUniqueLock(InterfaceUniqueLock && l)96 InterfaceUniqueLock(InterfaceUniqueLock&& l) noexcept : p_(l.p_)
97 {
98 l.p_ = nullptr;
99 }
100
101 InterfaceUniqueLock& operator=(InterfaceUniqueLock&& l) noexcept
102 {
103 p_ = l.p_;
104 l.p_ = nullptr;
105 return *this;
106 }
107
~InterfaceUniqueLock()108 ~InterfaceUniqueLock()
109 {
110 if (p_) {
111 p_->Unlock();
112 }
113 }
114
115 explicit operator bool() const
116 {
117 return p_ != nullptr;
118 }
119
120 private:
121 const ILockable* p_;
122 };
123
124 /**
125 * @brief Helper class to acquire read lock and release it end of the scope.
126 */
127 class InterfaceSharedLock {
128 public:
META_NO_COPY(InterfaceSharedLock)129 META_NO_COPY(InterfaceSharedLock)
130
131 explicit InterfaceSharedLock(const CORE_NS::IInterface* t) : p_(interface_cast<ILockable>(t))
132 {
133 if (p_) {
134 p_->LockShared();
135 }
136 }
InterfaceSharedLock(const CORE_NS::IInterface & t)137 explicit InterfaceSharedLock(const CORE_NS::IInterface& t) : InterfaceSharedLock(&t) {}
138 template<typename Type>
InterfaceSharedLock(const BASE_NS::shared_ptr<Type> & t)139 explicit InterfaceSharedLock(const BASE_NS::shared_ptr<Type>& t) : InterfaceSharedLock(t.get())
140 {}
141
InterfaceSharedLock(InterfaceSharedLock && l)142 InterfaceSharedLock(InterfaceSharedLock&& l) noexcept : p_(l.p_)
143 {
144 l.p_ = nullptr;
145 }
146
147 InterfaceSharedLock& operator=(InterfaceSharedLock&& l) noexcept
148 {
149 p_ = l.p_;
150 l.p_ = nullptr;
151 return *this;
152 }
153
~InterfaceSharedLock()154 ~InterfaceSharedLock()
155 {
156 if (p_) {
157 p_->UnlockShared();
158 }
159 }
160
161 explicit operator bool() const
162 {
163 return p_ != nullptr;
164 }
165
166 private:
167 const ILockable* p_;
168 };
169
170 META_END_NAMESPACE()
171
172 #endif
173