security/sandbox/chromium/base/synchronization/lock.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
     2 // Use of this source code is governed by a BSD-style license that can be
     3 // found in the LICENSE file.
     5 #ifndef BASE_SYNCHRONIZATION_LOCK_H_
     6 #define BASE_SYNCHRONIZATION_LOCK_H_
     8 #include "base/base_export.h"
     9 #include "base/synchronization/lock_impl.h"
    10 #include "base/threading/platform_thread.h"
    12 namespace base {
    14 // A convenient wrapper for an OS specific critical section.  The only real
    15 // intelligence in this class is in debug mode for the support for the
    16 // AssertAcquired() method.
    17 class BASE_EXPORT Lock {
    18  public:
    19 #if defined(NDEBUG)             // Optimized wrapper implementation
    20   Lock() : lock_() {}
    21   ~Lock() {}
    22   void Acquire() { lock_.Lock(); }
    23   void Release() { lock_.Unlock(); }
    25   // If the lock is not held, take it and return true. If the lock is already
    26   // held by another thread, immediately return false. This must not be called
    27   // by a thread already holding the lock (what happens is undefined and an
    28   // assertion may fail).
    29   bool Try() { return lock_.Try(); }
    31   // Null implementation if not debug.
    32   void AssertAcquired() const {}
    33 #else
    34   Lock();
    35   ~Lock();
    37   // NOTE: Although windows critical sections support recursive locks, we do not
    38   // allow this, and we will commonly fire a DCHECK() if a thread attempts to
    39   // acquire the lock a second time (while already holding it).
    40   void Acquire() {
    41     lock_.Lock();
    42     CheckUnheldAndMark();
    43   }
    44   void Release() {
    45     CheckHeldAndUnmark();
    46     lock_.Unlock();
    47   }
    49   bool Try() {
    50     bool rv = lock_.Try();
    51     if (rv) {
    52       CheckUnheldAndMark();
    53     }
    54     return rv;
    55   }
    57   void AssertAcquired() const;
    58 #endif                          // NDEBUG
    60 #if defined(OS_POSIX)
    61   // The posix implementation of ConditionVariable needs to be able
    62   // to see our lock and tweak our debugging counters, as it releases
    63   // and acquires locks inside of pthread_cond_{timed,}wait.
    64   friend class ConditionVariable;
    65 #elif defined(OS_WIN)
    66   // The Windows Vista implementation of ConditionVariable needs the
    67   // native handle of the critical section.
    68   friend class WinVistaCondVar;
    69 #endif
    71  private:
    72 #if !defined(NDEBUG)
    73   // Members and routines taking care of locks assertions.
    74   // Note that this checks for recursive locks and allows them
    75   // if the variable is set.  This is allowed by the underlying implementation
    76   // on windows but not on Posix, so we're doing unneeded checks on Posix.
    77   // It's worth it to share the code.
    78   void CheckHeldAndUnmark();
    79   void CheckUnheldAndMark();
    81   // All private data is implicitly protected by lock_.
    82   // Be VERY careful to only access members under that lock.
    84   // Determines validity of owning_thread_id_.  Needed as we don't have
    85   // a null owning_thread_id_ value.
    86   bool owned_by_thread_;
    87   base::PlatformThreadId owning_thread_id_;
    88 #endif  // NDEBUG
    90   // Platform specific underlying lock implementation.
    91   internal::LockImpl lock_;
    93   DISALLOW_COPY_AND_ASSIGN(Lock);
    94 };
    96 // A helper class that acquires the given Lock while the AutoLock is in scope.
    97 class AutoLock {
    98  public:
    99   struct AlreadyAcquired {};
   101   explicit AutoLock(Lock& lock) : lock_(lock) {
   102     lock_.Acquire();
   103   }
   105   AutoLock(Lock& lock, const AlreadyAcquired&) : lock_(lock) {
   106     lock_.AssertAcquired();
   107   }
   109   ~AutoLock() {
   110     lock_.AssertAcquired();
   111     lock_.Release();
   112   }
   114  private:
   115   Lock& lock_;
   116   DISALLOW_COPY_AND_ASSIGN(AutoLock);
   117 };
   119 // AutoUnlock is a helper that will Release() the |lock| argument in the
   120 // constructor, and re-Acquire() it in the destructor.
   121 class AutoUnlock {
   122  public:
   123   explicit AutoUnlock(Lock& lock) : lock_(lock) {
   124     // We require our caller to have the lock.
   125     lock_.AssertAcquired();
   126     lock_.Release();
   127   }
   129   ~AutoUnlock() {
   130     lock_.Acquire();
   131   }
   133  private:
   134   Lock& lock_;
   135   DISALLOW_COPY_AND_ASSIGN(AutoUnlock);
   136 };
   138 }  // namespace base
   140 #endif  // BASE_SYNCHRONIZATION_LOCK_H_

mercurial