Commit 78cd0ec8 authored by Aaryaman Sagar's avatar Aaryaman Sagar Committed by Facebook Github Bot

Cut LockedGuardPtr and its variants

Summary:
The compiler will likely remove the branch on destruction because
it's never used

Reviewed By: yfeldblum

Differential Revision: D8651868

fbshipit-source-id: ef16b9d11569f72aa0fa89cb6aa2450a58d783e7
parent 4029908d
...@@ -46,8 +46,6 @@ template <class LockedType, class Mutex, class LockPolicy> ...@@ -46,8 +46,6 @@ template <class LockedType, class Mutex, class LockPolicy>
class LockedPtrBase; class LockedPtrBase;
template <class LockedType, class LockPolicy> template <class LockedType, class LockPolicy>
class LockedPtr; class LockedPtr;
template <class LockedType, class LockPolicy = LockPolicyExclusive>
class LockedGuardPtr;
/** /**
* Public version of LockInterfaceDispatcher that contains the MutexLevel enum * Public version of LockInterfaceDispatcher that contains the MutexLevel enum
...@@ -171,12 +169,6 @@ class SynchronizedBase<Subclass, detail::MutexLevel::SHARED> { ...@@ -171,12 +169,6 @@ class SynchronizedBase<Subclass, detail::MutexLevel::SHARED> {
return ConstLockedPtr(static_cast<const Subclass*>(this), timeout); return ConstLockedPtr(static_cast<const Subclass*>(this), timeout);
} }
/*
* Note: C++ 17 adds guaranteed copy elision. (http://wg21.link/P0135)
* Once compilers support this, it would be nice to add wguard() and rguard()
* methods that return LockedGuardPtr objects.
*/
/** /**
* Invoke a function while holding the lock exclusively. * Invoke a function while holding the lock exclusively.
* *
...@@ -193,15 +185,11 @@ class SynchronizedBase<Subclass, detail::MutexLevel::SHARED> { ...@@ -193,15 +185,11 @@ class SynchronizedBase<Subclass, detail::MutexLevel::SHARED> {
*/ */
template <class Function> template <class Function>
auto withWLock(Function&& function) { auto withWLock(Function&& function) {
LockedGuardPtr<Subclass, LockPolicyExclusive> guardPtr( return function(*wlock());
static_cast<Subclass*>(this));
return function(*guardPtr);
} }
template <class Function> template <class Function>
auto withWLock(Function&& function) const { auto withWLock(Function&& function) const {
LockedGuardPtr<const Subclass, LockPolicyExclusive> guardPtr( return function(*wlock());
static_cast<const Subclass*>(this));
return function(*guardPtr);
} }
/** /**
...@@ -230,9 +218,7 @@ class SynchronizedBase<Subclass, detail::MutexLevel::SHARED> { ...@@ -230,9 +218,7 @@ class SynchronizedBase<Subclass, detail::MutexLevel::SHARED> {
*/ */
template <class Function> template <class Function>
auto withRLock(Function&& function) const { auto withRLock(Function&& function) const {
LockedGuardPtr<const Subclass, LockPolicyShared> guardPtr( return function(*rlock());
static_cast<const Subclass*>(this));
return function(*guardPtr);
} }
template <class Function> template <class Function>
...@@ -255,10 +241,6 @@ class SynchronizedBase<Subclass, detail::MutexLevel::UPGRADE> ...@@ -255,10 +241,6 @@ class SynchronizedBase<Subclass, detail::MutexLevel::UPGRADE>
using UpgradeLockedPtr = ::folly::LockedPtr<Subclass, LockPolicyUpgrade>; using UpgradeLockedPtr = ::folly::LockedPtr<Subclass, LockPolicyUpgrade>;
using ConstUpgradeLockedPtr = using ConstUpgradeLockedPtr =
::folly::LockedPtr<const Subclass, LockPolicyUpgrade>; ::folly::LockedPtr<const Subclass, LockPolicyUpgrade>;
using UpgradeLockedGuardPtr =
::folly::LockedGuardPtr<Subclass, LockPolicyUpgrade>;
using ConstUpgradeLockedGuardPtr =
::folly::LockedGuardPtr<const Subclass, LockPolicyUpgrade>;
using TryUpgradeLockedPtr = using TryUpgradeLockedPtr =
::folly::LockedPtr<Subclass, LockPolicyTryUpgrade>; ::folly::LockedPtr<Subclass, LockPolicyTryUpgrade>;
...@@ -330,8 +312,7 @@ class SynchronizedBase<Subclass, detail::MutexLevel::UPGRADE> ...@@ -330,8 +312,7 @@ class SynchronizedBase<Subclass, detail::MutexLevel::UPGRADE>
*/ */
template <class Function> template <class Function>
auto withULock(Function&& function) const { auto withULock(Function&& function) const {
ConstUpgradeLockedGuardPtr guardPtr(static_cast<const Subclass*>(this)); return function(*ulock());
return function(*guardPtr);
} }
/** /**
...@@ -421,12 +402,6 @@ class SynchronizedBase<Subclass, detail::MutexLevel::UNIQUE> { ...@@ -421,12 +402,6 @@ class SynchronizedBase<Subclass, detail::MutexLevel::UNIQUE> {
return ConstLockedPtr(static_cast<const Subclass*>(this), timeout); return ConstLockedPtr(static_cast<const Subclass*>(this), timeout);
} }
/*
* Note: C++ 17 adds guaranteed copy elision. (http://wg21.link/P0135)
* Once compilers support this, it would be nice to add guard() methods that
* return LockedGuardPtr objects.
*/
/** /**
* Invoke a function while holding the lock. * Invoke a function while holding the lock.
* *
...@@ -443,15 +418,11 @@ class SynchronizedBase<Subclass, detail::MutexLevel::UNIQUE> { ...@@ -443,15 +418,11 @@ class SynchronizedBase<Subclass, detail::MutexLevel::UNIQUE> {
*/ */
template <class Function> template <class Function>
auto withLock(Function&& function) { auto withLock(Function&& function) {
LockedGuardPtr<Subclass, LockPolicyExclusive> guardPtr( return function(*lock());
static_cast<Subclass*>(this));
return function(*guardPtr);
} }
template <class Function> template <class Function>
auto withLock(Function&& function) const { auto withLock(Function&& function) const {
LockedGuardPtr<const Subclass, LockPolicyExclusive> guardPtr( return function(*lock());
static_cast<const Subclass*>(this));
return function(*guardPtr);
} }
/** /**
...@@ -798,8 +769,6 @@ struct Synchronized : public SynchronizedBase< ...@@ -798,8 +769,6 @@ struct Synchronized : public SynchronizedBase<
friend class folly::LockedPtrBase; friend class folly::LockedPtrBase;
template <class LockedType, class LockPolicy> template <class LockedType, class LockPolicy>
friend class folly::LockedPtr; friend class folly::LockedPtr;
template <class LockedType, class LockPolicy>
friend class folly::LockedGuardPtr;
/** /**
* Helper constructors to enable Synchronized for * Helper constructors to enable Synchronized for
...@@ -1525,62 +1494,6 @@ class LockedPtr : public LockedPtrBase< ...@@ -1525,62 +1494,6 @@ class LockedPtr : public LockedPtrBase<
} }
}; };
/**
* LockedGuardPtr is a simplified version of LockedPtr.
*
* It is non-movable, and supports fewer features than LockedPtr. However, it
* is ever-so-slightly more performant than LockedPtr. (The destructor can
* unconditionally release the lock, without requiring a conditional branch.)
*
* The relationship between LockedGuardPtr and LockedPtr is similar to that
* between std::lock_guard and std::unique_lock.
*/
template <class SynchronizedType, class LockPolicy>
class LockedGuardPtr {
private:
// CDataType is the DataType with the appropriate const-qualification
using CDataType = detail::SynchronizedDataType<SynchronizedType>;
public:
using DataType = typename SynchronizedType::DataType;
using MutexType = typename SynchronizedType::MutexType;
using Synchronized = typename std::remove_const<SynchronizedType>::type;
LockedGuardPtr() = delete;
/**
* Takes a Synchronized<T> and locks it.
*/
explicit LockedGuardPtr(SynchronizedType* parent) : parent_(parent) {
LockPolicy::lock(parent_->mutex_);
}
/**
* Destructor releases.
*/
~LockedGuardPtr() {
LockPolicy::unlock(parent_->mutex_);
}
/**
* Access the locked data.
*/
CDataType* operator->() const {
return &parent_->datum_;
}
/**
* Access the locked data.
*/
CDataType& operator*() const {
return parent_->datum_;
}
private:
// This is the entire state of LockedGuardPtr.
SynchronizedType* const parent_{nullptr};
};
/** /**
* Acquire locks on many lockables or synchronized instances in such a way * Acquire locks on many lockables or synchronized instances in such a way
* that the sequence of calls within the function does not cause deadlocks. * that the sequence of calls within the function does not cause deadlocks.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment