Commit b805d853 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

revise Synchronized LockedPtr to use lock types

Summary:
Use `std::unique_lock`, `std::shared_lock`, and `folly::upgrade_lock`. There are two reasons:

* Makes generic the use of `std::unique_lock` with `std::mutex`, which is currently special-cased.
* Permits specializations of `std::unique_lock` and the other lock types to be found automatically.

In particular, this permits the use of `Synchronized<T, DistributedMutex>`, which is only proxy-lockable and not lockable.

Reviewed By: simpkins

Differential Revision: D28705607

fbshipit-source-id: 48daa2910ce16ee4fde6f5ea629a41d9768f3c87
parent 424e569f
...@@ -25,9 +25,12 @@ ...@@ -25,9 +25,12 @@
#pragma once #pragma once
#include <chrono> #include <chrono>
#include <mutex>
#include <shared_mutex>
#include <type_traits> #include <type_traits>
#include <folly/functional/Invoke.h> #include <folly/functional/Invoke.h>
#include <folly/synchronization/Lock.h>
// Android, OSX, and Cygwin don't have timed mutexes // Android, OSX, and Cygwin don't have timed mutexes
#if defined(ANDROID) || defined(__ANDROID__) || defined(__APPLE__) || \ #if defined(ANDROID) || defined(__ANDROID__) || defined(__APPLE__) || \
...@@ -244,6 +247,8 @@ struct LockTraitsImpl<Mutex, MutexLevel::UPGRADE, false> ...@@ -244,6 +247,8 @@ struct LockTraitsImpl<Mutex, MutexLevel::UPGRADE, false>
template <class Mutex> template <class Mutex>
struct LockTraitsImpl<Mutex, MutexLevel::UNIQUE, true> struct LockTraitsImpl<Mutex, MutexLevel::UNIQUE, true>
: public LockTraitsImpl<Mutex, MutexLevel::UNIQUE, false> { : public LockTraitsImpl<Mutex, MutexLevel::UNIQUE, false> {
using lock_type = std::unique_lock<Mutex>;
static constexpr bool is_timed{true}; static constexpr bool is_timed{true};
static constexpr bool is_shared{false}; static constexpr bool is_shared{false};
static constexpr bool is_upgrade{false}; static constexpr bool is_upgrade{false};
...@@ -269,6 +274,8 @@ template <class Mutex> ...@@ -269,6 +274,8 @@ template <class Mutex>
struct LockTraitsImpl<Mutex, MutexLevel::SHARED, true> struct LockTraitsImpl<Mutex, MutexLevel::SHARED, true>
: public LockTraitsImpl<Mutex, MutexLevel::SHARED, false>, : public LockTraitsImpl<Mutex, MutexLevel::SHARED, false>,
public LockTraitsImpl<Mutex, MutexLevel::UNIQUE, true> { public LockTraitsImpl<Mutex, MutexLevel::UNIQUE, true> {
using lock_type = std::shared_lock<Mutex>;
static constexpr bool is_timed{true}; static constexpr bool is_timed{true};
static constexpr bool is_shared{true}; static constexpr bool is_shared{true};
static constexpr bool is_upgrade{false}; static constexpr bool is_upgrade{false};
...@@ -300,6 +307,8 @@ template <class Mutex> ...@@ -300,6 +307,8 @@ template <class Mutex>
struct LockTraitsImpl<Mutex, MutexLevel::UPGRADE, true> struct LockTraitsImpl<Mutex, MutexLevel::UPGRADE, true>
: public LockTraitsImpl<Mutex, MutexLevel::UPGRADE, false>, : public LockTraitsImpl<Mutex, MutexLevel::UPGRADE, false>,
public LockTraitsImpl<Mutex, MutexLevel::SHARED, true> { public LockTraitsImpl<Mutex, MutexLevel::SHARED, true> {
using lock_type = upgrade_lock<Mutex>;
static constexpr bool is_timed{true}; static constexpr bool is_timed{true};
static constexpr bool is_shared{true}; static constexpr bool is_shared{true};
static constexpr bool is_upgrade{true}; static constexpr bool is_upgrade{true};
...@@ -349,6 +358,9 @@ struct LockTraitsImpl<Mutex, MutexLevel::UPGRADE, true> ...@@ -349,6 +358,9 @@ struct LockTraitsImpl<Mutex, MutexLevel::UPGRADE, true>
*/ */
template <template <typename...> class LockTraits> template <template <typename...> class LockTraits>
struct UnlockPolicyExclusive { struct UnlockPolicyExclusive {
template <typename Mutex>
using lock_type = std::unique_lock<Mutex>;
constexpr static bool allows_concurrent_access = false; constexpr static bool allows_concurrent_access = false;
template <typename Mutex> template <typename Mutex>
...@@ -358,6 +370,9 @@ struct UnlockPolicyExclusive { ...@@ -358,6 +370,9 @@ struct UnlockPolicyExclusive {
}; };
template <template <typename...> class LockTraits> template <template <typename...> class LockTraits>
struct UnlockPolicyShared { struct UnlockPolicyShared {
template <typename Mutex>
using lock_type = std::shared_lock<Mutex>;
constexpr static bool allows_concurrent_access = true; constexpr static bool allows_concurrent_access = true;
template <typename Mutex> template <typename Mutex>
...@@ -367,6 +382,9 @@ struct UnlockPolicyShared { ...@@ -367,6 +382,9 @@ struct UnlockPolicyShared {
}; };
template <template <typename...> class LockTraits> template <template <typename...> class LockTraits>
struct UnlockPolicyUpgrade { struct UnlockPolicyUpgrade {
template <typename Mutex>
using lock_type = upgrade_lock<Mutex>;
constexpr static bool allows_concurrent_access = true; constexpr static bool allows_concurrent_access = true;
template <typename Mutex> template <typename Mutex>
...@@ -453,6 +471,8 @@ struct LockTraits : public LockTraitsBase<Mutex> {}; ...@@ -453,6 +471,8 @@ struct LockTraits : public LockTraitsBase<Mutex> {};
struct LockPolicyExclusive : detail::UnlockPolicyExclusive<LockTraits> { struct LockPolicyExclusive : detail::UnlockPolicyExclusive<LockTraits> {
using UnlockPolicy = detail::UnlockPolicyExclusive<LockTraits>; using UnlockPolicy = detail::UnlockPolicyExclusive<LockTraits>;
static constexpr bool is_try = false;
template <class Mutex> template <class Mutex>
static std::true_type lock(Mutex& mutex) { static std::true_type lock(Mutex& mutex) {
LockTraits<Mutex>::lock(mutex); LockTraits<Mutex>::lock(mutex);
...@@ -472,6 +492,8 @@ struct LockPolicyExclusive : detail::UnlockPolicyExclusive<LockTraits> { ...@@ -472,6 +492,8 @@ struct LockPolicyExclusive : detail::UnlockPolicyExclusive<LockTraits> {
struct LockPolicyShared : detail::UnlockPolicyShared<LockTraits> { struct LockPolicyShared : detail::UnlockPolicyShared<LockTraits> {
using UnlockPolicy = detail::UnlockPolicyShared<LockTraits>; using UnlockPolicy = detail::UnlockPolicyShared<LockTraits>;
static constexpr bool is_try = false;
template <class Mutex> template <class Mutex>
static std::true_type lock(Mutex& mutex) { static std::true_type lock(Mutex& mutex) {
LockTraits<Mutex>::lock_shared(mutex); LockTraits<Mutex>::lock_shared(mutex);
...@@ -494,6 +516,8 @@ struct LockPolicyShared : detail::UnlockPolicyShared<LockTraits> { ...@@ -494,6 +516,8 @@ struct LockPolicyShared : detail::UnlockPolicyShared<LockTraits> {
struct LockPolicyUpgrade : detail::UnlockPolicyUpgrade<LockTraits> { struct LockPolicyUpgrade : detail::UnlockPolicyUpgrade<LockTraits> {
using UnlockPolicy = detail::UnlockPolicyUpgrade<LockTraits>; using UnlockPolicy = detail::UnlockPolicyUpgrade<LockTraits>;
static constexpr bool is_try = false;
template <class Mutex> template <class Mutex>
static std::true_type lock(Mutex& mutex) { static std::true_type lock(Mutex& mutex) {
LockTraits<Mutex>::lock_upgrade(mutex); LockTraits<Mutex>::lock_upgrade(mutex);
...@@ -516,6 +540,8 @@ struct LockPolicyUpgrade : detail::UnlockPolicyUpgrade<LockTraits> { ...@@ -516,6 +540,8 @@ struct LockPolicyUpgrade : detail::UnlockPolicyUpgrade<LockTraits> {
struct LockPolicyTryExclusive : detail::UnlockPolicyExclusive<LockTraits> { struct LockPolicyTryExclusive : detail::UnlockPolicyExclusive<LockTraits> {
using UnlockPolicy = detail::UnlockPolicyExclusive<LockTraits>; using UnlockPolicy = detail::UnlockPolicyExclusive<LockTraits>;
static constexpr bool is_try = true;
template <class Mutex> template <class Mutex>
static bool lock(Mutex& mutex) { static bool lock(Mutex& mutex) {
return LockTraits<Mutex>::try_lock(mutex); return LockTraits<Mutex>::try_lock(mutex);
...@@ -529,6 +555,8 @@ struct LockPolicyTryExclusive : detail::UnlockPolicyExclusive<LockTraits> { ...@@ -529,6 +555,8 @@ struct LockPolicyTryExclusive : detail::UnlockPolicyExclusive<LockTraits> {
struct LockPolicyTryShared : detail::UnlockPolicyShared<LockTraits> { struct LockPolicyTryShared : detail::UnlockPolicyShared<LockTraits> {
using UnlockPolicy = detail::UnlockPolicyShared<LockTraits>; using UnlockPolicy = detail::UnlockPolicyShared<LockTraits>;
static constexpr bool is_try = true;
template <class Mutex> template <class Mutex>
static bool lock(Mutex& mutex) { static bool lock(Mutex& mutex) {
return LockTraits<Mutex>::try_lock_shared(mutex); return LockTraits<Mutex>::try_lock_shared(mutex);
...@@ -542,102 +570,12 @@ struct LockPolicyTryShared : detail::UnlockPolicyShared<LockTraits> { ...@@ -542,102 +570,12 @@ struct LockPolicyTryShared : detail::UnlockPolicyShared<LockTraits> {
struct LockPolicyTryUpgrade : detail::UnlockPolicyUpgrade<LockTraits> { struct LockPolicyTryUpgrade : detail::UnlockPolicyUpgrade<LockTraits> {
using UnlockPolicy = detail::UnlockPolicyUpgrade<LockTraits>; using UnlockPolicy = detail::UnlockPolicyUpgrade<LockTraits>;
static constexpr bool is_try = true;
template <class Mutex> template <class Mutex>
static bool lock(Mutex& mutex) { static bool lock(Mutex& mutex) {
return LockTraits<Mutex>::try_lock_upgrade(mutex); return LockTraits<Mutex>::try_lock_upgrade(mutex);
} }
}; };
/*****************************************************************************
* Policies for all the transitions from possible mutex levels
****************************************************************************/
/**
* A lock policy with the following mapping
*
* lock() -> unlock_upgrade_and_lock()
* unlock() -> unlock()
* try_lock_for -> try_unlock_upgrade_and_lock_for()
*/
struct LockPolicyFromUpgradeToExclusive : LockPolicyExclusive {
template <class Mutex>
static std::true_type lock(Mutex& mutex) {
LockTraits<Mutex>::unlock_upgrade_and_lock(mutex);
return std::true_type{};
}
template <class Mutex, class Rep, class Period>
static bool try_lock_for(
Mutex& mutex, const std::chrono::duration<Rep, Period>& timeout) {
return LockTraits<Mutex>::try_unlock_upgrade_and_lock_for(mutex, timeout);
}
};
/**
* A lock policy with the following mapping
*
* lock() -> unlock_and_lock_upgrade()
* unlock() -> unlock_upgrade()
* try_lock_for -> unlock_and_lock_upgrade()
*/
struct LockPolicyFromExclusiveToUpgrade : LockPolicyUpgrade {
template <class Mutex>
static std::true_type lock(Mutex& mutex) {
LockTraits<Mutex>::unlock_and_lock_upgrade(mutex);
return std::true_type{};
}
template <class Mutex, class Rep, class Period>
static bool try_lock_for(
Mutex& mutex, const std::chrono::duration<Rep, Period>&) {
LockTraits<Mutex>::unlock_and_lock_upgrade(mutex);
// downgrade should be non blocking and should succeed
return true;
}
};
/**
* A lock policy with the following mapping
*
* lock() -> unlock_upgrade_and_lock_shared()
* unlock() -> unlock_shared()
* try_lock_for -> unlock_upgrade_and_lock_shared()
*/
struct LockPolicyFromUpgradeToShared : LockPolicyShared {
template <class Mutex>
static std::true_type lock(Mutex& mutex) {
LockTraits<Mutex>::unlock_upgrade_and_lock_shared(mutex);
return std::true_type{};
}
template <class Mutex, class Rep, class Period>
static bool try_lock_for(
Mutex& mutex, const std::chrono::duration<Rep, Period>&) {
LockTraits<Mutex>::unlock_upgrade_and_lock_shared(mutex);
// downgrade should be non blocking and should succeed
return true;
}
};
/**
* A lock policy with the following mapping
*
* lock() -> unlock_and_lock_shared()
* unlock() -> unlock_shared()
* try_lock_for() -> unlock_and_lock_shared()
*/
struct LockPolicyFromExclusiveToShared : LockPolicyShared {
template <class Mutex>
static std::true_type lock(Mutex& mutex) {
LockTraits<Mutex>::unlock_and_lock_shared(mutex);
return std::true_type{};
}
template <class Mutex, class Rep, class Period>
static bool try_lock_for(
Mutex& mutex, const std::chrono::duration<Rep, Period>&) {
LockTraits<Mutex>::unlock_and_lock_shared(mutex);
// downgrade should be non blocking and should succeed
return true;
}
};
} // namespace folly } // namespace folly
This diff is collapsed.
...@@ -256,30 +256,6 @@ TEST(LockTraits, LockPolicy) { ...@@ -256,30 +256,6 @@ TEST(LockTraits, LockPolicy) {
mutex.lock_upgrade(); mutex.lock_upgrade();
LockPolicyUpgrade::unlock(mutex); LockPolicyUpgrade::unlock(mutex);
mutex.lock_upgrade();
LockPolicyFromUpgradeToExclusive::lock(mutex);
mutex.unlock();
mutex.lock();
LockPolicyFromUpgradeToExclusive::unlock(mutex);
mutex.lock();
LockPolicyFromExclusiveToUpgrade::lock(mutex);
mutex.unlock_upgrade();
mutex.lock_upgrade();
LockPolicyFromExclusiveToUpgrade::unlock(mutex);
mutex.lock_upgrade();
LockPolicyFromUpgradeToShared::lock(mutex);
mutex.unlock_shared();
mutex.lock_shared();
LockPolicyFromUpgradeToShared::unlock(mutex);
mutex.lock();
LockPolicyFromExclusiveToShared::lock(mutex);
mutex.unlock_shared();
mutex.lock_shared();
LockPolicyFromExclusiveToShared::unlock(mutex);
EXPECT_EQ(mutex.lock_state, Mutex::CurrentLockState::UNLOCKED); EXPECT_EQ(mutex.lock_state, Mutex::CurrentLockState::UNLOCKED);
} }
...@@ -293,30 +269,6 @@ TEST(LockTraits, LockPolicyTimed) { ...@@ -293,30 +269,6 @@ TEST(LockTraits, LockPolicyTimed) {
bool gotLock = LockPolicyUpgrade::try_lock_for(mutex, one_ms); bool gotLock = LockPolicyUpgrade::try_lock_for(mutex, one_ms);
EXPECT_TRUE(gotLock) << "Should have been able to acquire the fake mutex"; EXPECT_TRUE(gotLock) << "Should have been able to acquire the fake mutex";
LockPolicyUpgrade::unlock(mutex); LockPolicyUpgrade::unlock(mutex);
mutex.lock_upgrade();
gotLock = LockPolicyFromUpgradeToExclusive::try_lock_for(mutex, one_ms);
EXPECT_TRUE(gotLock)
<< "Should have been able to upgrade from upgrade to unique";
mutex.unlock();
mutex.lock();
gotLock = LockPolicyFromExclusiveToUpgrade::try_lock_for(mutex, one_ms);
EXPECT_TRUE(gotLock) << "Should have been able to downgrade from exclusive "
"to upgrade";
mutex.unlock_upgrade();
mutex.lock_upgrade();
gotLock = LockPolicyFromUpgradeToShared::try_lock_for(mutex, one_ms);
EXPECT_TRUE(gotLock) << "Should have been able to downgrade from upgrade to "
"shared";
mutex.unlock_shared();
mutex.lock();
gotLock = LockPolicyFromExclusiveToShared::try_lock_for(mutex, one_ms);
EXPECT_TRUE(gotLock) << "Should have been able to downgrade from exclusive "
"to shared";
mutex.unlock_shared();
} }
/** /**
...@@ -330,24 +282,12 @@ TEST(LockTraits, LockPolicyCompatibilities) { ...@@ -330,24 +282,12 @@ TEST(LockTraits, LockPolicyCompatibilities) {
EXPECT_TRUE((std::is_same< EXPECT_TRUE((std::is_same<
LockPolicyExclusive::UnlockPolicy, LockPolicyExclusive::UnlockPolicy,
LockPolicyTryExclusive::UnlockPolicy>::value)); LockPolicyTryExclusive::UnlockPolicy>::value));
EXPECT_TRUE((std::is_same<
LockPolicyExclusive::UnlockPolicy,
LockPolicyFromUpgradeToExclusive::UnlockPolicy>::value));
EXPECT_TRUE((std::is_same< EXPECT_TRUE((std::is_same<
LockPolicyShared::UnlockPolicy, LockPolicyShared::UnlockPolicy,
LockPolicyTryShared::UnlockPolicy>::value)); LockPolicyTryShared::UnlockPolicy>::value));
EXPECT_TRUE((std::is_same<
LockPolicyShared::UnlockPolicy,
LockPolicyFromUpgradeToShared::UnlockPolicy>::value));
EXPECT_TRUE((std::is_same<
LockPolicyShared::UnlockPolicy,
LockPolicyFromExclusiveToShared::UnlockPolicy>::value));
EXPECT_TRUE((std::is_same< EXPECT_TRUE((std::is_same<
LockPolicyUpgrade::UnlockPolicy, LockPolicyUpgrade::UnlockPolicy,
LockPolicyTryUpgrade::UnlockPolicy>::value)); LockPolicyTryUpgrade::UnlockPolicy>::value));
EXPECT_TRUE((std::is_same<
LockPolicyUpgrade::UnlockPolicy,
LockPolicyFromExclusiveToUpgrade::UnlockPolicy>::value));
} }
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <folly/SharedMutex.h> #include <folly/SharedMutex.h>
#include <folly/SpinLock.h> #include <folly/SpinLock.h>
#include <folly/portability/GTest.h> #include <folly/portability/GTest.h>
#include <folly/synchronization/DistributedMutex.h>
#include <folly/synchronization/RWSpinLock.h> #include <folly/synchronization/RWSpinLock.h>
#include <folly/test/SynchronizedTestLib.h> #include <folly/test/SynchronizedTestLib.h>
...@@ -39,6 +40,7 @@ template <class Mutex> ...@@ -39,6 +40,7 @@ template <class Mutex>
class SynchronizedTest : public testing::Test {}; class SynchronizedTest : public testing::Test {};
using SynchronizedTestTypes = testing::Types< using SynchronizedTestTypes = testing::Types<
folly::DistributedMutex,
folly::SharedMutexReadPriority, folly::SharedMutexReadPriority,
folly::SharedMutexWritePriority, folly::SharedMutexWritePriority,
std::mutex, std::mutex,
...@@ -744,9 +746,6 @@ template <template <typename...> class Trait> ...@@ -744,9 +746,6 @@ template <template <typename...> class Trait>
void testLockedPtrCompatibilityExclusive() { void testLockedPtrCompatibilityExclusive() {
EXPECT_TRUE(( EXPECT_TRUE((
Trait<LPtr<LockPolicyExclusive>, LPtr<LockPolicyTryExclusive>&&>::value)); Trait<LPtr<LockPolicyExclusive>, LPtr<LockPolicyTryExclusive>&&>::value));
EXPECT_TRUE((Trait<
LPtr<LockPolicyExclusive>,
LPtr<LockPolicyFromUpgradeToExclusive>&&>::value));
EXPECT_FALSE( EXPECT_FALSE(
(Trait<LPtr<LockPolicyExclusive>&, LPtr<LockPolicyShared>&&>::value)); (Trait<LPtr<LockPolicyExclusive>&, LPtr<LockPolicyShared>&&>::value));
...@@ -756,27 +755,12 @@ void testLockedPtrCompatibilityExclusive() { ...@@ -756,27 +755,12 @@ void testLockedPtrCompatibilityExclusive() {
(Trait<LPtr<LockPolicyExclusive>, LPtr<LockPolicyUpgrade>&&>::value)); (Trait<LPtr<LockPolicyExclusive>, LPtr<LockPolicyUpgrade>&&>::value));
EXPECT_FALSE( EXPECT_FALSE(
(Trait<LPtr<LockPolicyExclusive>, LPtr<LockPolicyTryUpgrade>&&>::value)); (Trait<LPtr<LockPolicyExclusive>, LPtr<LockPolicyTryUpgrade>&&>::value));
EXPECT_FALSE((Trait<
LPtr<LockPolicyExclusive>,
LPtr<LockPolicyFromExclusiveToUpgrade>&&>::value));
EXPECT_FALSE((Trait<
LPtr<LockPolicyExclusive>,
LPtr<LockPolicyFromExclusiveToShared>&&>::value));
EXPECT_FALSE(
(Trait<LPtr<LockPolicyExclusive>, LPtr<LockPolicyFromUpgradeToShared>&&>::
value));
} }
template <template <typename...> class Trait> template <template <typename...> class Trait>
void testLockedPtrCompatibilityShared() { void testLockedPtrCompatibilityShared() {
EXPECT_TRUE( EXPECT_TRUE(
(Trait<LPtr<LockPolicyShared>, LPtr<LockPolicyTryShared>&&>::value)); (Trait<LPtr<LockPolicyShared>, LPtr<LockPolicyTryShared>&&>::value));
EXPECT_TRUE(
(Trait<LPtr<LockPolicyShared>, LPtr<LockPolicyFromUpgradeToShared>&&>::
value));
EXPECT_TRUE(
(Trait<LPtr<LockPolicyShared>, LPtr<LockPolicyFromExclusiveToShared>&&>::
value));
EXPECT_FALSE( EXPECT_FALSE(
(Trait<LPtr<LockPolicyShared>, LPtr<LockPolicyExclusive>&&>::value)); (Trait<LPtr<LockPolicyShared>, LPtr<LockPolicyExclusive>&&>::value));
...@@ -786,21 +770,12 @@ void testLockedPtrCompatibilityShared() { ...@@ -786,21 +770,12 @@ void testLockedPtrCompatibilityShared() {
(Trait<LPtr<LockPolicyShared>, LPtr<LockPolicyUpgrade>&&>::value)); (Trait<LPtr<LockPolicyShared>, LPtr<LockPolicyUpgrade>&&>::value));
EXPECT_FALSE( EXPECT_FALSE(
(Trait<LPtr<LockPolicyShared>, LPtr<LockPolicyTryUpgrade>&&>::value)); (Trait<LPtr<LockPolicyShared>, LPtr<LockPolicyTryUpgrade>&&>::value));
EXPECT_FALSE(
(Trait<LPtr<LockPolicyShared>, LPtr<LockPolicyFromExclusiveToUpgrade>&&>::
value));
EXPECT_FALSE(
(Trait<LPtr<LockPolicyShared>, LPtr<LockPolicyFromUpgradeToExclusive>&&>::
value));
} }
template <template <typename...> class Trait> template <template <typename...> class Trait>
void testLockedPtrCompatibilityUpgrade() { void testLockedPtrCompatibilityUpgrade() {
EXPECT_TRUE( EXPECT_TRUE(
(Trait<LPtr<LockPolicyUpgrade>, LPtr<LockPolicyTryUpgrade>&&>::value)); (Trait<LPtr<LockPolicyUpgrade>, LPtr<LockPolicyTryUpgrade>&&>::value));
EXPECT_TRUE((
Trait<LPtr<LockPolicyUpgrade>, LPtr<LockPolicyFromExclusiveToUpgrade>&&>::
value));
EXPECT_FALSE( EXPECT_FALSE(
(Trait<LPtr<LockPolicyUpgrade>, LPtr<LockPolicyExclusive>&&>::value)); (Trait<LPtr<LockPolicyUpgrade>, LPtr<LockPolicyExclusive>&&>::value));
...@@ -810,15 +785,6 @@ void testLockedPtrCompatibilityUpgrade() { ...@@ -810,15 +785,6 @@ void testLockedPtrCompatibilityUpgrade() {
(Trait<LPtr<LockPolicyUpgrade>, LPtr<LockPolicyShared>&&>::value)); (Trait<LPtr<LockPolicyUpgrade>, LPtr<LockPolicyShared>&&>::value));
EXPECT_FALSE( EXPECT_FALSE(
(Trait<LPtr<LockPolicyUpgrade>, LPtr<LockPolicyTryShared>&&>::value)); (Trait<LPtr<LockPolicyUpgrade>, LPtr<LockPolicyTryShared>&&>::value));
EXPECT_FALSE(
(Trait<LPtr<LockPolicyUpgrade>, LPtr<LockPolicyFromExclusiveToShared>&&>::
value));
EXPECT_FALSE(
(Trait<LPtr<LockPolicyUpgrade>, LPtr<LockPolicyFromUpgradeToShared>&&>::
value));
EXPECT_FALSE((
Trait<LPtr<LockPolicyUpgrade>, LPtr<LockPolicyFromUpgradeToExclusive>&&>::
value));
} }
} // namespace } // namespace
......
...@@ -72,7 +72,7 @@ void runParallel(size_t numThreads, const Function& function) { ...@@ -72,7 +72,7 @@ void runParallel(size_t numThreads, const Function& function) {
// as close to the same time as possible. // as close to the same time as possible.
{ {
auto lockedGo = go.lock(); auto lockedGo = go.lock();
goCV.wait(lockedGo.getUniqueLock(), [&] { return *lockedGo; }); goCV.wait(lockedGo.as_lock(), [&] { return *lockedGo; });
} }
function(threadIndex); function(threadIndex);
...@@ -86,9 +86,8 @@ void runParallel(size_t numThreads, const Function& function) { ...@@ -86,9 +86,8 @@ void runParallel(size_t numThreads, const Function& function) {
// Wait for all threads to become ready // Wait for all threads to become ready
{ {
auto readyLocked = threadsReady.lock(); auto readyLocked = threadsReady.lock();
readyCV.wait(readyLocked.getUniqueLock(), [&] { readyCV.wait(
return *readyLocked == numThreads; readyLocked.as_lock(), [&] { return *readyLocked == numThreads; });
});
} }
// Now signal the threads that they can go // Now signal the threads that they can go
go = true; go = true;
......
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