• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright 2018, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #ifndef KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_CONCURRENCY_H_
19 #define KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_CONCURRENCY_H_
20 
21 #include <type_traits>
22 
23 namespace keystore {
24 
25 template <typename LockedType> class UnlockProxyLockHelper {
26   private:
27     std::function<void(LockedType*)> unlock_;
28     LockedType* value_;
29 
30   public:
31     using lockedType = LockedType;
UnlockProxyLockHelper()32     UnlockProxyLockHelper() : value_(nullptr) {}
UnlockProxyLockHelper(LockedType * value,std::function<void (LockedType *)> && unlock)33     UnlockProxyLockHelper(LockedType* value, std::function<void(LockedType*)>&& unlock)
34         : unlock_(std::move(unlock)), value_(value) {}
~UnlockProxyLockHelper()35     ~UnlockProxyLockHelper() {
36         if (unlock_) unlock_(value_);
37     }
UnlockProxyLockHelper(UnlockProxyLockHelper && rhs)38     UnlockProxyLockHelper(UnlockProxyLockHelper&& rhs)
39         : unlock_(std::move(rhs.unlock_)), value_(rhs.value_) {
40         rhs.value_ = nullptr;
41         rhs.unlock_ = {};
42     }
43     UnlockProxyLockHelper& operator=(UnlockProxyLockHelper&& rhs) {
44         if (this != &rhs) {
45             UnlockProxyLockHelper dummy(std::move(*this));
46             unlock_ = std::move(rhs.unlock_);
47             value_ = std::move(rhs.value_);
48             rhs.value_ = nullptr;
49             rhs.unlock_ = {};
50         }
51         return *this;
52     }
53     UnlockProxyLockHelper(const UnlockProxyLockHelper& rhs) = delete;
54     UnlockProxyLockHelper& operator=(const UnlockProxyLockHelper& rhs) = delete;
55 
56     template <typename T = LockedType>
value()57     std::enable_if_t<!std::is_const<LockedType>::value, T*> value() {
58         return value_;
59     }
value()60     const LockedType* value() const { return value_; }
61 };
62 
63 template <typename LockedType, typename MutexType, template <typename> class GuardType>
64 class MutexProxyLockHelper {
65   private:
66     GuardType<MutexType> lock_;
67     LockedType* value_;
68 
69   public:
70     using lockedType = LockedType;
MutexProxyLockHelper()71     MutexProxyLockHelper() : value_(nullptr) {}
MutexProxyLockHelper(LockedType * value,GuardType<MutexType> && lock)72     MutexProxyLockHelper(LockedType* value, GuardType<MutexType>&& lock)
73         : lock_(std::move(lock)), value_(value) {}
74 
75     template <typename T = LockedType>
value()76     std::enable_if_t<!std::is_const<LockedType>::value, T*> value() {
77         return value_;
78     }
value()79     const LockedType* value() const { return value_; }
80 };
81 
82 template <typename Implementation> class ProxyLock {
83   private:
84     Implementation impl_;
85 
86   public:
ProxyLock()87     ProxyLock() : impl_() {}
88     // NOLINTNEXTLINE(google-explicit-constructor)
ProxyLock(Args &&...args)89     template <typename... Args> ProxyLock(Args&&... args) : impl_{std::forward<Args>(args)...} {}
ProxyLock(Implementation && impl)90     explicit ProxyLock(Implementation&& impl) : impl_(std::move(impl)) {}
91     explicit operator bool() const { return impl_.value() != nullptr; }
92 
93     template <typename T = typename Implementation::lockedType>
94     std::enable_if_t<!std::is_const<typename Implementation::lockedType>::value, T*> operator->() {
95         return impl_.value();
96     }
97 
98     template <typename T = typename Implementation::lockedType>
99     std::enable_if_t<!std::is_const<typename Implementation::lockedType>::value, T&> operator*() {
100         return *impl_.value();
101     }
102 
103     const std::remove_const_t<typename Implementation::lockedType>* operator->() const {
104         return impl_.value();
105     }
106 
107     const std::remove_const_t<typename Implementation::lockedType>& operator*() const {
108         return *impl_.value();
109     }
110 };
111 
112 }  // namespace keystore
113 
114 #endif  // KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_CONCURRENCY_H_
115