Bump to WebRTC M120 release
Some API deprecation -- ExperimentalAgc and ExperimentalNs are gone. We're continuing to carry iSAC even though it's gone upstream, but maybe we'll want to drop that soon.
This commit is contained in:
@ -20,9 +20,8 @@ rtc_library("yield") {
|
||||
deps = []
|
||||
}
|
||||
|
||||
rtc_library("mutex") {
|
||||
rtc_source_set("mutex") {
|
||||
sources = [
|
||||
"mutex.cc",
|
||||
"mutex.h",
|
||||
"mutex_critical_section.h",
|
||||
"mutex_pthread.h",
|
||||
@ -36,7 +35,7 @@ rtc_library("mutex") {
|
||||
"..:checks",
|
||||
"..:macromagic",
|
||||
"..:platform_thread_types",
|
||||
"../system:unused",
|
||||
"../system:no_unique_address",
|
||||
]
|
||||
absl_deps = [ "//third_party/abseil-cpp/absl/base:core_headers" ]
|
||||
if (rtc_use_absl_mutex) {
|
||||
@ -44,33 +43,15 @@ rtc_library("mutex") {
|
||||
}
|
||||
}
|
||||
|
||||
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") {
|
||||
rtc_library("sequence_checker_internal") {
|
||||
visibility = [ "../../api:sequence_checker" ]
|
||||
sources = [
|
||||
"sequence_checker.cc",
|
||||
"sequence_checker.h",
|
||||
"sequence_checker_internal.cc",
|
||||
"sequence_checker_internal.h",
|
||||
]
|
||||
deps = [
|
||||
":mutex",
|
||||
"..:checks",
|
||||
"..:criticalsection",
|
||||
"..:macromagic",
|
||||
"..:platform_thread_types",
|
||||
"..:stringutils",
|
||||
@ -91,7 +72,7 @@ rtc_library("yield_policy") {
|
||||
]
|
||||
}
|
||||
|
||||
if (rtc_include_tests) {
|
||||
if (rtc_include_tests && rtc_enable_google_benchmarks) {
|
||||
rtc_library("synchronization_unittests") {
|
||||
testonly = true
|
||||
sources = [
|
||||
@ -104,8 +85,9 @@ if (rtc_include_tests) {
|
||||
":yield_policy",
|
||||
"..:checks",
|
||||
"..:macromagic",
|
||||
"..:rtc_base",
|
||||
"..:platform_thread",
|
||||
"..:rtc_event",
|
||||
"..:threading",
|
||||
"../../test:test_support",
|
||||
"//third_party/google_benchmark",
|
||||
]
|
||||
@ -120,19 +102,4 @@ if (rtc_include_tests) {
|
||||
"//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",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* 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
|
@ -13,9 +13,9 @@
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#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)
|
||||
@ -38,15 +38,15 @@ class RTC_LOCKABLE Mutex final {
|
||||
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) {
|
||||
void Lock() RTC_EXCLUSIVE_LOCK_FUNCTION() { impl_.Lock(); }
|
||||
ABSL_MUST_USE_RESULT bool TryLock() RTC_EXCLUSIVE_TRYLOCK_FUNCTION(true) {
|
||||
return impl_.TryLock();
|
||||
}
|
||||
void Unlock() RTC_UNLOCK_FUNCTION() {
|
||||
impl_.Unlock();
|
||||
}
|
||||
// Return immediately if this thread holds the mutex, or RTC_DCHECK_IS_ON==0.
|
||||
// Otherwise, may report an error (typically by crashing with a diagnostic),
|
||||
// or may return immediately.
|
||||
void AssertHeld() const RTC_ASSERT_EXCLUSIVE_LOCK() { impl_.AssertHeld(); }
|
||||
void Unlock() RTC_UNLOCK_FUNCTION() { impl_.Unlock(); }
|
||||
|
||||
private:
|
||||
MutexImpl impl_;
|
||||
@ -68,41 +68,6 @@ class RTC_SCOPED_LOCKABLE MutexLock final {
|
||||
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_
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <sal.h> // must come after windows headers.
|
||||
// clang-format on
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "rtc_base/thread_annotations.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -37,9 +38,10 @@ class RTC_LOCKABLE MutexImpl final {
|
||||
void Lock() RTC_EXCLUSIVE_LOCK_FUNCTION() {
|
||||
EnterCriticalSection(&critical_section_);
|
||||
}
|
||||
RTC_WARN_UNUSED_RESULT bool TryLock() RTC_EXCLUSIVE_TRYLOCK_FUNCTION(true) {
|
||||
ABSL_MUST_USE_RESULT bool TryLock() RTC_EXCLUSIVE_TRYLOCK_FUNCTION(true) {
|
||||
return TryEnterCriticalSection(&critical_section_) != FALSE;
|
||||
}
|
||||
void AssertHeld() const RTC_ASSERT_EXCLUSIVE_LOCK() {}
|
||||
void Unlock() RTC_UNLOCK_FUNCTION() {
|
||||
LeaveCriticalSection(&critical_section_);
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include <pthread_spis.h>
|
||||
#endif
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "rtc_base/system/no_unique_address.h"
|
||||
#include "rtc_base/thread_annotations.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -38,14 +40,60 @@ class RTC_LOCKABLE MutexImpl final {
|
||||
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 Lock() RTC_EXCLUSIVE_LOCK_FUNCTION() {
|
||||
pthread_mutex_lock(&mutex_);
|
||||
owner_.SetOwner();
|
||||
}
|
||||
ABSL_MUST_USE_RESULT bool TryLock() RTC_EXCLUSIVE_TRYLOCK_FUNCTION(true) {
|
||||
if (pthread_mutex_trylock(&mutex_) != 0) {
|
||||
return false;
|
||||
}
|
||||
owner_.SetOwner();
|
||||
return true;
|
||||
}
|
||||
void AssertHeld() const RTC_ASSERT_EXCLUSIVE_LOCK() { owner_.AssertOwned(); }
|
||||
void Unlock() RTC_UNLOCK_FUNCTION() {
|
||||
owner_.ClearOwner();
|
||||
pthread_mutex_unlock(&mutex_);
|
||||
}
|
||||
void Unlock() RTC_UNLOCK_FUNCTION() { pthread_mutex_unlock(&mutex_); }
|
||||
|
||||
private:
|
||||
class OwnerRecord {
|
||||
public:
|
||||
#if !RTC_DCHECK_IS_ON
|
||||
void SetOwner() {}
|
||||
void ClearOwner() {}
|
||||
void AssertOwned() const {}
|
||||
#else
|
||||
void SetOwner() {
|
||||
latest_owner_ = pthread_self();
|
||||
is_owned_ = true;
|
||||
}
|
||||
void ClearOwner() { is_owned_ = false; }
|
||||
void AssertOwned() const {
|
||||
RTC_CHECK(is_owned_);
|
||||
RTC_CHECK(pthread_equal(latest_owner_, pthread_self()));
|
||||
}
|
||||
|
||||
private:
|
||||
// Use two separate primitive types, rather than absl::optional, since the
|
||||
// data race described below might invalidate absl::optional invariants.
|
||||
bool is_owned_ = false;
|
||||
pthread_t latest_owner_ = pthread_self();
|
||||
#endif
|
||||
};
|
||||
|
||||
pthread_mutex_t mutex_;
|
||||
// This record is modified only with the mutex held, and hence, calls to
|
||||
// AssertHeld where mutex is held are race-free and will always succeed.
|
||||
//
|
||||
// The failure case is more subtle: If AssertHeld is called from some thread
|
||||
// not holding the mutex, and RTC_DCHECK_IS_ON==1, we have a data race. It is
|
||||
// highly likely that the calling thread will see `is_owned_` false or
|
||||
// `latest_owner_` different from itself, and crash. But it may fail to crash,
|
||||
// and invoke some other undefined behavior (still, this race can happen only
|
||||
// when RTC_DCHECK_IS_ON==1).
|
||||
RTC_NO_UNIQUE_ADDRESS OwnerRecord owner_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* 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
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* 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_
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* 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
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* 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_
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* 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_
|
@ -1,187 +0,0 @@
|
||||
/*
|
||||
* 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_
|
@ -7,61 +7,39 @@
|
||||
* 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"
|
||||
#include "rtc_base/synchronization/sequence_checker_internal.h"
|
||||
|
||||
#if defined(WEBRTC_MAC)
|
||||
#include <dispatch/dispatch.h>
|
||||
#endif
|
||||
#include <string>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
#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 webrtc_sequence_checker_internal {
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string ExpectationToString(const webrtc::SequenceChecker* checker) {
|
||||
#if RTC_DCHECK_IS_ON
|
||||
return checker->ExpectationToString();
|
||||
#endif
|
||||
return std::string();
|
||||
}
|
||||
|
||||
SequenceCheckerImpl::SequenceCheckerImpl()
|
||||
: attached_(true),
|
||||
SequenceCheckerImpl::SequenceCheckerImpl(bool attach_to_current_thread)
|
||||
: attached_(attach_to_current_thread),
|
||||
valid_thread_(rtc::CurrentThreadRef()),
|
||||
valid_queue_(TaskQueueBase::Current()),
|
||||
valid_system_queue_(GetSystemQueueRef()) {}
|
||||
valid_queue_(TaskQueueBase::Current()) {}
|
||||
|
||||
SequenceCheckerImpl::~SequenceCheckerImpl() = default;
|
||||
SequenceCheckerImpl::SequenceCheckerImpl(TaskQueueBase* attached_queue)
|
||||
: attached_(attached_queue != nullptr),
|
||||
valid_thread_(rtc::PlatformThreadRef()),
|
||||
valid_queue_(attached_queue) {}
|
||||
|
||||
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) {
|
||||
if (valid_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);
|
||||
}
|
||||
|
||||
@ -76,7 +54,6 @@ void SequenceCheckerImpl::Detach() {
|
||||
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.";
|
||||
@ -90,17 +67,13 @@ std::string SequenceCheckerImpl::ExpectationToString() const {
|
||||
|
||||
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));
|
||||
"# Expected: TQ: %p Thread: %p\n"
|
||||
"# Actual: TQ: %p Thread: %p\n",
|
||||
valid_queue_, reinterpret_cast<const void*>(valid_thread_), current_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";
|
||||
}
|
||||
@ -109,4 +82,5 @@ std::string SequenceCheckerImpl::ExpectationToString() const {
|
||||
}
|
||||
#endif // RTC_DCHECK_IS_ON
|
||||
|
||||
} // namespace webrtc_sequence_checker_internal
|
||||
} // namespace webrtc
|
90
webrtc/rtc_base/synchronization/sequence_checker_internal.h
Normal file
90
webrtc/rtc_base/synchronization/sequence_checker_internal.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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_SEQUENCE_CHECKER_INTERNAL_H_
|
||||
#define RTC_BASE_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H_
|
||||
|
||||
#include <string>
|
||||
#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 {
|
||||
namespace webrtc_sequence_checker_internal {
|
||||
|
||||
// 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:
|
||||
explicit SequenceCheckerImpl(bool attach_to_current_thread);
|
||||
explicit SequenceCheckerImpl(TaskQueueBase* attached_queue);
|
||||
~SequenceCheckerImpl() = default;
|
||||
|
||||
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_);
|
||||
};
|
||||
|
||||
// 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:
|
||||
explicit SequenceCheckerDoNothing(bool attach_to_current_thread) {}
|
||||
explicit SequenceCheckerDoNothing(TaskQueueBase* attached_queue) {}
|
||||
bool IsCurrent() const { return true; }
|
||||
void Detach() {}
|
||||
};
|
||||
|
||||
template <typename ThreadLikeObject>
|
||||
std::enable_if_t<std::is_base_of_v<SequenceCheckerImpl, ThreadLikeObject>,
|
||||
std::string>
|
||||
ExpectationToString(const ThreadLikeObject* checker) {
|
||||
#if RTC_DCHECK_IS_ON
|
||||
return checker->ExpectationToString();
|
||||
#else
|
||||
return std::string();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Catch-all implementation for types other than explicitly supported above.
|
||||
template <typename ThreadLikeObject>
|
||||
std::enable_if_t<!std::is_base_of_v<SequenceCheckerImpl, ThreadLikeObject>,
|
||||
std::string>
|
||||
ExpectationToString(const ThreadLikeObject*) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
} // namespace webrtc_sequence_checker_internal
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // RTC_BASE_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H_
|
Reference in New Issue
Block a user