1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/chromium/base/synchronization/lock.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,140 @@ 1.4 +// Copyright (c) 2011 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#ifndef BASE_SYNCHRONIZATION_LOCK_H_ 1.9 +#define BASE_SYNCHRONIZATION_LOCK_H_ 1.10 + 1.11 +#include "base/base_export.h" 1.12 +#include "base/synchronization/lock_impl.h" 1.13 +#include "base/threading/platform_thread.h" 1.14 + 1.15 +namespace base { 1.16 + 1.17 +// A convenient wrapper for an OS specific critical section. The only real 1.18 +// intelligence in this class is in debug mode for the support for the 1.19 +// AssertAcquired() method. 1.20 +class BASE_EXPORT Lock { 1.21 + public: 1.22 +#if defined(NDEBUG) // Optimized wrapper implementation 1.23 + Lock() : lock_() {} 1.24 + ~Lock() {} 1.25 + void Acquire() { lock_.Lock(); } 1.26 + void Release() { lock_.Unlock(); } 1.27 + 1.28 + // If the lock is not held, take it and return true. If the lock is already 1.29 + // held by another thread, immediately return false. This must not be called 1.30 + // by a thread already holding the lock (what happens is undefined and an 1.31 + // assertion may fail). 1.32 + bool Try() { return lock_.Try(); } 1.33 + 1.34 + // Null implementation if not debug. 1.35 + void AssertAcquired() const {} 1.36 +#else 1.37 + Lock(); 1.38 + ~Lock(); 1.39 + 1.40 + // NOTE: Although windows critical sections support recursive locks, we do not 1.41 + // allow this, and we will commonly fire a DCHECK() if a thread attempts to 1.42 + // acquire the lock a second time (while already holding it). 1.43 + void Acquire() { 1.44 + lock_.Lock(); 1.45 + CheckUnheldAndMark(); 1.46 + } 1.47 + void Release() { 1.48 + CheckHeldAndUnmark(); 1.49 + lock_.Unlock(); 1.50 + } 1.51 + 1.52 + bool Try() { 1.53 + bool rv = lock_.Try(); 1.54 + if (rv) { 1.55 + CheckUnheldAndMark(); 1.56 + } 1.57 + return rv; 1.58 + } 1.59 + 1.60 + void AssertAcquired() const; 1.61 +#endif // NDEBUG 1.62 + 1.63 +#if defined(OS_POSIX) 1.64 + // The posix implementation of ConditionVariable needs to be able 1.65 + // to see our lock and tweak our debugging counters, as it releases 1.66 + // and acquires locks inside of pthread_cond_{timed,}wait. 1.67 + friend class ConditionVariable; 1.68 +#elif defined(OS_WIN) 1.69 + // The Windows Vista implementation of ConditionVariable needs the 1.70 + // native handle of the critical section. 1.71 + friend class WinVistaCondVar; 1.72 +#endif 1.73 + 1.74 + private: 1.75 +#if !defined(NDEBUG) 1.76 + // Members and routines taking care of locks assertions. 1.77 + // Note that this checks for recursive locks and allows them 1.78 + // if the variable is set. This is allowed by the underlying implementation 1.79 + // on windows but not on Posix, so we're doing unneeded checks on Posix. 1.80 + // It's worth it to share the code. 1.81 + void CheckHeldAndUnmark(); 1.82 + void CheckUnheldAndMark(); 1.83 + 1.84 + // All private data is implicitly protected by lock_. 1.85 + // Be VERY careful to only access members under that lock. 1.86 + 1.87 + // Determines validity of owning_thread_id_. Needed as we don't have 1.88 + // a null owning_thread_id_ value. 1.89 + bool owned_by_thread_; 1.90 + base::PlatformThreadId owning_thread_id_; 1.91 +#endif // NDEBUG 1.92 + 1.93 + // Platform specific underlying lock implementation. 1.94 + internal::LockImpl lock_; 1.95 + 1.96 + DISALLOW_COPY_AND_ASSIGN(Lock); 1.97 +}; 1.98 + 1.99 +// A helper class that acquires the given Lock while the AutoLock is in scope. 1.100 +class AutoLock { 1.101 + public: 1.102 + struct AlreadyAcquired {}; 1.103 + 1.104 + explicit AutoLock(Lock& lock) : lock_(lock) { 1.105 + lock_.Acquire(); 1.106 + } 1.107 + 1.108 + AutoLock(Lock& lock, const AlreadyAcquired&) : lock_(lock) { 1.109 + lock_.AssertAcquired(); 1.110 + } 1.111 + 1.112 + ~AutoLock() { 1.113 + lock_.AssertAcquired(); 1.114 + lock_.Release(); 1.115 + } 1.116 + 1.117 + private: 1.118 + Lock& lock_; 1.119 + DISALLOW_COPY_AND_ASSIGN(AutoLock); 1.120 +}; 1.121 + 1.122 +// AutoUnlock is a helper that will Release() the |lock| argument in the 1.123 +// constructor, and re-Acquire() it in the destructor. 1.124 +class AutoUnlock { 1.125 + public: 1.126 + explicit AutoUnlock(Lock& lock) : lock_(lock) { 1.127 + // We require our caller to have the lock. 1.128 + lock_.AssertAcquired(); 1.129 + lock_.Release(); 1.130 + } 1.131 + 1.132 + ~AutoUnlock() { 1.133 + lock_.Acquire(); 1.134 + } 1.135 + 1.136 + private: 1.137 + Lock& lock_; 1.138 + DISALLOW_COPY_AND_ASSIGN(AutoUnlock); 1.139 +}; 1.140 + 1.141 +} // namespace base 1.142 + 1.143 +#endif // BASE_SYNCHRONIZATION_LOCK_H_