blob: 039ca3135a157f3348b9a488515243f811ac2f0c [file] [log] [blame]
/*
**
** Copyright 2018, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#ifndef KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_CONCURRENCY_H_
#define KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_CONCURRENCY_H_
#include <type_traits>
namespace keystore {
template <typename LockedType> class UnlockProxyLockHelper {
private:
std::function<void(LockedType*)> unlock_;
LockedType* value_;
public:
using lockedType = LockedType;
UnlockProxyLockHelper() : value_(nullptr) {}
UnlockProxyLockHelper(LockedType* value, std::function<void(LockedType*)>&& unlock)
: unlock_(std::move(unlock)), value_(value) {}
~UnlockProxyLockHelper() {
if (unlock_) unlock_(value_);
}
UnlockProxyLockHelper(UnlockProxyLockHelper&& rhs)
: unlock_(std::move(rhs.unlock_)), value_(rhs.value_) {
rhs.value_ = nullptr;
rhs.unlock_ = {};
}
UnlockProxyLockHelper& operator=(UnlockProxyLockHelper&& rhs) {
if (this != &rhs) {
UnlockProxyLockHelper dummy(std::move(*this));
unlock_ = std::move(rhs.unlock_);
value_ = std::move(rhs.value_);
rhs.value_ = nullptr;
rhs.unlock_ = {};
}
return *this;
}
UnlockProxyLockHelper(const UnlockProxyLockHelper& rhs) = delete;
UnlockProxyLockHelper& operator=(const UnlockProxyLockHelper& rhs) = delete;
template <typename T = LockedType>
std::enable_if_t<!std::is_const<LockedType>::value, T*> value() {
return value_;
}
const LockedType* value() const { return value_; }
};
template <typename LockedType, typename MutexType, template <typename> class GuardType>
class MutexProxyLockHelper {
private:
GuardType<MutexType> lock_;
LockedType* value_;
public:
using lockedType = LockedType;
MutexProxyLockHelper() : value_(nullptr) {}
MutexProxyLockHelper(LockedType* value, GuardType<MutexType>&& lock)
: lock_(std::move(lock)), value_(value) {}
template <typename T = LockedType>
std::enable_if_t<!std::is_const<LockedType>::value, T*> value() {
return value_;
}
const LockedType* value() const { return value_; }
};
template <typename Implementation> class ProxyLock {
private:
Implementation impl_;
public:
ProxyLock() : impl_() {}
// NOLINTNEXTLINE(google-explicit-constructor)
template <typename... Args> ProxyLock(Args&&... args) : impl_{std::forward<Args>(args)...} {}
explicit ProxyLock(Implementation&& impl) : impl_(std::move(impl)) {}
explicit operator bool() const { return impl_.value() != nullptr; }
template <typename T = typename Implementation::lockedType>
std::enable_if_t<!std::is_const<typename Implementation::lockedType>::value, T*> operator->() {
return impl_.value();
}
template <typename T = typename Implementation::lockedType>
std::enable_if_t<!std::is_const<typename Implementation::lockedType>::value, T&> operator*() {
return *impl_.value();
}
const std::remove_const_t<typename Implementation::lockedType>* operator->() const {
return impl_.value();
}
const std::remove_const_t<typename Implementation::lockedType>& operator*() const {
return *impl_.value();
}
};
} // namespace keystore
#endif // KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_CONCURRENCY_H_