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