| 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
 | 
| 
 |