Update to current webrtc library
This is from the upstream library commit id 3326535126e435f1ba647885ce43a8f0f3d317eb, corresponding to Chromium 88.0.4290.1.
This commit is contained in:
		
							
								
								
									
										138
									
								
								webrtc/rtc_base/synchronization/BUILD.gn
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								webrtc/rtc_base/synchronization/BUILD.gn
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| # Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. | ||||
| # | ||||
| # Use of this source code is governed by a BSD-style license | ||||
| # that can be found in the LICENSE file in the root of the source | ||||
| # tree. An additional intellectual property rights grant can be found | ||||
| # in the file PATENTS.  All contributing project authors may | ||||
| # be found in the AUTHORS file in the root of the source tree. | ||||
|  | ||||
| import("../../webrtc.gni") | ||||
| if (is_android) { | ||||
|   import("//build/config/android/config.gni") | ||||
|   import("//build/config/android/rules.gni") | ||||
| } | ||||
|  | ||||
| rtc_library("yield") { | ||||
|   sources = [ | ||||
|     "yield.cc", | ||||
|     "yield.h", | ||||
|   ] | ||||
|   deps = [] | ||||
| } | ||||
|  | ||||
| rtc_library("mutex") { | ||||
|   sources = [ | ||||
|     "mutex.cc", | ||||
|     "mutex.h", | ||||
|     "mutex_critical_section.h", | ||||
|     "mutex_pthread.h", | ||||
|   ] | ||||
|   if (rtc_use_absl_mutex) { | ||||
|     sources += [ "mutex_abseil.h" ] | ||||
|   } | ||||
|  | ||||
|   deps = [ | ||||
|     ":yield", | ||||
|     "..:checks", | ||||
|     "..:macromagic", | ||||
|     "..:platform_thread_types", | ||||
|     "../system:unused", | ||||
|   ] | ||||
|   absl_deps = [ "//third_party/abseil-cpp/absl/base:core_headers" ] | ||||
|   if (rtc_use_absl_mutex) { | ||||
|     absl_deps += [ "//third_party/abseil-cpp/absl/synchronization" ] | ||||
|   } | ||||
| } | ||||
|  | ||||
| rtc_library("rw_lock_wrapper") { | ||||
|   public = [ "rw_lock_wrapper.h" ] | ||||
|   sources = [ "rw_lock_wrapper.cc" ] | ||||
|   deps = [ "..:macromagic" ] | ||||
|   if (is_win) { | ||||
|     sources += [ | ||||
|       "rw_lock_win.cc", | ||||
|       "rw_lock_win.h", | ||||
|     ] | ||||
|     deps += [ "..:logging" ] | ||||
|   } else { | ||||
|     sources += [ | ||||
|       "rw_lock_posix.cc", | ||||
|       "rw_lock_posix.h", | ||||
|     ] | ||||
|   } | ||||
| } | ||||
|  | ||||
| rtc_library("sequence_checker") { | ||||
|   sources = [ | ||||
|     "sequence_checker.cc", | ||||
|     "sequence_checker.h", | ||||
|   ] | ||||
|   deps = [ | ||||
|     ":mutex", | ||||
|     "..:checks", | ||||
|     "..:criticalsection", | ||||
|     "..:macromagic", | ||||
|     "..:platform_thread_types", | ||||
|     "..:stringutils", | ||||
|     "../../api/task_queue", | ||||
|     "../system:rtc_export", | ||||
|   ] | ||||
| } | ||||
|  | ||||
| rtc_library("yield_policy") { | ||||
|   sources = [ | ||||
|     "yield_policy.cc", | ||||
|     "yield_policy.h", | ||||
|   ] | ||||
|   deps = [ "..:checks" ] | ||||
|   absl_deps = [ | ||||
|     "//third_party/abseil-cpp/absl/base:config", | ||||
|     "//third_party/abseil-cpp/absl/base:core_headers", | ||||
|   ] | ||||
| } | ||||
|  | ||||
| if (rtc_include_tests) { | ||||
|   rtc_library("synchronization_unittests") { | ||||
|     testonly = true | ||||
|     sources = [ | ||||
|       "mutex_unittest.cc", | ||||
|       "yield_policy_unittest.cc", | ||||
|     ] | ||||
|     deps = [ | ||||
|       ":mutex", | ||||
|       ":yield", | ||||
|       ":yield_policy", | ||||
|       "..:checks", | ||||
|       "..:macromagic", | ||||
|       "..:rtc_base", | ||||
|       "..:rtc_event", | ||||
|       "../../test:test_support", | ||||
|       "//third_party/google_benchmark", | ||||
|     ] | ||||
|   } | ||||
|  | ||||
|   rtc_library("mutex_benchmark") { | ||||
|     testonly = true | ||||
|     sources = [ "mutex_benchmark.cc" ] | ||||
|     deps = [ | ||||
|       ":mutex", | ||||
|       "../system:unused", | ||||
|       "//third_party/google_benchmark", | ||||
|     ] | ||||
|   } | ||||
|  | ||||
|   rtc_library("sequence_checker_unittests") { | ||||
|     testonly = true | ||||
|  | ||||
|     sources = [ "sequence_checker_unittest.cc" ] | ||||
|     deps = [ | ||||
|       ":sequence_checker", | ||||
|       "..:checks", | ||||
|       "..:rtc_base_approved", | ||||
|       "..:task_queue_for_test", | ||||
|       "../../api:function_view", | ||||
|       "../../test:test_main", | ||||
|       "../../test:test_support", | ||||
|     ] | ||||
|   } | ||||
| } | ||||
							
								
								
									
										39
									
								
								webrtc/rtc_base/synchronization/mutex.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								webrtc/rtc_base/synchronization/mutex.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| /* | ||||
|  *  Copyright 2020 The WebRTC Project Authors. All rights reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
| #include "rtc_base/synchronization/mutex.h" | ||||
|  | ||||
| #include "rtc_base/checks.h" | ||||
| #include "rtc_base/synchronization/yield.h" | ||||
|  | ||||
| namespace webrtc { | ||||
|  | ||||
| #if !defined(WEBRTC_ABSL_MUTEX) | ||||
| void GlobalMutex::Lock() { | ||||
|   while (mutex_locked_.exchange(1)) { | ||||
|     YieldCurrentThread(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void GlobalMutex::Unlock() { | ||||
|   int old = mutex_locked_.exchange(0); | ||||
|   RTC_DCHECK_EQ(old, 1) << "Unlock called without calling Lock first"; | ||||
| } | ||||
|  | ||||
| GlobalMutexLock::GlobalMutexLock(GlobalMutex* mutex) : mutex_(mutex) { | ||||
|   mutex_->Lock(); | ||||
| } | ||||
|  | ||||
| GlobalMutexLock::~GlobalMutexLock() { | ||||
|   mutex_->Unlock(); | ||||
| } | ||||
| #endif  // #if !defined(WEBRTC_ABSL_MUTEX) | ||||
|  | ||||
| }  // namespace webrtc | ||||
							
								
								
									
										108
									
								
								webrtc/rtc_base/synchronization/mutex.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								webrtc/rtc_base/synchronization/mutex.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| /* | ||||
|  *  Copyright 2020 The WebRTC Project Authors. All rights reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
| #ifndef RTC_BASE_SYNCHRONIZATION_MUTEX_H_ | ||||
| #define RTC_BASE_SYNCHRONIZATION_MUTEX_H_ | ||||
|  | ||||
| #include <atomic> | ||||
|  | ||||
| #include "absl/base/const_init.h" | ||||
| #include "rtc_base/checks.h" | ||||
| #include "rtc_base/system/unused.h" | ||||
| #include "rtc_base/thread_annotations.h" | ||||
|  | ||||
| #if defined(WEBRTC_ABSL_MUTEX) | ||||
| #include "rtc_base/synchronization/mutex_abseil.h"  // nogncheck | ||||
| #elif defined(WEBRTC_WIN) | ||||
| #include "rtc_base/synchronization/mutex_critical_section.h" | ||||
| #elif defined(WEBRTC_POSIX) | ||||
| #include "rtc_base/synchronization/mutex_pthread.h" | ||||
| #else | ||||
| #error Unsupported platform. | ||||
| #endif | ||||
|  | ||||
| namespace webrtc { | ||||
|  | ||||
| // The Mutex guarantees exclusive access and aims to follow Abseil semantics | ||||
| // (i.e. non-reentrant etc). | ||||
| class RTC_LOCKABLE Mutex final { | ||||
|  public: | ||||
|   Mutex() = default; | ||||
|   Mutex(const Mutex&) = delete; | ||||
|   Mutex& operator=(const Mutex&) = delete; | ||||
|  | ||||
|   void Lock() RTC_EXCLUSIVE_LOCK_FUNCTION() { | ||||
|     impl_.Lock(); | ||||
|   } | ||||
|   RTC_WARN_UNUSED_RESULT bool TryLock() RTC_EXCLUSIVE_TRYLOCK_FUNCTION(true) { | ||||
|     return impl_.TryLock(); | ||||
|   } | ||||
|   void Unlock() RTC_UNLOCK_FUNCTION() { | ||||
|     impl_.Unlock(); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   MutexImpl impl_; | ||||
| }; | ||||
|  | ||||
| // MutexLock, for serializing execution through a scope. | ||||
| class RTC_SCOPED_LOCKABLE MutexLock final { | ||||
|  public: | ||||
|   MutexLock(const MutexLock&) = delete; | ||||
|   MutexLock& operator=(const MutexLock&) = delete; | ||||
|  | ||||
|   explicit MutexLock(Mutex* mutex) RTC_EXCLUSIVE_LOCK_FUNCTION(mutex) | ||||
|       : mutex_(mutex) { | ||||
|     mutex->Lock(); | ||||
|   } | ||||
|   ~MutexLock() RTC_UNLOCK_FUNCTION() { mutex_->Unlock(); } | ||||
|  | ||||
|  private: | ||||
|   Mutex* mutex_; | ||||
| }; | ||||
|  | ||||
| // A mutex used to protect global variables. Do NOT use for other purposes. | ||||
| #if defined(WEBRTC_ABSL_MUTEX) | ||||
| using GlobalMutex = absl::Mutex; | ||||
| using GlobalMutexLock = absl::MutexLock; | ||||
| #else | ||||
| class RTC_LOCKABLE GlobalMutex final { | ||||
|  public: | ||||
|   GlobalMutex(const GlobalMutex&) = delete; | ||||
|   GlobalMutex& operator=(const GlobalMutex&) = delete; | ||||
|  | ||||
|   constexpr explicit GlobalMutex(absl::ConstInitType /*unused*/) | ||||
|       : mutex_locked_(0) {} | ||||
|  | ||||
|   void Lock() RTC_EXCLUSIVE_LOCK_FUNCTION(); | ||||
|   void Unlock() RTC_UNLOCK_FUNCTION(); | ||||
|  | ||||
|  private: | ||||
|   std::atomic<int> mutex_locked_;  // 0 means lock not taken, 1 means taken. | ||||
| }; | ||||
|  | ||||
| // GlobalMutexLock, for serializing execution through a scope. | ||||
| class RTC_SCOPED_LOCKABLE GlobalMutexLock final { | ||||
|  public: | ||||
|   GlobalMutexLock(const GlobalMutexLock&) = delete; | ||||
|   GlobalMutexLock& operator=(const GlobalMutexLock&) = delete; | ||||
|  | ||||
|   explicit GlobalMutexLock(GlobalMutex* mutex) | ||||
|       RTC_EXCLUSIVE_LOCK_FUNCTION(mutex_); | ||||
|   ~GlobalMutexLock() RTC_UNLOCK_FUNCTION(); | ||||
|  | ||||
|  private: | ||||
|   GlobalMutex* mutex_; | ||||
| }; | ||||
| #endif  // if defined(WEBRTC_ABSL_MUTEX) | ||||
|  | ||||
| }  // namespace webrtc | ||||
|  | ||||
| #endif  // RTC_BASE_SYNCHRONIZATION_MUTEX_H_ | ||||
							
								
								
									
										54
									
								
								webrtc/rtc_base/synchronization/mutex_critical_section.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								webrtc/rtc_base/synchronization/mutex_critical_section.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| /* | ||||
|  *  Copyright 2020 The WebRTC Project Authors. All rights reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
| #ifndef RTC_BASE_SYNCHRONIZATION_MUTEX_CRITICAL_SECTION_H_ | ||||
| #define RTC_BASE_SYNCHRONIZATION_MUTEX_CRITICAL_SECTION_H_ | ||||
|  | ||||
| #if defined(WEBRTC_WIN) | ||||
| // clang-format off | ||||
| // clang formating would change include order. | ||||
|  | ||||
| // Include winsock2.h before including <windows.h> to maintain consistency with | ||||
| // win32.h. To include win32.h directly, it must be broken out into its own | ||||
| // build target. | ||||
| #include <winsock2.h> | ||||
| #include <windows.h> | ||||
| #include <sal.h>  // must come after windows headers. | ||||
| // clang-format on | ||||
|  | ||||
| #include "rtc_base/thread_annotations.h" | ||||
|  | ||||
| namespace webrtc { | ||||
|  | ||||
| class RTC_LOCKABLE MutexImpl final { | ||||
|  public: | ||||
|   MutexImpl() { InitializeCriticalSection(&critical_section_); } | ||||
|   MutexImpl(const MutexImpl&) = delete; | ||||
|   MutexImpl& operator=(const MutexImpl&) = delete; | ||||
|   ~MutexImpl() { DeleteCriticalSection(&critical_section_); } | ||||
|  | ||||
|   void Lock() RTC_EXCLUSIVE_LOCK_FUNCTION() { | ||||
|     EnterCriticalSection(&critical_section_); | ||||
|   } | ||||
|   RTC_WARN_UNUSED_RESULT bool TryLock() RTC_EXCLUSIVE_TRYLOCK_FUNCTION(true) { | ||||
|     return TryEnterCriticalSection(&critical_section_) != FALSE; | ||||
|   } | ||||
|   void Unlock() RTC_UNLOCK_FUNCTION() { | ||||
|     LeaveCriticalSection(&critical_section_); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   CRITICAL_SECTION critical_section_; | ||||
| }; | ||||
|  | ||||
| }  // namespace webrtc | ||||
|  | ||||
| #endif  // #if defined(WEBRTC_WIN) | ||||
| #endif  // RTC_BASE_SYNCHRONIZATION_MUTEX_CRITICAL_SECTION_H_ | ||||
							
								
								
									
										53
									
								
								webrtc/rtc_base/synchronization/mutex_pthread.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								webrtc/rtc_base/synchronization/mutex_pthread.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| /* | ||||
|  *  Copyright 2020 The WebRTC Project Authors. All rights reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
| #ifndef RTC_BASE_SYNCHRONIZATION_MUTEX_PTHREAD_H_ | ||||
| #define RTC_BASE_SYNCHRONIZATION_MUTEX_PTHREAD_H_ | ||||
|  | ||||
| #if defined(WEBRTC_POSIX) | ||||
|  | ||||
| #include <pthread.h> | ||||
| #if defined(WEBRTC_MAC) | ||||
| #include <pthread_spis.h> | ||||
| #endif | ||||
|  | ||||
| #include "rtc_base/thread_annotations.h" | ||||
|  | ||||
| namespace webrtc { | ||||
|  | ||||
| class RTC_LOCKABLE MutexImpl final { | ||||
|  public: | ||||
|   MutexImpl() { | ||||
|     pthread_mutexattr_t mutex_attribute; | ||||
|     pthread_mutexattr_init(&mutex_attribute); | ||||
| #if defined(WEBRTC_MAC) | ||||
|     pthread_mutexattr_setpolicy_np(&mutex_attribute, | ||||
|                                    _PTHREAD_MUTEX_POLICY_FIRSTFIT); | ||||
| #endif | ||||
|     pthread_mutex_init(&mutex_, &mutex_attribute); | ||||
|     pthread_mutexattr_destroy(&mutex_attribute); | ||||
|   } | ||||
|   MutexImpl(const MutexImpl&) = delete; | ||||
|   MutexImpl& operator=(const MutexImpl&) = delete; | ||||
|   ~MutexImpl() { pthread_mutex_destroy(&mutex_); } | ||||
|  | ||||
|   void Lock() RTC_EXCLUSIVE_LOCK_FUNCTION() { pthread_mutex_lock(&mutex_); } | ||||
|   RTC_WARN_UNUSED_RESULT bool TryLock() RTC_EXCLUSIVE_TRYLOCK_FUNCTION(true) { | ||||
|     return pthread_mutex_trylock(&mutex_) == 0; | ||||
|   } | ||||
|   void Unlock() RTC_UNLOCK_FUNCTION() { pthread_mutex_unlock(&mutex_); } | ||||
|  | ||||
|  private: | ||||
|   pthread_mutex_t mutex_; | ||||
| }; | ||||
|  | ||||
| }  // namespace webrtc | ||||
| #endif  // #if defined(WEBRTC_POSIX) | ||||
| #endif  // RTC_BASE_SYNCHRONIZATION_MUTEX_PTHREAD_H_ | ||||
							
								
								
									
										52
									
								
								webrtc/rtc_base/synchronization/rw_lock_posix.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								webrtc/rtc_base/synchronization/rw_lock_posix.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| /* | ||||
|  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
| #include "rtc_base/synchronization/rw_lock_posix.h" | ||||
|  | ||||
| #include <stddef.h> | ||||
|  | ||||
| namespace webrtc { | ||||
|  | ||||
| RWLockPosix::RWLockPosix() : lock_() {} | ||||
|  | ||||
| RWLockPosix::~RWLockPosix() { | ||||
|   pthread_rwlock_destroy(&lock_); | ||||
| } | ||||
|  | ||||
| RWLockPosix* RWLockPosix::Create() { | ||||
|   RWLockPosix* ret_val = new RWLockPosix(); | ||||
|   if (!ret_val->Init()) { | ||||
|     delete ret_val; | ||||
|     return NULL; | ||||
|   } | ||||
|   return ret_val; | ||||
| } | ||||
|  | ||||
| bool RWLockPosix::Init() { | ||||
|   return pthread_rwlock_init(&lock_, 0) == 0; | ||||
| } | ||||
|  | ||||
| void RWLockPosix::AcquireLockExclusive() { | ||||
|   pthread_rwlock_wrlock(&lock_); | ||||
| } | ||||
|  | ||||
| void RWLockPosix::ReleaseLockExclusive() { | ||||
|   pthread_rwlock_unlock(&lock_); | ||||
| } | ||||
|  | ||||
| void RWLockPosix::AcquireLockShared() { | ||||
|   pthread_rwlock_rdlock(&lock_); | ||||
| } | ||||
|  | ||||
| void RWLockPosix::ReleaseLockShared() { | ||||
|   pthread_rwlock_unlock(&lock_); | ||||
| } | ||||
|  | ||||
| }  // namespace webrtc | ||||
							
								
								
									
										40
									
								
								webrtc/rtc_base/synchronization/rw_lock_posix.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								webrtc/rtc_base/synchronization/rw_lock_posix.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
|  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
| #ifndef RTC_BASE_SYNCHRONIZATION_RW_LOCK_POSIX_H_ | ||||
| #define RTC_BASE_SYNCHRONIZATION_RW_LOCK_POSIX_H_ | ||||
|  | ||||
| #include <pthread.h> | ||||
|  | ||||
| #include "rtc_base/synchronization/rw_lock_wrapper.h" | ||||
|  | ||||
| namespace webrtc { | ||||
|  | ||||
| class RWLockPosix : public RWLockWrapper { | ||||
|  public: | ||||
|   static RWLockPosix* Create(); | ||||
|   ~RWLockPosix() override; | ||||
|  | ||||
|   void AcquireLockExclusive() override; | ||||
|   void ReleaseLockExclusive() override; | ||||
|  | ||||
|   void AcquireLockShared() override; | ||||
|   void ReleaseLockShared() override; | ||||
|  | ||||
|  private: | ||||
|   RWLockPosix(); | ||||
|   bool Init(); | ||||
|  | ||||
|   pthread_rwlock_t lock_; | ||||
| }; | ||||
|  | ||||
| }  // namespace webrtc | ||||
|  | ||||
| #endif  // RTC_BASE_SYNCHRONIZATION_RW_LOCK_POSIX_H_ | ||||
							
								
								
									
										41
									
								
								webrtc/rtc_base/synchronization/rw_lock_win.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								webrtc/rtc_base/synchronization/rw_lock_win.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| /* | ||||
|  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
| #include "rtc_base/synchronization/rw_lock_win.h" | ||||
|  | ||||
| #include "rtc_base/logging.h" | ||||
|  | ||||
| namespace webrtc { | ||||
|  | ||||
| RWLockWin::RWLockWin() { | ||||
|   InitializeSRWLock(&lock_); | ||||
| } | ||||
|  | ||||
| RWLockWin* RWLockWin::Create() { | ||||
|   return new RWLockWin(); | ||||
| } | ||||
|  | ||||
| void RWLockWin::AcquireLockExclusive() { | ||||
|   AcquireSRWLockExclusive(&lock_); | ||||
| } | ||||
|  | ||||
| void RWLockWin::ReleaseLockExclusive() { | ||||
|   ReleaseSRWLockExclusive(&lock_); | ||||
| } | ||||
|  | ||||
| void RWLockWin::AcquireLockShared() { | ||||
|   AcquireSRWLockShared(&lock_); | ||||
| } | ||||
|  | ||||
| void RWLockWin::ReleaseLockShared() { | ||||
|   ReleaseSRWLockShared(&lock_); | ||||
| } | ||||
|  | ||||
| }  // namespace webrtc | ||||
							
								
								
									
										38
									
								
								webrtc/rtc_base/synchronization/rw_lock_win.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								webrtc/rtc_base/synchronization/rw_lock_win.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| /* | ||||
|  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
| #ifndef RTC_BASE_SYNCHRONIZATION_RW_LOCK_WIN_H_ | ||||
| #define RTC_BASE_SYNCHRONIZATION_RW_LOCK_WIN_H_ | ||||
|  | ||||
| #include <Windows.h> | ||||
|  | ||||
| #include "rtc_base/synchronization/rw_lock_wrapper.h" | ||||
|  | ||||
| namespace webrtc { | ||||
|  | ||||
| class RWLockWin : public RWLockWrapper { | ||||
|  public: | ||||
|   static RWLockWin* Create(); | ||||
|  | ||||
|   void AcquireLockExclusive() override; | ||||
|   void ReleaseLockExclusive() override; | ||||
|  | ||||
|   void AcquireLockShared() override; | ||||
|   void ReleaseLockShared() override; | ||||
|  | ||||
|  private: | ||||
|   RWLockWin(); | ||||
|  | ||||
|   SRWLOCK lock_; | ||||
| }; | ||||
|  | ||||
| }  // namespace webrtc | ||||
|  | ||||
| #endif  // RTC_BASE_SYNCHRONIZATION_RW_LOCK_WIN_H_ | ||||
							
								
								
									
										29
									
								
								webrtc/rtc_base/synchronization/rw_lock_wrapper.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								webrtc/rtc_base/synchronization/rw_lock_wrapper.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| /* | ||||
|  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
| #include "rtc_base/synchronization/rw_lock_wrapper.h" | ||||
|  | ||||
| #if defined(_WIN32) | ||||
| #include "rtc_base/synchronization/rw_lock_win.h" | ||||
| #else | ||||
| #include "rtc_base/synchronization/rw_lock_posix.h" | ||||
| #endif | ||||
|  | ||||
| namespace webrtc { | ||||
|  | ||||
| RWLockWrapper* RWLockWrapper::CreateRWLock() { | ||||
| #ifdef _WIN32 | ||||
|   return RWLockWin::Create(); | ||||
| #else | ||||
|   return RWLockPosix::Create(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| }  // namespace webrtc | ||||
							
								
								
									
										66
									
								
								webrtc/rtc_base/synchronization/rw_lock_wrapper.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								webrtc/rtc_base/synchronization/rw_lock_wrapper.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| /* | ||||
|  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
| #ifndef RTC_BASE_SYNCHRONIZATION_RW_LOCK_WRAPPER_H_ | ||||
| #define RTC_BASE_SYNCHRONIZATION_RW_LOCK_WRAPPER_H_ | ||||
|  | ||||
| #include "rtc_base/thread_annotations.h" | ||||
|  | ||||
| // Note, Windows pre-Vista version of RW locks are not supported natively. For | ||||
| // these OSs regular critical sections have been used to approximate RW lock | ||||
| // functionality and will therefore have worse performance. | ||||
|  | ||||
| namespace webrtc { | ||||
|  | ||||
| class RTC_LOCKABLE RWLockWrapper { | ||||
|  public: | ||||
|   static RWLockWrapper* CreateRWLock(); | ||||
|   virtual ~RWLockWrapper() {} | ||||
|  | ||||
|   virtual void AcquireLockExclusive() RTC_EXCLUSIVE_LOCK_FUNCTION() = 0; | ||||
|   virtual void ReleaseLockExclusive() RTC_UNLOCK_FUNCTION() = 0; | ||||
|  | ||||
|   virtual void AcquireLockShared() RTC_SHARED_LOCK_FUNCTION() = 0; | ||||
|   virtual void ReleaseLockShared() RTC_UNLOCK_FUNCTION() = 0; | ||||
| }; | ||||
|  | ||||
| // RAII extensions of the RW lock. Prevents Acquire/Release missmatches and | ||||
| // provides more compact locking syntax. | ||||
| class RTC_SCOPED_LOCKABLE ReadLockScoped { | ||||
|  public: | ||||
|   explicit ReadLockScoped(RWLockWrapper& rw_lock) | ||||
|       RTC_SHARED_LOCK_FUNCTION(rw_lock) | ||||
|       : rw_lock_(rw_lock) { | ||||
|     rw_lock_.AcquireLockShared(); | ||||
|   } | ||||
|  | ||||
|   ~ReadLockScoped() RTC_UNLOCK_FUNCTION() { rw_lock_.ReleaseLockShared(); } | ||||
|  | ||||
|  private: | ||||
|   RWLockWrapper& rw_lock_; | ||||
| }; | ||||
|  | ||||
| class RTC_SCOPED_LOCKABLE WriteLockScoped { | ||||
|  public: | ||||
|   explicit WriteLockScoped(RWLockWrapper& rw_lock) | ||||
|       RTC_EXCLUSIVE_LOCK_FUNCTION(rw_lock) | ||||
|       : rw_lock_(rw_lock) { | ||||
|     rw_lock_.AcquireLockExclusive(); | ||||
|   } | ||||
|  | ||||
|   ~WriteLockScoped() RTC_UNLOCK_FUNCTION() { rw_lock_.ReleaseLockExclusive(); } | ||||
|  | ||||
|  private: | ||||
|   RWLockWrapper& rw_lock_; | ||||
| }; | ||||
|  | ||||
| }  // namespace webrtc | ||||
|  | ||||
| #endif  // RTC_BASE_SYNCHRONIZATION_RW_LOCK_WRAPPER_H_ | ||||
							
								
								
									
										112
									
								
								webrtc/rtc_base/synchronization/sequence_checker.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								webrtc/rtc_base/synchronization/sequence_checker.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | ||||
| /* | ||||
|  *  Copyright 2019 The WebRTC project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
| #include "rtc_base/synchronization/sequence_checker.h" | ||||
|  | ||||
| #if defined(WEBRTC_MAC) | ||||
| #include <dispatch/dispatch.h> | ||||
| #endif | ||||
|  | ||||
| #include "rtc_base/strings/string_builder.h" | ||||
|  | ||||
| namespace webrtc { | ||||
| namespace { | ||||
| // On Mac, returns the label of the current dispatch queue; elsewhere, return | ||||
| // null. | ||||
| const void* GetSystemQueueRef() { | ||||
| #if defined(WEBRTC_MAC) | ||||
|   return dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL); | ||||
| #else | ||||
|   return nullptr; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| }  // namespace | ||||
|  | ||||
| std::string ExpectationToString(const webrtc::SequenceChecker* checker) { | ||||
| #if RTC_DCHECK_IS_ON | ||||
|   return checker->ExpectationToString(); | ||||
| #endif | ||||
|   return std::string(); | ||||
| } | ||||
|  | ||||
| SequenceCheckerImpl::SequenceCheckerImpl() | ||||
|     : attached_(true), | ||||
|       valid_thread_(rtc::CurrentThreadRef()), | ||||
|       valid_queue_(TaskQueueBase::Current()), | ||||
|       valid_system_queue_(GetSystemQueueRef()) {} | ||||
|  | ||||
| SequenceCheckerImpl::~SequenceCheckerImpl() = default; | ||||
|  | ||||
| bool SequenceCheckerImpl::IsCurrent() const { | ||||
|   const TaskQueueBase* const current_queue = TaskQueueBase::Current(); | ||||
|   const rtc::PlatformThreadRef current_thread = rtc::CurrentThreadRef(); | ||||
|   const void* const current_system_queue = GetSystemQueueRef(); | ||||
|   MutexLock scoped_lock(&lock_); | ||||
|   if (!attached_) {  // Previously detached. | ||||
|     attached_ = true; | ||||
|     valid_thread_ = current_thread; | ||||
|     valid_queue_ = current_queue; | ||||
|     valid_system_queue_ = current_system_queue; | ||||
|     return true; | ||||
|   } | ||||
|   if (valid_queue_ || current_queue) { | ||||
|     return valid_queue_ == current_queue; | ||||
|   } | ||||
|   if (valid_system_queue_ && valid_system_queue_ == current_system_queue) { | ||||
|     return true; | ||||
|   } | ||||
|   return rtc::IsThreadRefEqual(valid_thread_, current_thread); | ||||
| } | ||||
|  | ||||
| void SequenceCheckerImpl::Detach() { | ||||
|   MutexLock scoped_lock(&lock_); | ||||
|   attached_ = false; | ||||
|   // We don't need to touch the other members here, they will be | ||||
|   // reset on the next call to IsCurrent(). | ||||
| } | ||||
|  | ||||
| #if RTC_DCHECK_IS_ON | ||||
| std::string SequenceCheckerImpl::ExpectationToString() const { | ||||
|   const TaskQueueBase* const current_queue = TaskQueueBase::Current(); | ||||
|   const rtc::PlatformThreadRef current_thread = rtc::CurrentThreadRef(); | ||||
|   const void* const current_system_queue = GetSystemQueueRef(); | ||||
|   MutexLock scoped_lock(&lock_); | ||||
|   if (!attached_) | ||||
|     return "Checker currently not attached."; | ||||
|  | ||||
|   // The format of the string is meant to compliment the one we have inside of | ||||
|   // FatalLog() (checks.cc).  Example: | ||||
|   // | ||||
|   // # Expected: TQ: 0x0 SysQ: 0x7fff69541330 Thread: 0x11dcf6dc0 | ||||
|   // # Actual:   TQ: 0x7fa8f0604190 SysQ: 0x7fa8f0604a30 Thread: 0x700006f1a000 | ||||
|   // TaskQueue doesn't match | ||||
|  | ||||
|   rtc::StringBuilder message; | ||||
|   message.AppendFormat( | ||||
|       "# Expected: TQ: %p SysQ: %p Thread: %p\n" | ||||
|       "# Actual:   TQ: %p SysQ: %p Thread: %p\n", | ||||
|       valid_queue_, valid_system_queue_, | ||||
|       reinterpret_cast<const void*>(valid_thread_), current_queue, | ||||
|       current_system_queue, reinterpret_cast<const void*>(current_thread)); | ||||
|  | ||||
|   if ((valid_queue_ || current_queue) && valid_queue_ != current_queue) { | ||||
|     message << "TaskQueue doesn't match\n"; | ||||
|   } else if (valid_system_queue_ && | ||||
|              valid_system_queue_ != current_system_queue) { | ||||
|     message << "System queue doesn't match\n"; | ||||
|   } else if (!rtc::IsThreadRefEqual(valid_thread_, current_thread)) { | ||||
|     message << "Threads don't match\n"; | ||||
|   } | ||||
|  | ||||
|   return message.Release(); | ||||
| } | ||||
| #endif  // RTC_DCHECK_IS_ON | ||||
|  | ||||
| }  // namespace webrtc | ||||
							
								
								
									
										187
									
								
								webrtc/rtc_base/synchronization/sequence_checker.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								webrtc/rtc_base/synchronization/sequence_checker.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,187 @@ | ||||
| /* | ||||
|  *  Copyright 2019 The WebRTC project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
| #ifndef RTC_BASE_SYNCHRONIZATION_SEQUENCE_CHECKER_H_ | ||||
| #define RTC_BASE_SYNCHRONIZATION_SEQUENCE_CHECKER_H_ | ||||
|  | ||||
| #include <type_traits> | ||||
|  | ||||
| #include "api/task_queue/task_queue_base.h" | ||||
| #include "rtc_base/platform_thread_types.h" | ||||
| #include "rtc_base/synchronization/mutex.h" | ||||
| #include "rtc_base/system/rtc_export.h" | ||||
| #include "rtc_base/thread_annotations.h" | ||||
|  | ||||
| namespace webrtc { | ||||
| // Real implementation of SequenceChecker, for use in debug mode, or | ||||
| // for temporary use in release mode (e.g. to RTC_CHECK on a threading issue | ||||
| // seen only in the wild). | ||||
| // | ||||
| // Note: You should almost always use the SequenceChecker class to get the | ||||
| // right version for your build configuration. | ||||
| class RTC_EXPORT SequenceCheckerImpl { | ||||
|  public: | ||||
|   SequenceCheckerImpl(); | ||||
|   ~SequenceCheckerImpl(); | ||||
|  | ||||
|   bool IsCurrent() const; | ||||
|   // Changes the task queue or thread that is checked for in IsCurrent. This can | ||||
|   // be useful when an object may be created on one task queue / thread and then | ||||
|   // used exclusively on another thread. | ||||
|   void Detach(); | ||||
|  | ||||
|   // Returns a string that is formatted to match with the error string printed | ||||
|   // by RTC_CHECK() when a condition is not met. | ||||
|   // This is used in conjunction with the RTC_DCHECK_RUN_ON() macro. | ||||
|   std::string ExpectationToString() const; | ||||
|  | ||||
|  private: | ||||
|   mutable Mutex lock_; | ||||
|   // These are mutable so that IsCurrent can set them. | ||||
|   mutable bool attached_ RTC_GUARDED_BY(lock_); | ||||
|   mutable rtc::PlatformThreadRef valid_thread_ RTC_GUARDED_BY(lock_); | ||||
|   mutable const TaskQueueBase* valid_queue_ RTC_GUARDED_BY(lock_); | ||||
|   mutable const void* valid_system_queue_ RTC_GUARDED_BY(lock_); | ||||
| }; | ||||
|  | ||||
| // Do nothing implementation, for use in release mode. | ||||
| // | ||||
| // Note: You should almost always use the SequenceChecker class to get the | ||||
| // right version for your build configuration. | ||||
| class SequenceCheckerDoNothing { | ||||
|  public: | ||||
|   bool IsCurrent() const { return true; } | ||||
|   void Detach() {} | ||||
| }; | ||||
|  | ||||
| // SequenceChecker is a helper class used to help verify that some methods | ||||
| // of a class are called on the same task queue or thread. A | ||||
| // SequenceChecker is bound to a a task queue if the object is | ||||
| // created on a task queue, or a thread otherwise. | ||||
| // | ||||
| // | ||||
| // Example: | ||||
| // class MyClass { | ||||
| //  public: | ||||
| //   void Foo() { | ||||
| //     RTC_DCHECK_RUN_ON(sequence_checker_); | ||||
| //     ... (do stuff) ... | ||||
| //   } | ||||
| // | ||||
| //  private: | ||||
| //   SequenceChecker sequence_checker_; | ||||
| // } | ||||
| // | ||||
| // In Release mode, IsCurrent will always return true. | ||||
| #if RTC_DCHECK_IS_ON | ||||
| class RTC_LOCKABLE SequenceChecker : public SequenceCheckerImpl {}; | ||||
| #else | ||||
| class RTC_LOCKABLE SequenceChecker : public SequenceCheckerDoNothing {}; | ||||
| #endif  // RTC_ENABLE_THREAD_CHECKER | ||||
|  | ||||
| namespace webrtc_seq_check_impl { | ||||
| // Helper class used by RTC_DCHECK_RUN_ON (see example usage below). | ||||
| class RTC_SCOPED_LOCKABLE SequenceCheckerScope { | ||||
|  public: | ||||
|   template <typename ThreadLikeObject> | ||||
|   explicit SequenceCheckerScope(const ThreadLikeObject* thread_like_object) | ||||
|       RTC_EXCLUSIVE_LOCK_FUNCTION(thread_like_object) {} | ||||
|   SequenceCheckerScope(const SequenceCheckerScope&) = delete; | ||||
|   SequenceCheckerScope& operator=(const SequenceCheckerScope&) = delete; | ||||
|   ~SequenceCheckerScope() RTC_UNLOCK_FUNCTION() {} | ||||
|  | ||||
|   template <typename ThreadLikeObject> | ||||
|   static bool IsCurrent(const ThreadLikeObject* thread_like_object) { | ||||
|     return thread_like_object->IsCurrent(); | ||||
|   } | ||||
| }; | ||||
| }  // namespace webrtc_seq_check_impl | ||||
| }  // namespace webrtc | ||||
|  | ||||
| // RTC_RUN_ON/RTC_GUARDED_BY/RTC_DCHECK_RUN_ON macros allows to annotate | ||||
| // variables are accessed from same thread/task queue. | ||||
| // Using tools designed to check mutexes, it checks at compile time everywhere | ||||
| // variable is access, there is a run-time dcheck thread/task queue is correct. | ||||
| // | ||||
| // class ThreadExample { | ||||
| //  public: | ||||
| //   void NeedVar1() { | ||||
| //     RTC_DCHECK_RUN_ON(network_thread_); | ||||
| //     transport_->Send(); | ||||
| //   } | ||||
| // | ||||
| //  private: | ||||
| //   rtc::Thread* network_thread_; | ||||
| //   int transport_ RTC_GUARDED_BY(network_thread_); | ||||
| // }; | ||||
| // | ||||
| // class SequenceCheckerExample { | ||||
| //  public: | ||||
| //   int CalledFromPacer() RTC_RUN_ON(pacer_sequence_checker_) { | ||||
| //     return var2_; | ||||
| //   } | ||||
| // | ||||
| //   void CallMeFromPacer() { | ||||
| //     RTC_DCHECK_RUN_ON(&pacer_sequence_checker_) | ||||
| //        << "Should be called from pacer"; | ||||
| //     CalledFromPacer(); | ||||
| //   } | ||||
| // | ||||
| //  private: | ||||
| //   int pacer_var_ RTC_GUARDED_BY(pacer_sequence_checker_); | ||||
| //   SequenceChecker pacer_sequence_checker_; | ||||
| // }; | ||||
| // | ||||
| // class TaskQueueExample { | ||||
| //  public: | ||||
| //   class Encoder { | ||||
| //    public: | ||||
| //     rtc::TaskQueue* Queue() { return encoder_queue_; } | ||||
| //     void Encode() { | ||||
| //       RTC_DCHECK_RUN_ON(encoder_queue_); | ||||
| //       DoSomething(var_); | ||||
| //     } | ||||
| // | ||||
| //    private: | ||||
| //     rtc::TaskQueue* const encoder_queue_; | ||||
| //     Frame var_ RTC_GUARDED_BY(encoder_queue_); | ||||
| //   }; | ||||
| // | ||||
| //   void Encode() { | ||||
| //     // Will fail at runtime when DCHECK is enabled: | ||||
| //     // encoder_->Encode(); | ||||
| //     // Will work: | ||||
| //     rtc::scoped_refptr<Encoder> encoder = encoder_; | ||||
| //     encoder_->Queue()->PostTask([encoder] { encoder->Encode(); }); | ||||
| //   } | ||||
| // | ||||
| //  private: | ||||
| //   rtc::scoped_refptr<Encoder> encoder_; | ||||
| // } | ||||
|  | ||||
| // Document if a function expected to be called from same thread/task queue. | ||||
| #define RTC_RUN_ON(x) \ | ||||
|   RTC_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(x)) | ||||
|  | ||||
| namespace webrtc { | ||||
| std::string ExpectationToString(const webrtc::SequenceChecker* checker); | ||||
|  | ||||
| // Catch-all implementation for types other than explicitly supported above. | ||||
| template <typename ThreadLikeObject> | ||||
| std::string ExpectationToString(const ThreadLikeObject*) { | ||||
|   return std::string(); | ||||
| } | ||||
|  | ||||
| }  // namespace webrtc | ||||
|  | ||||
| #define RTC_DCHECK_RUN_ON(x)                                              \ | ||||
|   webrtc::webrtc_seq_check_impl::SequenceCheckerScope seq_check_scope(x); \ | ||||
|   RTC_DCHECK((x)->IsCurrent()) << webrtc::ExpectationToString(x) | ||||
|  | ||||
| #endif  // RTC_BASE_SYNCHRONIZATION_SEQUENCE_CHECKER_H_ | ||||
							
								
								
									
										36
									
								
								webrtc/rtc_base/synchronization/yield.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								webrtc/rtc_base/synchronization/yield.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| /* | ||||
|  *  Copyright 2020 The WebRTC Project Authors. All rights reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
| #include "rtc_base/synchronization/yield.h" | ||||
|  | ||||
| #if defined(WEBRTC_WIN) | ||||
| #include <windows.h> | ||||
| #else | ||||
| #include <sched.h> | ||||
| #include <time.h> | ||||
| #endif | ||||
|  | ||||
| namespace webrtc { | ||||
|  | ||||
| void YieldCurrentThread() { | ||||
|   // TODO(bugs.webrtc.org/11634): use dedicated OS functionality instead of | ||||
|   // sleep for yielding. | ||||
| #if defined(WEBRTC_WIN) | ||||
|   ::Sleep(0); | ||||
| #elif defined(WEBRTC_MAC) && defined(RTC_USE_NATIVE_MUTEX_ON_MAC) && \ | ||||
|     !RTC_USE_NATIVE_MUTEX_ON_MAC | ||||
|   sched_yield(); | ||||
| #else | ||||
|   static const struct timespec ts_null = {0}; | ||||
|   nanosleep(&ts_null, nullptr); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| }  // namespace webrtc | ||||
							
								
								
									
										20
									
								
								webrtc/rtc_base/synchronization/yield.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								webrtc/rtc_base/synchronization/yield.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| /* | ||||
|  *  Copyright 2020 The WebRTC project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
| #ifndef RTC_BASE_SYNCHRONIZATION_YIELD_H_ | ||||
| #define RTC_BASE_SYNCHRONIZATION_YIELD_H_ | ||||
|  | ||||
| namespace webrtc { | ||||
|  | ||||
| // Request rescheduling of threads. | ||||
| void YieldCurrentThread(); | ||||
|  | ||||
| }  // namespace webrtc | ||||
|  | ||||
| #endif  // RTC_BASE_SYNCHRONIZATION_YIELD_H_ | ||||
							
								
								
									
										82
									
								
								webrtc/rtc_base/synchronization/yield_policy.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								webrtc/rtc_base/synchronization/yield_policy.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| /* | ||||
|  *  Copyright 2019 The WebRTC project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
| #include "rtc_base/synchronization/yield_policy.h" | ||||
|  | ||||
| #include "absl/base/attributes.h" | ||||
| #include "absl/base/config.h" | ||||
| #include "rtc_base/checks.h" | ||||
| #if !defined(ABSL_HAVE_THREAD_LOCAL) && defined(WEBRTC_POSIX) | ||||
| #include <pthread.h> | ||||
| #endif | ||||
|  | ||||
| namespace rtc { | ||||
| namespace { | ||||
|  | ||||
| #if defined(ABSL_HAVE_THREAD_LOCAL) | ||||
|  | ||||
| ABSL_CONST_INIT thread_local YieldInterface* current_yield_policy = nullptr; | ||||
|  | ||||
| YieldInterface* GetCurrentYieldPolicy() { | ||||
|   return current_yield_policy; | ||||
| } | ||||
|  | ||||
| void SetCurrentYieldPolicy(YieldInterface* ptr) { | ||||
|   current_yield_policy = ptr; | ||||
| } | ||||
|  | ||||
| #elif defined(WEBRTC_POSIX) | ||||
|  | ||||
| // Emscripten does not support the C++11 thread_local keyword but does support | ||||
| // the pthread thread-local storage API. | ||||
| // https://github.com/emscripten-core/emscripten/issues/3502 | ||||
|  | ||||
| ABSL_CONST_INIT pthread_key_t g_current_yield_policy_tls = 0; | ||||
|  | ||||
| void InitializeTls() { | ||||
|   RTC_CHECK_EQ(pthread_key_create(&g_current_yield_policy_tls, nullptr), 0); | ||||
| } | ||||
|  | ||||
| pthread_key_t GetCurrentYieldPolicyTls() { | ||||
|   static pthread_once_t init_once = PTHREAD_ONCE_INIT; | ||||
|   RTC_CHECK_EQ(pthread_once(&init_once, &InitializeTls), 0); | ||||
|   return g_current_yield_policy_tls; | ||||
| } | ||||
|  | ||||
| YieldInterface* GetCurrentYieldPolicy() { | ||||
|   return static_cast<YieldInterface*>( | ||||
|       pthread_getspecific(GetCurrentYieldPolicyTls())); | ||||
| } | ||||
|  | ||||
| void SetCurrentYieldPolicy(YieldInterface* ptr) { | ||||
|   pthread_setspecific(GetCurrentYieldPolicyTls(), ptr); | ||||
| } | ||||
|  | ||||
| #else | ||||
| #error Unsupported platform | ||||
| #endif | ||||
|  | ||||
| }  // namespace | ||||
|  | ||||
| ScopedYieldPolicy::ScopedYieldPolicy(YieldInterface* policy) | ||||
|     : previous_(GetCurrentYieldPolicy()) { | ||||
|   SetCurrentYieldPolicy(policy); | ||||
| } | ||||
|  | ||||
| ScopedYieldPolicy::~ScopedYieldPolicy() { | ||||
|   SetCurrentYieldPolicy(previous_); | ||||
| } | ||||
|  | ||||
| void ScopedYieldPolicy::YieldExecution() { | ||||
|   YieldInterface* current = GetCurrentYieldPolicy(); | ||||
|   if (current) | ||||
|     current->YieldExecution(); | ||||
| } | ||||
|  | ||||
| }  // namespace rtc | ||||
							
								
								
									
										38
									
								
								webrtc/rtc_base/synchronization/yield_policy.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								webrtc/rtc_base/synchronization/yield_policy.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| /* | ||||
|  *  Copyright 2019 The WebRTC project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
| #ifndef RTC_BASE_SYNCHRONIZATION_YIELD_POLICY_H_ | ||||
| #define RTC_BASE_SYNCHRONIZATION_YIELD_POLICY_H_ | ||||
|  | ||||
| namespace rtc { | ||||
| class YieldInterface { | ||||
|  public: | ||||
|   virtual ~YieldInterface() = default; | ||||
|   virtual void YieldExecution() = 0; | ||||
| }; | ||||
|  | ||||
| // Sets the current thread-local yield policy while it's in scope and reverts | ||||
| // to the previous policy when it leaves the scope. | ||||
| class ScopedYieldPolicy final { | ||||
|  public: | ||||
|   explicit ScopedYieldPolicy(YieldInterface* policy); | ||||
|   ScopedYieldPolicy(const ScopedYieldPolicy&) = delete; | ||||
|   ScopedYieldPolicy& operator=(const ScopedYieldPolicy&) = delete; | ||||
|   ~ScopedYieldPolicy(); | ||||
|   // Will yield as specified by the currently active thread-local yield policy | ||||
|   // (which by default is a no-op). | ||||
|   static void YieldExecution(); | ||||
|  | ||||
|  private: | ||||
|   YieldInterface* const previous_; | ||||
| }; | ||||
|  | ||||
| }  // namespace rtc | ||||
|  | ||||
| #endif  // RTC_BASE_SYNCHRONIZATION_YIELD_POLICY_H_ | ||||
		Reference in New Issue
	
	Block a user