| Index: rlz/lib/recursive_lock_unittest.cc
|
| diff --git a/base/synchronization/lock_unittest.cc b/rlz/lib/recursive_lock_unittest.cc
|
| similarity index 52%
|
| copy from base/synchronization/lock_unittest.cc
|
| copy to rlz/lib/recursive_lock_unittest.cc
|
| index a048f8570c2eb455ee9b9f56c39e0a7e43eeeb16..916af7f327de85f6dfc0ce0206779c4c8d9c9eaa 100644
|
| --- a/base/synchronization/lock_unittest.cc
|
| +++ b/rlz/lib/recursive_lock_unittest.cc
|
| @@ -2,21 +2,26 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "base/synchronization/lock.h"
|
| +#include "rlz/lib/recursive_lock.h"
|
|
|
| #include <stdlib.h>
|
|
|
| #include "base/compiler_specific.h"
|
| #include "base/threading/platform_thread.h"
|
| +#include "base/time.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| -namespace base {
|
| +using base::kNullThreadHandle;
|
| +using base::PlatformThread;
|
| +using base::PlatformThreadHandle;
|
| +using base::TimeDelta;
|
|
|
| -// Basic test to make sure that Acquire()/Release()/Try() don't crash ----------
|
| +namespace rlz_lib {
|
|
|
| +// Basic test to make sure that Acquire()/Release() don't crash.
|
| class BasicLockTestThread : public PlatformThread::Delegate {
|
| public:
|
| - BasicLockTestThread(Lock* lock) : lock_(lock), acquired_(0) {}
|
| + BasicLockTestThread(RecursiveLock* lock) : lock_(lock), acquired_(0) {}
|
|
|
| virtual void ThreadMain() OVERRIDE {
|
| for (int i = 0; i < 10; i++) {
|
| @@ -30,26 +35,19 @@ class BasicLockTestThread : public PlatformThread::Delegate {
|
| PlatformThread::Sleep(TimeDelta::FromMilliseconds(rand() % 20));
|
| lock_->Release();
|
| }
|
| - for (int i = 0; i < 10; i++) {
|
| - if (lock_->Try()) {
|
| - acquired_++;
|
| - PlatformThread::Sleep(TimeDelta::FromMilliseconds(rand() % 20));
|
| - lock_->Release();
|
| - }
|
| - }
|
| }
|
|
|
| int acquired() const { return acquired_; }
|
|
|
| private:
|
| - Lock* lock_;
|
| + RecursiveLock* lock_;
|
| int acquired_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(BasicLockTestThread);
|
| };
|
|
|
| -TEST(LockTest, Basic) {
|
| - Lock lock;
|
| +TEST(RecursiveLockTest, Basic) {
|
| + RecursiveLock lock;
|
| BasicLockTestThread thread(&lock);
|
| PlatformThreadHandle handle = kNullThreadHandle;
|
|
|
| @@ -67,13 +65,6 @@ TEST(LockTest, Basic) {
|
| PlatformThread::Sleep(TimeDelta::FromMilliseconds(rand() % 20));
|
| lock.Release();
|
| }
|
| - for (int i = 0; i < 10; i++) {
|
| - if (lock.Try()) {
|
| - acquired++;
|
| - PlatformThread::Sleep(TimeDelta::FromMilliseconds(rand() % 20));
|
| - lock.Release();
|
| - }
|
| - }
|
| for (int i = 0; i < 5; i++) {
|
| lock.Acquire();
|
| acquired++;
|
| @@ -83,81 +74,107 @@ TEST(LockTest, Basic) {
|
|
|
| PlatformThread::Join(handle);
|
|
|
| - EXPECT_GE(acquired, 20);
|
| - EXPECT_GE(thread.acquired(), 20);
|
| + EXPECT_EQ(acquired, 20);
|
| + EXPECT_EQ(thread.acquired(), 20);
|
| }
|
|
|
| -// Test that Try() works as expected -------------------------------------------
|
| -
|
| -class TryLockTestThread : public PlatformThread::Delegate {
|
| +// Tests that locks are actually exclusive.
|
| +class MutexLockTestThread : public PlatformThread::Delegate {
|
| public:
|
| - TryLockTestThread(Lock* lock) : lock_(lock), got_lock_(false) {}
|
| + MutexLockTestThread(RecursiveLock* lock, int* value)
|
| + : lock_(lock),
|
| + value_(value) {
|
| + }
|
|
|
| - virtual void ThreadMain() OVERRIDE {
|
| - got_lock_ = lock_->Try();
|
| - if (got_lock_)
|
| - lock_->Release();
|
| + // Static helper which can also be called from the main thread.
|
| + static void DoStuff(RecursiveLock* lock, int* value) {
|
| + for (int i = 0; i < 40; i++) {
|
| + lock->Acquire();
|
| + int v = *value;
|
| + PlatformThread::Sleep(TimeDelta::FromMilliseconds(rand() % 10));
|
| + *value = v + 1;
|
| + lock->Release();
|
| + }
|
| }
|
|
|
| - bool got_lock() const { return got_lock_; }
|
| + virtual void ThreadMain() OVERRIDE {
|
| + DoStuff(lock_, value_);
|
| + }
|
|
|
| private:
|
| - Lock* lock_;
|
| - bool got_lock_;
|
| + RecursiveLock* lock_;
|
| + int* value_;
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(TryLockTestThread);
|
| + DISALLOW_COPY_AND_ASSIGN(MutexLockTestThread);
|
| };
|
|
|
| -TEST(LockTest, TryLock) {
|
| - Lock lock;
|
| +TEST(RecursiveLockTest, MutexTwoThreads) {
|
| + RecursiveLock lock;
|
| + int value = 0;
|
|
|
| - ASSERT_TRUE(lock.Try());
|
| - // We now have the lock....
|
| + MutexLockTestThread thread(&lock, &value);
|
| + PlatformThreadHandle handle = kNullThreadHandle;
|
|
|
| - // This thread will not be able to get the lock.
|
| - {
|
| - TryLockTestThread thread(&lock);
|
| - PlatformThreadHandle handle = kNullThreadHandle;
|
| + ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
|
|
|
| - ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
|
| + MutexLockTestThread::DoStuff(&lock, &value);
|
|
|
| - PlatformThread::Join(handle);
|
| + PlatformThread::Join(handle);
|
|
|
| - ASSERT_FALSE(thread.got_lock());
|
| - }
|
| + EXPECT_EQ(2 * 40, value);
|
| +}
|
|
|
| - lock.Release();
|
| +TEST(RecursiveLockTest, MutexFourThreads) {
|
| + RecursiveLock lock;
|
| + int value = 0;
|
|
|
| - // This thread will....
|
| - {
|
| - TryLockTestThread thread(&lock);
|
| - PlatformThreadHandle handle = kNullThreadHandle;
|
| + MutexLockTestThread thread1(&lock, &value);
|
| + MutexLockTestThread thread2(&lock, &value);
|
| + MutexLockTestThread thread3(&lock, &value);
|
| + PlatformThreadHandle handle1 = kNullThreadHandle;
|
| + PlatformThreadHandle handle2 = kNullThreadHandle;
|
| + PlatformThreadHandle handle3 = kNullThreadHandle;
|
|
|
| - ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
|
| + ASSERT_TRUE(PlatformThread::Create(0, &thread1, &handle1));
|
| + ASSERT_TRUE(PlatformThread::Create(0, &thread2, &handle2));
|
| + ASSERT_TRUE(PlatformThread::Create(0, &thread3, &handle3));
|
|
|
| - PlatformThread::Join(handle);
|
| + MutexLockTestThread::DoStuff(&lock, &value);
|
|
|
| - ASSERT_TRUE(thread.got_lock());
|
| - // But it released it....
|
| - ASSERT_TRUE(lock.Try());
|
| - }
|
| + PlatformThread::Join(handle1);
|
| + PlatformThread::Join(handle2);
|
| + PlatformThread::Join(handle3);
|
|
|
| - lock.Release();
|
| + EXPECT_EQ(4 * 40, value);
|
| }
|
|
|
| -// Tests that locks actually exclude -------------------------------------------
|
| -
|
| -class MutexLockTestThread : public PlatformThread::Delegate {
|
| +// Tests that locks are recursive.
|
| +class MutexRecursiveLockTestThread : public PlatformThread::Delegate {
|
| public:
|
| - MutexLockTestThread(Lock* lock, int* value) : lock_(lock), value_(value) {}
|
| + MutexRecursiveLockTestThread(RecursiveLock* lock, int* value)
|
| + : lock_(lock),
|
| + value_(value) {
|
| + }
|
|
|
| // Static helper which can also be called from the main thread.
|
| - static void DoStuff(Lock* lock, int* value) {
|
| - for (int i = 0; i < 40; i++) {
|
| + static void DoStuff(RecursiveLock* lock, int* value) {
|
| + for (int i = 0; i < 20; i++) {
|
| + // First lock.
|
| lock->Acquire();
|
| int v = *value;
|
| PlatformThread::Sleep(TimeDelta::FromMilliseconds(rand() % 10));
|
| *value = v + 1;
|
| + {
|
| + // Recursive lock.
|
| + lock->Acquire();
|
| + int v = *value;
|
| + PlatformThread::Sleep(TimeDelta::FromMilliseconds(rand() % 10));
|
| + *value = v + 1;
|
| + lock->Release();
|
| + }
|
| + v = *value;
|
| + PlatformThread::Sleep(TimeDelta::FromMilliseconds(rand() % 10));
|
| + *value = v + 1;
|
| lock->Release();
|
| }
|
| }
|
| @@ -167,35 +184,36 @@ class MutexLockTestThread : public PlatformThread::Delegate {
|
| }
|
|
|
| private:
|
| - Lock* lock_;
|
| + RecursiveLock* lock_;
|
| int* value_;
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(MutexLockTestThread);
|
| + DISALLOW_COPY_AND_ASSIGN(MutexRecursiveLockTestThread);
|
| };
|
|
|
| -TEST(LockTest, MutexTwoThreads) {
|
| - Lock lock;
|
| +
|
| +TEST(RecursiveLockTest, MutexTwoThreadsRecursive) {
|
| + RecursiveLock lock;
|
| int value = 0;
|
|
|
| - MutexLockTestThread thread(&lock, &value);
|
| + MutexRecursiveLockTestThread thread(&lock, &value);
|
| PlatformThreadHandle handle = kNullThreadHandle;
|
|
|
| ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
|
|
|
| - MutexLockTestThread::DoStuff(&lock, &value);
|
| + MutexRecursiveLockTestThread::DoStuff(&lock, &value);
|
|
|
| PlatformThread::Join(handle);
|
|
|
| - EXPECT_EQ(2 * 40, value);
|
| + EXPECT_EQ(2 * 60, value);
|
| }
|
|
|
| -TEST(LockTest, MutexFourThreads) {
|
| - Lock lock;
|
| +TEST(RecursiveLockTest, MutexFourThreadsRecursive) {
|
| + RecursiveLock lock;
|
| int value = 0;
|
|
|
| - MutexLockTestThread thread1(&lock, &value);
|
| - MutexLockTestThread thread2(&lock, &value);
|
| - MutexLockTestThread thread3(&lock, &value);
|
| + MutexRecursiveLockTestThread thread1(&lock, &value);
|
| + MutexRecursiveLockTestThread thread2(&lock, &value);
|
| + MutexRecursiveLockTestThread thread3(&lock, &value);
|
| PlatformThreadHandle handle1 = kNullThreadHandle;
|
| PlatformThreadHandle handle2 = kNullThreadHandle;
|
| PlatformThreadHandle handle3 = kNullThreadHandle;
|
| @@ -204,13 +222,13 @@ TEST(LockTest, MutexFourThreads) {
|
| ASSERT_TRUE(PlatformThread::Create(0, &thread2, &handle2));
|
| ASSERT_TRUE(PlatformThread::Create(0, &thread3, &handle3));
|
|
|
| - MutexLockTestThread::DoStuff(&lock, &value);
|
| + MutexRecursiveLockTestThread::DoStuff(&lock, &value);
|
|
|
| PlatformThread::Join(handle1);
|
| PlatformThread::Join(handle2);
|
| PlatformThread::Join(handle3);
|
|
|
| - EXPECT_EQ(4 * 40, value);
|
| + EXPECT_EQ(4 * 60, value);
|
| }
|
|
|
| -} // namespace base
|
| +} // namespace rlz_lib
|
|
|