diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-01 23:16:20 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-01 23:16:20 +0000 |
commit | bc581a6829fe49e43f4869075781d6dc94843f09 (patch) | |
tree | a94363488dadff28fe2c03f3a169b6ad2eeb02e8 /base | |
parent | 10f33b1bd6c6adb6306759a45bf3a5c18221d878 (diff) | |
download | chromium_src-bc581a6829fe49e43f4869075781d6dc94843f09.zip chromium_src-bc581a6829fe49e43f4869075781d6dc94843f09.tar.gz chromium_src-bc581a6829fe49e43f4869075781d6dc94843f09.tar.bz2 |
Move base/lock and base/condition_variable to base/synchronization/
I kept a base/lock.h in place with a using statement to avoid updating
all callers in one CL.
TEST=it compiles
BUG=none
Review URL: http://codereview.chromium.org/6018013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70363 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
24 files changed, 281 insertions, 239 deletions
diff --git a/base/base.gyp b/base/base.gyp index a86bca0..50a19ee 100644 --- a/base/base.gyp +++ b/base/base.gyp @@ -1,4 +1,4 @@ -# Copyright (c) 2010 The Chromium Authors. All rights reserved. +# Copyright (c) 2011 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -67,7 +67,6 @@ 'callback_unittest.cc', 'cancellation_flag_unittest.cc', 'command_line_unittest.cc', - 'condition_variable_unittest.cc', 'crypto/encryptor_unittest.cc', 'crypto/rsa_private_key_unittest.cc', 'crypto/rsa_private_key_nss_unittest.cc', @@ -97,7 +96,6 @@ 'lazy_instance_unittest.cc', 'linked_list_unittest.cc', 'linked_ptr_unittest.cc', - 'lock_unittest.cc', 'logging_unittest.cc', 'mac/mac_util_unittest.mm', 'message_loop_proxy_impl_unittest.cc', @@ -132,6 +130,8 @@ 'string_util_unittest.cc', 'stringize_macros_unittest.cc', 'stringprintf_unittest.cc', + 'synchronization/condition_variable_unittest.cc', + 'synchronization/lock_unittest.cc', 'sys_info_unittest.cc', 'sys_string_conversions_mac_unittest.mm', 'sys_string_conversions_unittest.cc', diff --git a/base/base.gypi b/base/base.gypi index 53ca3c9..4147e68 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -1,4 +1,4 @@ -# Copyright (c) 2010 The Chromium Authors. All rights reserved. +# Copyright (c) 2011 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -44,9 +44,6 @@ 'command_line.cc', 'command_line.h', 'compiler_specific.h', - 'condition_variable.h', - 'condition_variable_posix.cc', - 'condition_variable_win.cc', 'cpu.cc', 'cpu.h', 'debug/debug_on_start_win.cc', @@ -103,11 +100,7 @@ 'lazy_instance.h', 'linked_list.h', 'linked_ptr.h', - 'lock.cc', 'lock.h', - 'lock_impl.h', - 'lock_impl_posix.cc', - 'lock_impl_win.cc', 'logging.cc', 'logging.h', 'logging_win.cc', @@ -216,6 +209,14 @@ 'stringize_macros.h', 'stringprintf.cc', 'stringprintf.h', + 'synchronization/condition_variable.h', + 'synchronization/condition_variable_posix.cc', + 'synchronization/condition_variable_win.cc', + 'synchronization/lock.cc', + 'synchronization/lock.h', + 'synchronization/lock_impl.h', + 'synchronization/lock_impl_posix.cc', + 'synchronization/lock_impl_win.cc', 'sys_info.h', 'sys_info_chromeos.cc', 'sys_info_freebsd.cc', diff --git a/base/crypto/cssm_init.cc b/base/crypto/cssm_init.cc index 46a6ffe..f588f30 100644 --- a/base/crypto/cssm_init.cc +++ b/base/crypto/cssm_init.cc @@ -6,9 +6,9 @@ #include <Security/SecBase.h> -#include "base/lock.h" #include "base/logging.h" #include "base/singleton.h" +#include "base/synchronization/lock.h" #include "base/sys_string_conversions.h" // When writing crypto code for Mac OS X, you may find the following @@ -92,7 +92,7 @@ class SecurityServicesSingleton { ~SecurityServicesSingleton() {} - Lock& lock() { return lock_; } + base::Lock& lock() { return lock_; } private: friend class Singleton<SecurityServicesSingleton>; @@ -100,7 +100,7 @@ class SecurityServicesSingleton { SecurityServicesSingleton() {} - Lock lock_; + base::Lock lock_; DISALLOW_COPY_AND_ASSIGN(SecurityServicesSingleton); }; @@ -154,7 +154,7 @@ void LogCSSMError(const char *fn_name, CSSM_RETURN err) { } } -Lock& GetMacSecurityServicesLock() { +base::Lock& GetMacSecurityServicesLock() { return SecurityServicesSingleton::GetInstance()->lock(); } diff --git a/base/crypto/cssm_init.h b/base/crypto/cssm_init.h index e457083..5644d7e 100644 --- a/base/crypto/cssm_init.h +++ b/base/crypto/cssm_init.h @@ -10,10 +10,10 @@ #include "base/scoped_ptr.h" -class Lock; - namespace base { +class Lock; + // Initialize CSSM if it isn't already initialized. This must be called before // any other CSSM functions. This function is thread-safe, and CSSM will only // ever be initialized once. CSSM will be properly shut down on program exit. diff --git a/base/lock.h b/base/lock.h index 672e3fb..7c90d86 100644 --- a/base/lock.h +++ b/base/lock.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,122 +6,13 @@ #define BASE_LOCK_H_ #pragma once -#include "base/lock_impl.h" -#include "base/threading/platform_thread.h" +// This is a temporary forwarding file so not every user of lock needs to +// be updated at once. +// TODO(brettw) remove this and fix everybody up to using the new location. +#include "base/synchronization/lock.h" -// A convenient wrapper for an OS specific critical section. The only real -// intelligence in this class is in debug mode for the support for the -// AssertAcquired() method. - -class Lock { - public: -#if defined(NDEBUG) // Optimized wrapper implementation - Lock() : lock_() {} - ~Lock() {} - void Acquire() { lock_.Lock(); } - void Release() { lock_.Unlock(); } - - // If the lock is not held, take it and return true. If the lock is already - // held by another thread, immediately return false. This must not be called - // by a thread already holding the lock (what happens is undefined and an - // assertion may fail). - bool Try() { return lock_.Try(); } - - // Null implementation if not debug. - void AssertAcquired() const {} -#else - Lock(); - ~Lock() {} - - // NOTE: Although windows critical sections support recursive locks, we do not - // allow this, and we will commonly fire a DCHECK() if a thread attempts to - // acquire the lock a second time (while already holding it). - void Acquire() { - lock_.Lock(); - CheckUnheldAndMark(); - } - void Release() { - CheckHeldAndUnmark(); - lock_.Unlock(); - } - - bool Try() { - bool rv = lock_.Try(); - if (rv) { - CheckUnheldAndMark(); - } - return rv; - } - - void AssertAcquired() const; -#endif // NDEBUG - -#if defined(OS_POSIX) - // The posix implementation of ConditionVariable needs to be able - // to see our lock and tweak our debugging counters, as it releases - // and acquires locks inside of pthread_cond_{timed,}wait. - // Windows doesn't need to do this as it calls the Lock::* methods. - friend class ConditionVariable; -#endif - - private: -#if !defined(NDEBUG) - // Members and routines taking care of locks assertions. - // Note that this checks for recursive locks and allows them - // if the variable is set. This is allowed by the underlying implementation - // on windows but not on Posix, so we're doing unneeded checks on Posix. - // It's worth it to share the code. - void CheckHeldAndUnmark(); - void CheckUnheldAndMark(); - - // All private data is implicitly protected by lock_. - // Be VERY careful to only access members under that lock. - - // Determines validity of owning_thread_id_. Needed as we don't have - // a null owning_thread_id_ value. - bool owned_by_thread_; - base::PlatformThreadId owning_thread_id_; -#endif // NDEBUG - - LockImpl lock_; // Platform specific underlying lock implementation. - - DISALLOW_COPY_AND_ASSIGN(Lock); -}; - -// A helper class that acquires the given Lock while the AutoLock is in scope. -class AutoLock { - public: - explicit AutoLock(Lock& lock) : lock_(lock) { - lock_.Acquire(); - } - - ~AutoLock() { - lock_.AssertAcquired(); - lock_.Release(); - } - - private: - Lock& lock_; - DISALLOW_COPY_AND_ASSIGN(AutoLock); -}; - -// AutoUnlock is a helper that will Release() the |lock| argument in the -// constructor, and re-Acquire() it in the destructor. -class AutoUnlock { - public: - explicit AutoUnlock(Lock& lock) : lock_(lock) { - // We require our caller to have the lock. - lock_.AssertAcquired(); - lock_.Release(); - } - - ~AutoUnlock() { - lock_.Acquire(); - } - - private: - Lock& lock_; - DISALLOW_COPY_AND_ASSIGN(AutoUnlock); -}; +using base::AutoLock; +using base::AutoUnlock; +using base::Lock; #endif // BASE_LOCK_H_ diff --git a/base/logging.cc b/base/logging.cc index 0a8931a..cfb1065 100644 --- a/base/logging.cc +++ b/base/logging.cc @@ -50,8 +50,8 @@ typedef pthread_mutex_t* MutexHandle; #include "base/debug/debugger.h" #include "base/debug/stack_trace.h" #include "base/eintr_wrapper.h" -#include "base/lock_impl.h" #include "base/string_piece.h" +#include "base/synchronization/lock_impl.h" #include "base/utf_string_conversions.h" #include "base/vlog.h" #if defined(OS_POSIX) @@ -243,7 +243,7 @@ class LoggingLock { } #endif } else { - log_lock = new LockImpl(); + log_lock = new base::internal::LockImpl(); } initialized = true; } @@ -282,7 +282,7 @@ class LoggingLock { // The lock is used if log file locking is false. It helps us avoid problems // with multiple threads writing to the log file at the same time. Use // LockImpl directly instead of using Lock, because Lock makes logging calls. - static LockImpl* log_lock; + static base::internal::LockImpl* log_lock; // When we don't use a lock, we are using a global mutex. We need to do this // because LockFileEx is not thread safe. @@ -299,7 +299,7 @@ class LoggingLock { // static bool LoggingLock::initialized = false; // static -LockImpl* LoggingLock::log_lock = NULL; +base::internal::LockImpl* LoggingLock::log_lock = NULL; // static LogLockingState LoggingLock::lock_log_file = LOCK_LOG_FILE; diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc index 75df12e..1526cd8 100644 --- a/base/metrics/histogram.cc +++ b/base/metrics/histogram.cc @@ -14,10 +14,10 @@ #include <algorithm> #include <string> -#include "base/lock.h" #include "base/logging.h" #include "base/pickle.h" #include "base/stringprintf.h" +#include "base/synchronization/lock.h" namespace base { @@ -911,9 +911,9 @@ StatisticsRecorder::StatisticsRecorder() { // during the termination phase. Since it's a static data member, we will // leak one per process, which would be similar to the instance allocated // during static initialization and released only on process termination. - lock_ = new Lock; + lock_ = new base::Lock; } - AutoLock auto_lock(*lock_); + base::AutoLock auto_lock(*lock_); histograms_ = new HistogramMap; } @@ -928,7 +928,7 @@ StatisticsRecorder::~StatisticsRecorder() { // Clean up. HistogramMap* histograms = NULL; { - AutoLock auto_lock(*lock_); + base::AutoLock auto_lock(*lock_); histograms = histograms_; histograms_ = NULL; } @@ -941,7 +941,7 @@ StatisticsRecorder::~StatisticsRecorder() { bool StatisticsRecorder::IsActive() { if (lock_ == NULL) return false; - AutoLock auto_lock(*lock_); + base::AutoLock auto_lock(*lock_); return NULL != histograms_; } @@ -954,7 +954,7 @@ bool StatisticsRecorder::IsActive() { void StatisticsRecorder::Register(Histogram* histogram) { if (lock_ == NULL) return; - AutoLock auto_lock(*lock_); + base::AutoLock auto_lock(*lock_); if (!histograms_) return; const std::string name = histogram->histogram_name(); @@ -1011,7 +1011,7 @@ void StatisticsRecorder::WriteGraph(const std::string& query, void StatisticsRecorder::GetHistograms(Histograms* output) { if (lock_ == NULL) return; - AutoLock auto_lock(*lock_); + base::AutoLock auto_lock(*lock_); if (!histograms_) return; for (HistogramMap::iterator it = histograms_->begin(); @@ -1026,7 +1026,7 @@ bool StatisticsRecorder::FindHistogram(const std::string& name, scoped_refptr<Histogram>* histogram) { if (lock_ == NULL) return false; - AutoLock auto_lock(*lock_); + base::AutoLock auto_lock(*lock_); if (!histograms_) return false; HistogramMap::iterator it = histograms_->find(name); @@ -1041,7 +1041,7 @@ void StatisticsRecorder::GetSnapshot(const std::string& query, Histograms* snapshot) { if (lock_ == NULL) return; - AutoLock auto_lock(*lock_); + base::AutoLock auto_lock(*lock_); if (!histograms_) return; for (HistogramMap::iterator it = histograms_->begin(); @@ -1055,7 +1055,7 @@ void StatisticsRecorder::GetSnapshot(const std::string& query, // static StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; // static -Lock* StatisticsRecorder::lock_ = NULL; +base::Lock* StatisticsRecorder::lock_ = NULL; // static bool StatisticsRecorder::dump_on_exit_ = false; diff --git a/base/metrics/histogram.h b/base/metrics/histogram.h index 6b09aa3..7ab5a77 100644 --- a/base/metrics/histogram.h +++ b/base/metrics/histogram.h @@ -41,11 +41,12 @@ #include "base/logging.h" #include "base/time.h" -class Lock; class Pickle; namespace base { +class Lock; + //------------------------------------------------------------------------------ // Provide easy general purpose histogram in a macro, just like stats counters. // The first four macros use 50 buckets. @@ -681,7 +682,7 @@ class StatisticsRecorder { static HistogramMap* histograms_; // lock protects access to the above map. - static Lock* lock_; + static base::Lock* lock_; // Dump all known histograms to log. static bool dump_on_exit_; diff --git a/base/nss_util.h b/base/nss_util.h index d1e36ac..2b0139e 100644 --- a/base/nss_util.h +++ b/base/nss_util.h @@ -10,7 +10,6 @@ #if defined(USE_NSS) class FilePath; -class Lock; #endif // defined(USE_NSS) // This file specifically doesn't depend on any NSS or NSPR headers because it @@ -18,6 +17,7 @@ class Lock; // initialization functions. namespace base { +class Lock; class Time; // Initialize NRPR if it isn't already initialized. This function is diff --git a/base/condition_variable.h b/base/synchronization/condition_variable.h index 4fe1892..3acd0ac 100644 --- a/base/condition_variable.h +++ b/base/synchronization/condition_variable.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -62,8 +62,8 @@ // For a discussion of the many very subtle implementation details, see the FAQ // at the end of condition_variable_win.cc. -#ifndef BASE_CONDITION_VARIABLE_H_ -#define BASE_CONDITION_VARIABLE_H_ +#ifndef BASE_SYNCHRONIZATION_CONDITION_VARIABLE_H_ +#define BASE_SYNCHRONIZATION_CONDITION_VARIABLE_H_ #pragma once #include "build/build_config.h" @@ -78,8 +78,8 @@ #include "base/lock.h" namespace base { - class TimeDelta; -} + +class TimeDelta; class ConditionVariable { public: @@ -91,7 +91,7 @@ class ConditionVariable { // Wait() releases the caller's critical section atomically as it starts to // sleep, and the reacquires it when it is signaled. void Wait(); - void TimedWait(const base::TimeDelta& max_time); + void TimedWait(const TimeDelta& max_time); // Broadcast() revives all waiting threads. void Broadcast(); @@ -184,4 +184,6 @@ class ConditionVariable { DISALLOW_COPY_AND_ASSIGN(ConditionVariable); }; -#endif // BASE_CONDITION_VARIABLE_H_ +} // namespace base + +#endif // BASE_SYNCHRONIZATION_CONDITION_VARIABLE_H_ diff --git a/base/condition_variable_posix.cc b/base/synchronization/condition_variable_posix.cc index 5d9ccb4..eff7053 100644 --- a/base/condition_variable_posix.cc +++ b/base/synchronization/condition_variable_posix.cc @@ -1,23 +1,22 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/condition_variable.h" +#include "base/synchronization/condition_variable.h" #include <errno.h> #include <sys/time.h> -#include "base/lock.h" #include "base/logging.h" +#include "base/synchronization/lock.h" #include "base/time.h" -using base::Time; -using base::TimeDelta; +namespace base { ConditionVariable::ConditionVariable(Lock* user_lock) - : user_mutex_(user_lock->lock_.os_lock()) + : user_mutex_(user_lock->lock_.os_lock()) #if !defined(NDEBUG) - , user_lock_(user_lock) + , user_lock_(user_lock) #endif { int rv = pthread_cond_init(&condition_, NULL); @@ -74,3 +73,5 @@ void ConditionVariable::Signal() { int rv = pthread_cond_signal(&condition_); DCHECK(rv == 0); } + +} // namespace base diff --git a/base/condition_variable_unittest.cc b/base/synchronization/condition_variable_unittest.cc index 18c9f2d19..8cfe4fe 100644 --- a/base/condition_variable_unittest.cc +++ b/base/synchronization/condition_variable_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,7 +8,7 @@ #include <algorithm> #include <vector> -#include "base/condition_variable.h" +#include "base/synchronization/condition_variable.h" #include "base/lock.h" #include "base/logging.h" #include "base/scoped_ptr.h" @@ -19,10 +19,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" -using base::PlatformThread; -using base::PlatformThreadHandle; -using base::TimeDelta; -using base::TimeTicks; +namespace base { namespace { //------------------------------------------------------------------------------ @@ -39,12 +36,12 @@ class ConditionVariableTest : public PlatformTest { const TimeDelta kOneHundredMs; explicit ConditionVariableTest() - : kZeroMs(TimeDelta::FromMilliseconds(0)), - kTenMs(TimeDelta::FromMilliseconds(10)), - kThirtyMs(TimeDelta::FromMilliseconds(30)), - kFortyFiveMs(TimeDelta::FromMilliseconds(45)), - kSixtyMs(TimeDelta::FromMilliseconds(60)), - kOneHundredMs(TimeDelta::FromMilliseconds(100)) { + : kZeroMs(TimeDelta::FromMilliseconds(0)), + kTenMs(TimeDelta::FromMilliseconds(10)), + kThirtyMs(TimeDelta::FromMilliseconds(30)), + kFortyFiveMs(TimeDelta::FromMilliseconds(45)), + kSixtyMs(TimeDelta::FromMilliseconds(60)), + kOneHundredMs(TimeDelta::FromMilliseconds(100)) { } }; @@ -198,7 +195,7 @@ TEST_F(ConditionVariableTest, MultiThreadConsumerTest) { const int kTaskCount = 10; // Number of tasks in each mini-test here. - base::Time start_time; // Used to time task processing. + Time start_time; // Used to time task processing. { AutoLock auto_lock(*queue.lock()); @@ -226,7 +223,7 @@ TEST_F(ConditionVariableTest, MultiThreadConsumerTest) { queue.SetWorkTime(kThirtyMs); queue.SetAllowHelp(false); - start_time = base::Time::Now(); + start_time = Time::Now(); } queue.work_is_available()->Signal(); // Start up one thread. @@ -241,7 +238,7 @@ TEST_F(ConditionVariableTest, MultiThreadConsumerTest) { // The last of the tasks *might* still be running, but... all but one should // be done by now, since tasks are being done serially. EXPECT_LE(queue.GetWorkTime().InMilliseconds() * (kTaskCount - 1), - (base::Time::Now() - start_time).InMilliseconds()); + (Time::Now() - start_time).InMilliseconds()); EXPECT_EQ(1, queue.GetNumThreadsTakingAssignments()); EXPECT_EQ(1, queue.GetNumThreadsCompletingTasks()); @@ -270,7 +267,7 @@ TEST_F(ConditionVariableTest, MultiThreadConsumerTest) { queue.SetWorkTime(kThirtyMs); queue.SetAllowHelp(true); - start_time = base::Time::Now(); + start_time = Time::Now(); } queue.work_is_available()->Signal(); // But each worker can signal another. @@ -749,3 +746,5 @@ void WorkQueue::ThreadMain() { } } // namespace + +} // namespace base diff --git a/base/condition_variable_win.cc b/base/synchronization/condition_variable_win.cc index 5150c23..3030178 100644 --- a/base/condition_variable_win.cc +++ b/base/synchronization/condition_variable_win.cc @@ -1,22 +1,22 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/condition_variable.h" +#include "base/synchronization/condition_variable.h" #include <stack> -#include "base/lock.h" #include "base/logging.h" +#include "base/synchronization/lock.h" #include "base/time.h" -using base::TimeDelta; +namespace base { ConditionVariable::ConditionVariable(Lock* user_lock) - : user_lock_(*user_lock), - run_state_(RUNNING), - allocation_counter_(0), - recycling_list_size_(0) { + : user_lock_(*user_lock), + run_state_(RUNNING), + allocation_counter_(0), + recycling_list_size_(0) { DCHECK(user_lock); } @@ -443,3 +443,5 @@ put so many assertions (DCHECKs) into the container class that it is trivial to code review and validate its correctness. */ + +} // namespace base diff --git a/base/lock.cc b/base/synchronization/lock.cc index dc21271..6445ce8 100644 --- a/base/lock.cc +++ b/base/synchronization/lock.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,11 +8,10 @@ #if !defined(NDEBUG) -#include "base/lock.h" +#include "base/synchronization/lock.h" #include "base/logging.h" -using base::PlatformThread; -using base::PlatformThreadId; +namespace base { Lock::Lock() : lock_() { owned_by_thread_ = false; @@ -37,4 +36,6 @@ void Lock::CheckUnheldAndMark() { owning_thread_id_ = PlatformThread::CurrentId(); } +} // namespace base + #endif // NDEBUG diff --git a/base/synchronization/lock.h b/base/synchronization/lock.h new file mode 100644 index 0000000..f7c9c49 --- /dev/null +++ b/base/synchronization/lock.h @@ -0,0 +1,131 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_SYNCHRONIZATION_LOCK_H_ +#define BASE_SYNCHRONIZATION_LOCK_H_ +#pragma once + +#include "base/synchronization/lock_impl.h" +#include "base/threading/platform_thread.h" + +namespace base { + +// A convenient wrapper for an OS specific critical section. The only real +// intelligence in this class is in debug mode for the support for the +// AssertAcquired() method. +class Lock { + public: +#if defined(NDEBUG) // Optimized wrapper implementation + Lock() : lock_() {} + ~Lock() {} + void Acquire() { lock_.Lock(); } + void Release() { lock_.Unlock(); } + + // If the lock is not held, take it and return true. If the lock is already + // held by another thread, immediately return false. This must not be called + // by a thread already holding the lock (what happens is undefined and an + // assertion may fail). + bool Try() { return lock_.Try(); } + + // Null implementation if not debug. + void AssertAcquired() const {} +#else + Lock(); + ~Lock() {} + + // NOTE: Although windows critical sections support recursive locks, we do not + // allow this, and we will commonly fire a DCHECK() if a thread attempts to + // acquire the lock a second time (while already holding it). + void Acquire() { + lock_.Lock(); + CheckUnheldAndMark(); + } + void Release() { + CheckHeldAndUnmark(); + lock_.Unlock(); + } + + bool Try() { + bool rv = lock_.Try(); + if (rv) { + CheckUnheldAndMark(); + } + return rv; + } + + void AssertAcquired() const; +#endif // NDEBUG + +#if defined(OS_POSIX) + // The posix implementation of ConditionVariable needs to be able + // to see our lock and tweak our debugging counters, as it releases + // and acquires locks inside of pthread_cond_{timed,}wait. + // Windows doesn't need to do this as it calls the Lock::* methods. + friend class ConditionVariable; +#endif + + private: +#if !defined(NDEBUG) + // Members and routines taking care of locks assertions. + // Note that this checks for recursive locks and allows them + // if the variable is set. This is allowed by the underlying implementation + // on windows but not on Posix, so we're doing unneeded checks on Posix. + // It's worth it to share the code. + void CheckHeldAndUnmark(); + void CheckUnheldAndMark(); + + // All private data is implicitly protected by lock_. + // Be VERY careful to only access members under that lock. + + // Determines validity of owning_thread_id_. Needed as we don't have + // a null owning_thread_id_ value. + bool owned_by_thread_; + base::PlatformThreadId owning_thread_id_; +#endif // NDEBUG + + // Platform specific underlying lock implementation. + internal::LockImpl lock_; + + DISALLOW_COPY_AND_ASSIGN(Lock); +}; + +// A helper class that acquires the given Lock while the AutoLock is in scope. +class AutoLock { + public: + explicit AutoLock(Lock& lock) : lock_(lock) { + lock_.Acquire(); + } + + ~AutoLock() { + lock_.AssertAcquired(); + lock_.Release(); + } + + private: + Lock& lock_; + DISALLOW_COPY_AND_ASSIGN(AutoLock); +}; + +// AutoUnlock is a helper that will Release() the |lock| argument in the +// constructor, and re-Acquire() it in the destructor. +class AutoUnlock { + public: + explicit AutoUnlock(Lock& lock) : lock_(lock) { + // We require our caller to have the lock. + lock_.AssertAcquired(); + lock_.Release(); + } + + ~AutoUnlock() { + lock_.Acquire(); + } + + private: + Lock& lock_; + DISALLOW_COPY_AND_ASSIGN(AutoUnlock); +}; + +} // namespace base + +#endif // BASE_SYNCHRONIZATION_LOCK_H_ diff --git a/base/lock_impl.h b/base/synchronization/lock_impl.h index 6066495..2994610 100644 --- a/base/lock_impl.h +++ b/base/synchronization/lock_impl.h @@ -1,9 +1,9 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef BASE_LOCK_IMPL_H_ -#define BASE_LOCK_IMPL_H_ +#ifndef BASE_SYNCHRONIZATION_LOCK_IMPL_H_ +#define BASE_SYNCHRONIZATION_LOCK_IMPL_H_ #pragma once #include "build/build_config.h" @@ -16,6 +16,9 @@ #include "base/basictypes.h" +namespace base { +namespace internal { + // This class implements the underlying platform-specific spin-lock mechanism // used for the Lock class. Most users should not use LockImpl directly, but // should instead use Lock. @@ -54,5 +57,7 @@ class LockImpl { DISALLOW_COPY_AND_ASSIGN(LockImpl); }; +} // namespace internal +} // namespace base -#endif // BASE_LOCK_IMPL_H_ +#endif // BASE_SYNCHRONIZATION_LOCK_IMPL_H_ diff --git a/base/lock_impl_posix.cc b/base/synchronization/lock_impl_posix.cc index 355149f..f638fcd 100644 --- a/base/lock_impl_posix.cc +++ b/base/synchronization/lock_impl_posix.cc @@ -1,13 +1,16 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/lock_impl.h" +#include "base/synchronization/lock_impl.h" #include <errno.h> #include "base/logging.h" +namespace base { +namespace internal { + LockImpl::LockImpl() { #ifndef NDEBUG // In debug, setup attributes for lock error checking. @@ -46,3 +49,6 @@ void LockImpl::Unlock() { int rv = pthread_mutex_unlock(&os_lock_); DCHECK_EQ(rv, 0); } + +} // namespace internal +} // namespace base diff --git a/base/lock_impl_win.cc b/base/synchronization/lock_impl_win.cc index 8c03b61..bb8a23d 100644 --- a/base/lock_impl_win.cc +++ b/base/synchronization/lock_impl_win.cc @@ -1,8 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/lock_impl.h" +#include "base/synchronization/lock_impl.h" + +namespace base { +namespace internal { LockImpl::LockImpl() { // The second parameter is the spin count, for short-held locks it avoid the @@ -28,3 +31,6 @@ void LockImpl::Lock() { void LockImpl::Unlock() { ::LeaveCriticalSection(&os_lock_); } + +} // namespace internal +} // namespace base diff --git a/base/lock_unittest.cc b/base/synchronization/lock_unittest.cc index a0a8d48..5ac3e6b 100644 --- a/base/lock_unittest.cc +++ b/base/synchronization/lock_unittest.cc @@ -1,19 +1,14 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/lock.h" - #include <stdlib.h> +#include "base/synchronization/lock.h" #include "base/threading/platform_thread.h" #include "testing/gtest/include/gtest/gtest.h" -using base::kNullThreadHandle; -using base::PlatformThread; -using base::PlatformThreadHandle; - -typedef testing::Test LockTest; +namespace base { // Basic test to make sure that Acquire()/Release()/Try() don't crash ---------- @@ -51,7 +46,7 @@ class BasicLockTestThread : public PlatformThread::Delegate { DISALLOW_COPY_AND_ASSIGN(BasicLockTestThread); }; -TEST_F(LockTest, Basic) { +TEST(LockTest, Basic) { Lock lock; BasicLockTestThread thread(&lock); PlatformThreadHandle handle = kNullThreadHandle; @@ -111,7 +106,7 @@ class TryLockTestThread : public PlatformThread::Delegate { DISALLOW_COPY_AND_ASSIGN(TryLockTestThread); }; -TEST_F(LockTest, TryLock) { +TEST(LockTest, TryLock) { Lock lock; ASSERT_TRUE(lock.Try()); @@ -176,7 +171,7 @@ class MutexLockTestThread : public PlatformThread::Delegate { DISALLOW_COPY_AND_ASSIGN(MutexLockTestThread); }; -TEST_F(LockTest, MutexTwoThreads) { +TEST(LockTest, MutexTwoThreads) { Lock lock; int value = 0; @@ -192,7 +187,7 @@ TEST_F(LockTest, MutexTwoThreads) { EXPECT_EQ(2 * 40, value); } -TEST_F(LockTest, MutexFourThreads) { +TEST(LockTest, MutexFourThreads) { Lock lock; int value = 0; @@ -215,3 +210,5 @@ TEST_F(LockTest, MutexFourThreads) { EXPECT_EQ(4 * 40, value); } + +} // namespace base diff --git a/base/threading/watchdog.h b/base/threading/watchdog.h index 8641f04..bf95639 100644 --- a/base/threading/watchdog.h +++ b/base/threading/watchdog.h @@ -21,8 +21,8 @@ #include <string> -#include "base/condition_variable.h" -#include "base/lock.h" +#include "base/synchronization/condition_variable.h" +#include "base/synchronization/lock.h" #include "base/threading/platform_thread.h" #include "base/time.h" @@ -31,15 +31,15 @@ namespace base { class Watchdog { public: // Constructor specifies how long the Watchdog will wait before alarming. - Watchdog(const base::TimeDelta& duration, + Watchdog(const TimeDelta& duration, const std::string& thread_watched_name, bool enabled); virtual ~Watchdog(); // Start timing, and alarm when time expires (unless we're disarm()ed.) void Arm(); // Arm starting now. - void ArmSomeTimeDeltaAgo(const base::TimeDelta& time_delta); - void ArmAtStartTime(const base::TimeTicks start_time); + void ArmSomeTimeDeltaAgo(const TimeDelta& time_delta); + void ArmAtStartTime(const TimeTicks start_time); // Reset time, and do not set off the alarm. void Disarm(); @@ -71,12 +71,12 @@ class Watchdog { Lock lock_; // Mutex for state_. ConditionVariable condition_variable_; State state_; - const base::TimeDelta duration_; // How long after start_time_ do we alarm? + const TimeDelta duration_; // How long after start_time_ do we alarm? const std::string thread_watched_name_; PlatformThreadHandle handle_; ThreadDelegate delegate_; // Store it, because it must outlive the thread. - base::TimeTicks start_time_; // Start of epoch, and alarm after duration_. + TimeTicks start_time_; // Start of epoch, and alarm after duration_. // When the debugger breaks (when we alarm), all the other alarms that are // armed will expire (also alarm). To diminish this effect, we track any @@ -86,9 +86,9 @@ class Watchdog { // on alarms from callers that specify old times. static Lock static_lock_; // Lock for access of static data... // When did we last alarm and get stuck (for a while) in a debugger? - static base::TimeTicks last_debugged_alarm_time_; + static TimeTicks last_debugged_alarm_time_; // How long did we sit on a break in the debugger? - static base::TimeDelta last_debugged_alarm_delay_; + static TimeDelta last_debugged_alarm_delay_; DISALLOW_COPY_AND_ASSIGN(Watchdog); }; diff --git a/base/threading/worker_pool_posix.h b/base/threading/worker_pool_posix.h index 44f0208..1b68aef 100644 --- a/base/threading/worker_pool_posix.h +++ b/base/threading/worker_pool_posix.h @@ -29,10 +29,10 @@ #include <string> #include "base/basictypes.h" -#include "base/condition_variable.h" -#include "base/lock.h" #include "base/ref_counted.h" #include "base/scoped_ptr.h" +#include "base/synchronization/condition_variable.h" +#include "base/synchronization/lock.h" #include "base/threading/platform_thread.h" class Task; diff --git a/base/threading/worker_pool_posix_unittest.cc b/base/threading/worker_pool_posix_unittest.cc index 25509bf..9be82c0 100644 --- a/base/threading/worker_pool_posix_unittest.cc +++ b/base/threading/worker_pool_posix_unittest.cc @@ -6,8 +6,8 @@ #include <set> -#include "base/condition_variable.h" #include "base/lock.h" +#include "base/synchronization/condition_variable.h" #include "base/task.h" #include "base/threading/platform_thread.h" #include "base/waitable_event.h" diff --git a/base/waitable_event_posix.cc b/base/waitable_event_posix.cc index adc521e..f6a6aab 100644 --- a/base/waitable_event_posix.cc +++ b/base/waitable_event_posix.cc @@ -1,11 +1,11 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/waitable_event.h" -#include "base/condition_variable.h" -#include "base/lock.h" +#include "base/synchronization/condition_variable.h" +#include "base/synchronization/lock.h" #include "base/message_loop.h" // ----------------------------------------------------------------------------- @@ -42,12 +42,12 @@ WaitableEvent::~WaitableEvent() { } void WaitableEvent::Reset() { - AutoLock locked(kernel_->lock_); + base::AutoLock locked(kernel_->lock_); kernel_->signaled_ = false; } void WaitableEvent::Signal() { - AutoLock locked(kernel_->lock_); + base::AutoLock locked(kernel_->lock_); if (kernel_->signaled_) return; @@ -64,7 +64,7 @@ void WaitableEvent::Signal() { } bool WaitableEvent::IsSignaled() { - AutoLock locked(kernel_->lock_); + base::AutoLock locked(kernel_->lock_); const bool result = kernel_->signaled_; if (result && !kernel_->manual_reset_) @@ -89,7 +89,7 @@ class SyncWaiter : public WaitableEvent::Waiter { } bool Fire(WaitableEvent* signaling_event) { - AutoLock locked(lock_); + base::AutoLock locked(lock_); if (fired_) return false; @@ -134,19 +134,19 @@ class SyncWaiter : public WaitableEvent::Waiter { fired_ = true; } - Lock* lock() { + base::Lock* lock() { return &lock_; } - ConditionVariable* cv() { + base::ConditionVariable* cv() { return &cv_; } private: bool fired_; WaitableEvent* signaling_event_; // The WaitableEvent which woke us - Lock lock_; - ConditionVariable cv_; + base::Lock lock_; + base::ConditionVariable cv_; }; bool WaitableEvent::TimedWait(const TimeDelta& max_time) { diff --git a/base/waitable_event_watcher_posix.cc b/base/waitable_event_watcher_posix.cc index 07ae694..148caaa 100644 --- a/base/waitable_event_watcher_posix.cc +++ b/base/waitable_event_watcher_posix.cc @@ -1,12 +1,11 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/waitable_event_watcher.h" -#include "base/condition_variable.h" -#include "base/lock.h" #include "base/message_loop.h" +#include "base/synchronization/lock.h" #include "base/waitable_event.h" namespace base { |