1 /* 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef WEBRTC_BASE_CRITICALSECTION_H_ 12 #define WEBRTC_BASE_CRITICALSECTION_H_ 13 14 #include "webrtc/base/atomicops.h" 15 #include "webrtc/base/constructormagic.h" 16 #include "webrtc/base/thread_annotations.h" 17 18 #if defined(WEBRTC_WIN) 19 // Include winsock2.h before including <windows.h> to maintain consistency with 20 // win32.h. We can't include win32.h directly here since it pulls in 21 // headers such as basictypes.h which causes problems in Chromium where webrtc 22 // exists as two separate projects, webrtc and libjingle. 23 #include <winsock2.h> 24 #include <windows.h> 25 #include <sal.h> // must come after windows headers. 26 #endif // defined(WEBRTC_WIN) 27 28 #if defined(WEBRTC_POSIX) 29 #include <pthread.h> 30 #endif 31 32 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) 33 #define CS_DEBUG_CHECKS 1 34 #endif 35 36 #if CS_DEBUG_CHECKS 37 #define CS_DEBUG_CODE(x) x 38 #else // !CS_DEBUG_CHECKS 39 #define CS_DEBUG_CODE(x) 40 #endif // !CS_DEBUG_CHECKS 41 42 namespace rtc { 43 44 class LOCKABLE CriticalSection { 45 public: 46 CriticalSection(); 47 ~CriticalSection(); 48 49 void Enter() EXCLUSIVE_LOCK_FUNCTION(); 50 bool TryEnter() EXCLUSIVE_TRYLOCK_FUNCTION(true); 51 void Leave() UNLOCK_FUNCTION(); 52 53 // Use only for RTC_DCHECKing. 54 bool CurrentThreadIsOwner() const; 55 // Use only for RTC_DCHECKing. 56 bool IsLocked() const; 57 58 private: 59 #if defined(WEBRTC_WIN) 60 CRITICAL_SECTION crit_; 61 #elif defined(WEBRTC_POSIX) 62 pthread_mutex_t mutex_; 63 CS_DEBUG_CODE(pthread_t thread_); 64 CS_DEBUG_CODE(int recursion_count_); 65 #endif 66 }; 67 68 // CritScope, for serializing execution through a scope. 69 class SCOPED_LOCKABLE CritScope { 70 public: 71 explicit CritScope(CriticalSection* cs) EXCLUSIVE_LOCK_FUNCTION(cs); 72 ~CritScope() UNLOCK_FUNCTION(); 73 private: 74 CriticalSection* const cs_; 75 RTC_DISALLOW_COPY_AND_ASSIGN(CritScope); 76 }; 77 78 // Tries to lock a critical section on construction via 79 // CriticalSection::TryEnter, and unlocks on destruction if the 80 // lock was taken. Never blocks. 81 // 82 // IMPORTANT: Unlike CritScope, the lock may not be owned by this thread in 83 // subsequent code. Users *must* check locked() to determine if the 84 // lock was taken. If you're not calling locked(), you're doing it wrong! 85 class TryCritScope { 86 public: 87 explicit TryCritScope(CriticalSection* cs); 88 ~TryCritScope(); 89 #if defined(WEBRTC_WIN) 90 _Check_return_ bool locked() const; 91 #else 92 bool locked() const __attribute__ ((__warn_unused_result__)); 93 #endif 94 private: 95 CriticalSection* const cs_; 96 const bool locked_; 97 CS_DEBUG_CODE(mutable bool lock_was_called_); 98 RTC_DISALLOW_COPY_AND_ASSIGN(TryCritScope); 99 }; 100 101 // A POD lock used to protect global variables. Do NOT use for other purposes. 102 // No custom constructor or private data member should be added. 103 class LOCKABLE GlobalLockPod { 104 public: 105 void Lock() EXCLUSIVE_LOCK_FUNCTION(); 106 107 void Unlock() UNLOCK_FUNCTION(); 108 109 volatile int lock_acquired; 110 }; 111 112 class GlobalLock : public GlobalLockPod { 113 public: 114 GlobalLock(); 115 }; 116 117 // GlobalLockScope, for serializing execution through a scope. 118 class SCOPED_LOCKABLE GlobalLockScope { 119 public: 120 explicit GlobalLockScope(GlobalLockPod* lock) EXCLUSIVE_LOCK_FUNCTION(lock); 121 ~GlobalLockScope() UNLOCK_FUNCTION(); 122 private: 123 GlobalLockPod* const lock_; 124 RTC_DISALLOW_COPY_AND_ASSIGN(GlobalLockScope); 125 }; 126 127 } // namespace rtc 128 129 #endif // WEBRTC_BASE_CRITICALSECTION_H_ 130