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