LCOV - code coverage report
Current view: top level - src/base/platform - mutex.h (source / functions) Hit Total Coverage
Test: app.info Lines: 2 2 100.0 %
Date: 2017-04-26 Functions: 2 2 100.0 %

          Line data    Source code
       1             : // Copyright 2013 the V8 project 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.
       4             : 
       5             : #ifndef V8_BASE_PLATFORM_MUTEX_H_
       6             : #define V8_BASE_PLATFORM_MUTEX_H_
       7             : 
       8             : #include "src/base/base-export.h"
       9             : #include "src/base/lazy-instance.h"
      10             : #if V8_OS_WIN
      11             : #include "src/base/win32-headers.h"
      12             : #endif
      13             : #include "src/base/logging.h"
      14             : 
      15             : #if V8_OS_POSIX
      16             : #include <pthread.h>  // NOLINT
      17             : #endif
      18             : 
      19             : namespace v8 {
      20             : namespace base {
      21             : 
      22             : // ----------------------------------------------------------------------------
      23             : // Mutex
      24             : //
      25             : // This class is a synchronization primitive that can be used to protect shared
      26             : // data from being simultaneously accessed by multiple threads. A mutex offers
      27             : // exclusive, non-recursive ownership semantics:
      28             : // - A calling thread owns a mutex from the time that it successfully calls
      29             : //   either |Lock()| or |TryLock()| until it calls |Unlock()|.
      30             : // - When a thread owns a mutex, all other threads will block (for calls to
      31             : //   |Lock()|) or receive a |false| return value (for |TryLock()|) if they
      32             : //   attempt to claim ownership of the mutex.
      33             : // A calling thread must not own the mutex prior to calling |Lock()| or
      34             : // |TryLock()|. The behavior of a program is undefined if a mutex is destroyed
      35             : // while still owned by some thread. The Mutex class is non-copyable.
      36             : 
      37             : class V8_BASE_EXPORT Mutex final {
      38             :  public:
      39             :   Mutex();
      40             :   ~Mutex();
      41             : 
      42             :   // Locks the given mutex. If the mutex is currently unlocked, it becomes
      43             :   // locked and owned by the calling thread, and immediately. If the mutex
      44             :   // is already locked by another thread, suspends the calling thread until
      45             :   // the mutex is unlocked.
      46             :   void Lock();
      47             : 
      48             :   // Unlocks the given mutex. The mutex is assumed to be locked and owned by
      49             :   // the calling thread on entrance.
      50             :   void Unlock();
      51             : 
      52             :   // Tries to lock the given mutex. Returns whether the mutex was
      53             :   // successfully locked.
      54             :   bool TryLock() WARN_UNUSED_RESULT;
      55             : 
      56             :   // The implementation-defined native handle type.
      57             : #if V8_OS_POSIX
      58             :   typedef pthread_mutex_t NativeHandle;
      59             : #elif V8_OS_WIN
      60             :   typedef CRITICAL_SECTION NativeHandle;
      61             : #endif
      62             : 
      63             :   NativeHandle& native_handle() {
      64             :     return native_handle_;
      65             :   }
      66             :   const NativeHandle& native_handle() const {
      67             :     return native_handle_;
      68             :   }
      69             : 
      70             :  private:
      71             :   NativeHandle native_handle_;
      72             : #ifdef DEBUG
      73             :   int level_;
      74             : #endif
      75             : 
      76             :   V8_INLINE void AssertHeldAndUnmark() {
      77             : #ifdef DEBUG
      78             :     DCHECK_EQ(1, level_);
      79             :     level_--;
      80             : #endif
      81             :   }
      82             : 
      83             :   V8_INLINE void AssertUnheldAndMark() {
      84             : #ifdef DEBUG
      85             :     DCHECK_EQ(0, level_);
      86             :     level_++;
      87             : #endif
      88             :   }
      89             : 
      90             :   friend class ConditionVariable;
      91             : 
      92             :   DISALLOW_COPY_AND_ASSIGN(Mutex);
      93             : };
      94             : 
      95             : 
      96             : // POD Mutex initialized lazily (i.e. the first time Pointer() is called).
      97             : // Usage:
      98             : //   static LazyMutex my_mutex = LAZY_MUTEX_INITIALIZER;
      99             : //
     100             : //   void my_function() {
     101             : //     LockGuard<Mutex> guard(my_mutex.Pointer());
     102             : //     // Do something.
     103             : //   }
     104             : //
     105             : typedef LazyStaticInstance<Mutex, DefaultConstructTrait<Mutex>,
     106             :                            ThreadSafeInitOnceTrait>::type LazyMutex;
     107             : 
     108             : #define LAZY_MUTEX_INITIALIZER LAZY_STATIC_INSTANCE_INITIALIZER
     109             : 
     110             : 
     111             : // -----------------------------------------------------------------------------
     112             : // RecursiveMutex
     113             : //
     114             : // This class is a synchronization primitive that can be used to protect shared
     115             : // data from being simultaneously accessed by multiple threads. A recursive
     116             : // mutex offers exclusive, recursive ownership semantics:
     117             : // - A calling thread owns a recursive mutex for a period of time that starts
     118             : //   when it successfully calls either |Lock()| or |TryLock()|. During this
     119             : //   period, the thread may make additional calls to |Lock()| or |TryLock()|.
     120             : //   The period of ownership ends when the thread makes a matching number of
     121             : //   calls to |Unlock()|.
     122             : // - When a thread owns a recursive mutex, all other threads will block (for
     123             : //   calls to |Lock()|) or receive a |false| return value (for |TryLock()|) if
     124             : //   they attempt to claim ownership of the recursive mutex.
     125             : // - The maximum number of times that a recursive mutex may be locked is
     126             : //   unspecified, but after that number is reached, calls to |Lock()| will
     127             : //   probably abort the process and calls to |TryLock()| return false.
     128             : // The behavior of a program is undefined if a recursive mutex is destroyed
     129             : // while still owned by some thread. The RecursiveMutex class is non-copyable.
     130             : 
     131             : class V8_BASE_EXPORT RecursiveMutex final {
     132             :  public:
     133             :   RecursiveMutex();
     134             :   ~RecursiveMutex();
     135             : 
     136             :   // Locks the mutex. If another thread has already locked the mutex, a call to
     137             :   // |Lock()| will block execution until the lock is acquired. A thread may call
     138             :   // |Lock()| on a recursive mutex repeatedly. Ownership will only be released
     139             :   // after the thread makes a matching number of calls to |Unlock()|.
     140             :   // The behavior is undefined if the mutex is not unlocked before being
     141             :   // destroyed, i.e. some thread still owns it.
     142             :   void Lock();
     143             : 
     144             :   // Unlocks the mutex if its level of ownership is 1 (there was exactly one
     145             :   // more call to |Lock()| than there were calls to unlock() made by this
     146             :   // thread), reduces the level of ownership by 1 otherwise. The mutex must be
     147             :   // locked by the current thread of execution, otherwise, the behavior is
     148             :   // undefined.
     149             :   void Unlock();
     150             : 
     151             :   // Tries to lock the given mutex. Returns whether the mutex was
     152             :   // successfully locked.
     153             :   bool TryLock() WARN_UNUSED_RESULT;
     154             : 
     155             :   // The implementation-defined native handle type.
     156             :   typedef Mutex::NativeHandle NativeHandle;
     157             : 
     158             :   NativeHandle& native_handle() {
     159             :     return native_handle_;
     160             :   }
     161             :   const NativeHandle& native_handle() const {
     162             :     return native_handle_;
     163             :   }
     164             : 
     165             :  private:
     166             :   NativeHandle native_handle_;
     167             : #ifdef DEBUG
     168             :   int level_;
     169             : #endif
     170             : 
     171             :   DISALLOW_COPY_AND_ASSIGN(RecursiveMutex);
     172             : };
     173             : 
     174             : 
     175             : // POD RecursiveMutex initialized lazily (i.e. the first time Pointer() is
     176             : // called).
     177             : // Usage:
     178             : //   static LazyRecursiveMutex my_mutex = LAZY_RECURSIVE_MUTEX_INITIALIZER;
     179             : //
     180             : //   void my_function() {
     181             : //     LockGuard<RecursiveMutex> guard(my_mutex.Pointer());
     182             : //     // Do something.
     183             : //   }
     184             : //
     185             : typedef LazyStaticInstance<RecursiveMutex,
     186             :                            DefaultConstructTrait<RecursiveMutex>,
     187             :                            ThreadSafeInitOnceTrait>::type LazyRecursiveMutex;
     188             : 
     189             : #define LAZY_RECURSIVE_MUTEX_INITIALIZER LAZY_STATIC_INSTANCE_INITIALIZER
     190             : 
     191             : 
     192             : // -----------------------------------------------------------------------------
     193             : // LockGuard
     194             : //
     195             : // This class is a mutex wrapper that provides a convenient RAII-style mechanism
     196             : // for owning a mutex for the duration of a scoped block.
     197             : // When a LockGuard object is created, it attempts to take ownership of the
     198             : // mutex it is given. When control leaves the scope in which the LockGuard
     199             : // object was created, the LockGuard is destructed and the mutex is released.
     200             : // The LockGuard class is non-copyable.
     201             : 
     202             : template <typename Mutex>
     203             : class LockGuard final {
     204             :  public:
     205   183391612 :   explicit LockGuard(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); }
     206   182677388 :   ~LockGuard() { mutex_->Unlock(); }
     207             : 
     208             :  private:
     209             :   Mutex* mutex_;
     210             : 
     211             :   DISALLOW_COPY_AND_ASSIGN(LockGuard);
     212             : };
     213             : 
     214             : }  // namespace base
     215             : }  // namespace v8
     216             : 
     217             : #endif  // V8_BASE_PLATFORM_MUTEX_H_

Generated by: LCOV version 1.10