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