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

changeset 0
6474c204b198
     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_

mercurial