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 RTC_BASE_DEPRECATED_RECURSIVE_CRITICAL_SECTION_H_ 12 #define RTC_BASE_DEPRECATED_RECURSIVE_CRITICAL_SECTION_H_ 13 14 #include "rtc_base/constructor_magic.h" 15 #include "rtc_base/platform_thread_types.h" 16 #include "rtc_base/thread_annotations.h" 17 18 #if defined(WEBRTC_WIN) 19 // clang-format off 20 // clang formating would change include order. 21 22 // Include winsock2.h before including <windows.h> to maintain consistency with 23 // win32.h. To include win32.h directly, it must be broken out into its own 24 // build target. 25 #include <winsock2.h> 26 #include <windows.h> 27 #include <sal.h> // must come after windows headers. 28 // clang-format on 29 #endif // defined(WEBRTC_WIN) 30 31 #if defined(WEBRTC_POSIX) 32 #include <pthread.h> 33 #endif 34 35 // See notes in the 'Performance' unit test for the effects of this flag. 36 #define RTC_USE_NATIVE_MUTEX_ON_MAC 1 37 38 #if defined(WEBRTC_MAC) && !RTC_USE_NATIVE_MUTEX_ON_MAC 39 #include <dispatch/dispatch.h> 40 #endif 41 42 namespace rtc { 43 44 // NOTE: This class is deprecated. Please use webrtc::Mutex instead! 45 // Search using https://www.google.com/?q=recursive+lock+considered+harmful 46 // to find the reasons. 47 // 48 // Locking methods (Enter, TryEnter, Leave)are const to permit protecting 49 // members inside a const context without requiring mutable 50 // RecursiveCriticalSections everywhere. RecursiveCriticalSection is 51 // reentrant lock. 52 class RTC_LOCKABLE RecursiveCriticalSection { 53 public: 54 RecursiveCriticalSection(); 55 ~RecursiveCriticalSection(); 56 57 void Enter() const RTC_EXCLUSIVE_LOCK_FUNCTION(); 58 bool TryEnter() const RTC_EXCLUSIVE_TRYLOCK_FUNCTION(true); 59 void Leave() const RTC_UNLOCK_FUNCTION(); 60 61 private: 62 // Use only for RTC_DCHECKing. 63 bool CurrentThreadIsOwner() const; 64 65 #if defined(WEBRTC_WIN) 66 mutable CRITICAL_SECTION crit_; 67 #elif defined(WEBRTC_POSIX) 68 #if defined(WEBRTC_MAC) && !RTC_USE_NATIVE_MUTEX_ON_MAC 69 // Number of times the lock has been locked + number of threads waiting. 70 // TODO(tommi): We could use this number and subtract the recursion count 71 // to find places where we have multiple threads contending on the same lock. 72 mutable volatile int lock_queue_; 73 // |recursion_| represents the recursion count + 1 for the thread that owns 74 // the lock. Only modified by the thread that owns the lock. 75 mutable int recursion_; 76 // Used to signal a single waiting thread when the lock becomes available. 77 mutable dispatch_semaphore_t semaphore_; 78 // The thread that currently holds the lock. Required to handle recursion. 79 mutable PlatformThreadRef owning_thread_; 80 #else 81 mutable pthread_mutex_t mutex_; 82 #endif 83 mutable PlatformThreadRef thread_; // Only used by RTC_DCHECKs. 84 mutable int recursion_count_; // Only used by RTC_DCHECKs. 85 #else // !defined(WEBRTC_WIN) && !defined(WEBRTC_POSIX) 86 #error Unsupported platform. 87 #endif 88 }; 89 90 // CritScope, for serializing execution through a scope. 91 class RTC_SCOPED_LOCKABLE CritScope { 92 public: 93 explicit CritScope(const RecursiveCriticalSection* cs) 94 RTC_EXCLUSIVE_LOCK_FUNCTION(cs); 95 ~CritScope() RTC_UNLOCK_FUNCTION(); 96 97 private: 98 const RecursiveCriticalSection* const cs_; 99 RTC_DISALLOW_COPY_AND_ASSIGN(CritScope); 100 }; 101 102 } // namespace rtc 103 104 #endif // RTC_BASE_DEPRECATED_RECURSIVE_CRITICAL_SECTION_H_ 105