diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn index e22904250a..3b9fac45e3 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -316,14 +316,9 @@ rtc_source_set("logging") { rtc_source_set("thread_checker") { sources = [ "thread_checker.h", - "thread_checker_impl.cc", - "thread_checker_impl.h", ] deps = [ - ":checks", - ":criticalsection", - ":macromagic", - ":platform_thread_types", + "synchronization:sequence_checker", ] } @@ -579,15 +574,9 @@ rtc_source_set("rtc_task_queue_stdlib") { rtc_source_set("sequenced_task_checker") { sources = [ "sequenced_task_checker.h", - "sequenced_task_checker_impl.cc", - "sequenced_task_checker_impl.h", ] deps = [ - ":checks", - ":criticalsection", - ":macromagic", - ":thread_checker", - "../api/task_queue", + "synchronization:sequence_checker", ] } diff --git a/rtc_base/platform_thread.cc b/rtc_base/platform_thread.cc index 19da912e66..163e1c378e 100644 --- a/rtc_base/platform_thread.cc +++ b/rtc_base/platform_thread.cc @@ -218,7 +218,6 @@ bool PlatformThread::SetPriority(ThreadPriority priority) { if (run_function_) { // The non-deprecated way of how this function gets called, is that it must // be called on the worker thread itself. - RTC_DCHECK(!thread_checker_.CalledOnValidThread()); RTC_DCHECK(spawned_thread_checker_.CalledOnValidThread()); } else { // In the case of deprecated use of this method, it must be called on the diff --git a/rtc_base/sequenced_task_checker.h b/rtc_base/sequenced_task_checker.h index e5443afe5a..feaa04c7f9 100644 --- a/rtc_base/sequenced_task_checker.h +++ b/rtc_base/sequenced_task_checker.h @@ -11,78 +11,16 @@ #ifndef RTC_BASE_SEQUENCED_TASK_CHECKER_H_ #define RTC_BASE_SEQUENCED_TASK_CHECKER_H_ -// Apart from debug builds, we also enable the sequence checker in -// builds with RTC_DCHECK_IS_ON so that trybots and waterfall bots -// with this define will get the same level of checking as debug bots. -#define ENABLE_SEQUENCED_TASK_CHECKER RTC_DCHECK_IS_ON - -#include "rtc_base/checks.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/sequenced_task_checker_impl.h" -#include "rtc_base/thread_annotations.h" +#include "rtc_base/synchronization/sequence_checker.h" namespace rtc { -namespace internal { -// Forward declaration of the internal implementation of RTC_GUARDED_BY(). -// SequencedTaskChecker grants this class access to call its IsCurrent() method. -// See thread_checker.h for more details. -class AnnounceOnThread; -} // namespace internal - -// Do nothing implementation, for use in release mode. -// -// Note: You should almost always use the SequencedTaskChecker class to get the -// right version for your build configuration. -class SequencedTaskCheckerDoNothing { +// TODO(srte): Replace usages of this with SequenceChecker. +class SequencedTaskChecker : public webrtc::SequenceChecker { public: - bool CalledSequentially() const { return true; } - void Detach() {} - - private: - friend class internal::AnnounceOnThread; - bool IsCurrent() const { return CalledSequentially(); } + bool CalledSequentially() const { return IsCurrent(); } }; - -// SequencedTaskChecker is a helper class used to help verify that some methods -// of a class are called on the same task queue or thread. A -// SequencedTaskChecker 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(sequence_checker_.CalledSequentially()); -// ... (do stuff) ... -// } -// -// private: -// SequencedTaskChecker sequence_checker_; -// } -// -// In Release mode, CalledOnValidThread will always return true. -#if ENABLE_SEQUENCED_TASK_CHECKER -class RTC_LOCKABLE SequencedTaskChecker : public SequencedTaskCheckerImpl {}; -#else -class RTC_LOCKABLE SequencedTaskChecker : public SequencedTaskCheckerDoNothing { -}; -#endif // ENABLE_SEQUENCED_TASK_CHECKER_H_ - -namespace internal { -class RTC_SCOPED_LOCKABLE SequencedTaskCheckerScope { - public: - explicit SequencedTaskCheckerScope(const SequencedTaskChecker* checker) - RTC_EXCLUSIVE_LOCK_FUNCTION(checker); - ~SequencedTaskCheckerScope() RTC_UNLOCK_FUNCTION(); -}; - -} // namespace internal - -#define RTC_DCHECK_CALLED_SEQUENTIALLY(x) \ - rtc::internal::SequencedTaskCheckerScope checker(x) - -#undef ENABLE_SEQUENCED_TASK_CHECKER - } // namespace rtc + +#define RTC_DCHECK_CALLED_SEQUENTIALLY(x) RTC_DCHECK_RUN_ON(x) + #endif // RTC_BASE_SEQUENCED_TASK_CHECKER_H_ diff --git a/rtc_base/sequenced_task_checker_impl.cc b/rtc_base/sequenced_task_checker_impl.cc deleted file mode 100644 index 678f91d0fd..0000000000 --- a/rtc_base/sequenced_task_checker_impl.cc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2016 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/sequenced_task_checker_impl.h" - -#if defined(WEBRTC_MAC) -#include -#endif - -#include "api/task_queue/task_queue_base.h" -#include "rtc_base/checks.h" -#include "rtc_base/sequenced_task_checker.h" - -namespace rtc { - -SequencedTaskCheckerImpl::SequencedTaskCheckerImpl() - : attached_(true), valid_queue_(webrtc::TaskQueueBase::Current()) {} - -SequencedTaskCheckerImpl::~SequencedTaskCheckerImpl() {} - -bool SequencedTaskCheckerImpl::CalledSequentially() const { - QueueId current_queue = webrtc::TaskQueueBase::Current(); -#if defined(WEBRTC_MAC) - // If we're not running on a TaskQueue, use the system dispatch queue - // label as an identifier. - if (current_queue == nullptr) - current_queue = dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL); -#endif - CritScope scoped_lock(&lock_); - if (!attached_) { // true if previously detached. - valid_queue_ = current_queue; - attached_ = true; - } - if (!valid_queue_) - return thread_checker_.CalledOnValidThread(); - return valid_queue_ == current_queue; -} - -void SequencedTaskCheckerImpl::Detach() { - CritScope scoped_lock(&lock_); - attached_ = false; - valid_queue_ = nullptr; - thread_checker_.DetachFromThread(); -} - -namespace internal { - -SequencedTaskCheckerScope::SequencedTaskCheckerScope( - const SequencedTaskChecker* checker) { - RTC_DCHECK(checker->CalledSequentially()); -} - -SequencedTaskCheckerScope::~SequencedTaskCheckerScope() {} - -} // namespace internal -} // namespace rtc diff --git a/rtc_base/sequenced_task_checker_impl.h b/rtc_base/sequenced_task_checker_impl.h deleted file mode 100644 index bd539611cd..0000000000 --- a/rtc_base/sequenced_task_checker_impl.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016 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_SEQUENCED_TASK_CHECKER_IMPL_H_ -#define RTC_BASE_SEQUENCED_TASK_CHECKER_IMPL_H_ - -#include "rtc_base/critical_section.h" -#include "rtc_base/thread_checker.h" - -namespace rtc { - -// Real implementation of SequencedTaskChecker, for use in debug mode, or -// for temporary use in release mode. -// -// Note: You should almost always use the SequencedTaskChecker class to get the -// right version for your build configuration. -class SequencedTaskCheckerImpl { - public: - SequencedTaskCheckerImpl(); - ~SequencedTaskCheckerImpl(); - - bool CalledSequentially() const; - - // Changes the task queue or thread that is checked for in IsCurrent. This - // may be useful when an object may be created on one task queue / thread and - // then used exclusively on another thread. - void Detach(); - - private: - friend class internal::AnnounceOnThread; - bool IsCurrent() const { return CalledSequentially(); } - - typedef const void* QueueId; - CriticalSection lock_; - ThreadChecker thread_checker_; - mutable bool attached_; - mutable QueueId valid_queue_; -}; - -} // namespace rtc -#endif // RTC_BASE_SEQUENCED_TASK_CHECKER_IMPL_H_ diff --git a/rtc_base/synchronization/BUILD.gn b/rtc_base/synchronization/BUILD.gn index 05d36f1099..975c1a1968 100644 --- a/rtc_base/synchronization/BUILD.gn +++ b/rtc_base/synchronization/BUILD.gn @@ -36,6 +36,20 @@ rtc_source_set("rw_lock_wrapper") { } } +rtc_source_set("sequence_checker") { + sources = [ + "sequence_checker.cc", + "sequence_checker.h", + ] + deps = [ + "..:checks", + "..:criticalsection", + "..:macromagic", + "..:platform_thread_types", + "../../api/task_queue", + ] +} + rtc_source_set("yield_policy") { sources = [ "yield_policy.cc", diff --git a/rtc_base/synchronization/sequence_checker.cc b/rtc_base/synchronization/sequence_checker.cc new file mode 100644 index 0000000000..d64f32a616 --- /dev/null +++ b/rtc_base/synchronization/sequence_checker.cc @@ -0,0 +1,65 @@ +/* + * 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 +#endif + +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 + +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(); + rtc::CritScope 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() { + rtc::CritScope 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(). +} + +} // namespace webrtc diff --git a/rtc_base/synchronization/sequence_checker.h b/rtc_base/synchronization/sequence_checker.h new file mode 100644 index 0000000000..910c99d239 --- /dev/null +++ b/rtc_base/synchronization/sequence_checker.h @@ -0,0 +1,168 @@ +/* + * 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 "api/task_queue/task_queue_base.h" +#include "rtc_base/critical_section.h" +#include "rtc_base/platform_thread_types.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 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(); + + private: + rtc::CriticalSection 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 + 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 + 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_->Queue()->PostTask([encoder] { encoder->Encode(); }); +// } +// +// private: +// rtc::scoped_refptr 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)) + +#define RTC_DCHECK_RUN_ON(x) \ + webrtc::webrtc_seq_check_impl::SequenceCheckerScope seq_check_scope(x); \ + RTC_DCHECK((x)->IsCurrent()) + +#endif // RTC_BASE_SYNCHRONIZATION_SEQUENCE_CHECKER_H_ diff --git a/rtc_base/thread_checker.h b/rtc_base/thread_checker.h index 43f7320945..d3daa6f764 100644 --- a/rtc_base/thread_checker.h +++ b/rtc_base/thread_checker.h @@ -13,159 +13,14 @@ #ifndef RTC_BASE_THREAD_CHECKER_H_ #define RTC_BASE_THREAD_CHECKER_H_ -// Apart from debug builds, we also enable the thread checker in -// builds with RTC_DCHECK_IS_ON so that trybots and waterfall bots -// with this define will get the same level of thread checking as -// debug bots. -#define RTC_ENABLE_THREAD_CHECKER RTC_DCHECK_IS_ON - -#include "rtc_base/checks.h" -#include "rtc_base/constructor_magic.h" -#include "rtc_base/thread_annotations.h" -#include "rtc_base/thread_checker_impl.h" +#include "rtc_base/synchronization/sequence_checker.h" namespace rtc { - -// Do nothing implementation, for use in release mode. -// -// Note: You should almost always use the ThreadChecker class to get the -// right version for your build configuration. -class ThreadCheckerDoNothing { +// TODO(srte): Replace usages of this with SequenceChecker. +class ThreadChecker : public webrtc::SequenceChecker { public: - bool CalledOnValidThread() const { return true; } - - void DetachFromThread() {} + bool CalledOnValidThread() const { return IsCurrent(); } + void DetachFromThread() { Detach(); } }; - -// ThreadChecker is a helper class used to help verify that some methods of a -// class are called from the same thread. It provides identical functionality to -// base::NonThreadSafe, but it is meant to be held as a member variable, rather -// than inherited from base::NonThreadSafe. -// -// While inheriting from base::NonThreadSafe may give a clear indication about -// the thread-safety of a class, it may also lead to violations of the style -// guide with regard to multiple inheritance. The choice between having a -// ThreadChecker member and inheriting from base::NonThreadSafe should be based -// on whether: -// - Derived classes need to know the thread they belong to, as opposed to -// having that functionality fully encapsulated in the base class. -// - Derived classes should be able to reassign the base class to another -// thread, via DetachFromThread. -// -// If neither of these are true, then having a ThreadChecker member and calling -// CalledOnValidThread is the preferable solution. -// -// Example: -// class MyClass { -// public: -// void Foo() { -// RTC_DCHECK(thread_checker_.CalledOnValidThread()); -// ... (do stuff) ... -// } -// -// private: -// ThreadChecker thread_checker_; -// } -// -// In Release mode, CalledOnValidThread will always return true. -#if RTC_ENABLE_THREAD_CHECKER -class RTC_LOCKABLE ThreadChecker : public ThreadCheckerImpl {}; -#else -class RTC_LOCKABLE ThreadChecker : public ThreadCheckerDoNothing {}; -#endif // RTC_ENABLE_THREAD_CHECKER - -#undef RTC_ENABLE_THREAD_CHECKER - -namespace internal { -class RTC_SCOPED_LOCKABLE AnnounceOnThread { - public: - template - explicit AnnounceOnThread(const ThreadLikeObject* thread_like_object) - RTC_EXCLUSIVE_LOCK_FUNCTION(thread_like_object) {} - ~AnnounceOnThread() RTC_UNLOCK_FUNCTION() {} - - template - static bool IsCurrent(const ThreadLikeObject* thread_like_object) { - return thread_like_object->IsCurrent(); - } - static bool IsCurrent(const rtc::ThreadChecker* checker) { - return checker->CalledOnValidThread(); - } - - private: - RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AnnounceOnThread); -}; - -} // namespace internal } // namespace rtc - -// 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 ExampleThread { -// public: -// void NeedVar1() { -// RTC_DCHECK_RUN_ON(network_thread_); -// transport_->Send(); -// } -// -// private: -// rtc::Thread* network_thread_; -// int transport_ RTC_GUARDED_BY(network_thread_); -// }; -// -// class ExampleThreadChecker { -// public: -// int CalledFromPacer() RTC_RUN_ON(pacer_thread_checker_) { -// return var2_; -// } -// -// void CallMeFromPacer() { -// RTC_DCHECK_RUN_ON(&pacer_thread_checker_) -// << "Should be called from pacer"; -// CalledFromPacer(); -// } -// -// private: -// int pacer_var_ RTC_GUARDED_BY(pacer_thread_checker_); -// rtc::ThreadChecker pacer_thread_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_->Queue()->PostTask([encoder] { encoder->Encode(); }); -// } -// -// private: -// rtc::scoped_refptr 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)) - -#define RTC_DCHECK_RUN_ON(thread_like_object) \ - rtc::internal::AnnounceOnThread thread_announcer(thread_like_object); \ - RTC_DCHECK(rtc::internal::AnnounceOnThread::IsCurrent(thread_like_object)) - #endif // RTC_BASE_THREAD_CHECKER_H_ diff --git a/rtc_base/thread_checker_impl.cc b/rtc_base/thread_checker_impl.cc deleted file mode 100644 index a9e87c67a0..0000000000 --- a/rtc_base/thread_checker_impl.cc +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2014 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. - */ - -// Borrowed from Chromium's src/base/threading/thread_checker_impl.cc. - -#include "rtc_base/thread_checker_impl.h" - -namespace rtc { - -ThreadCheckerImpl::ThreadCheckerImpl() : valid_thread_(CurrentThreadRef()) {} - -ThreadCheckerImpl::~ThreadCheckerImpl() {} - -bool ThreadCheckerImpl::CalledOnValidThread() const { - const PlatformThreadRef current_thread = CurrentThreadRef(); - CritScope scoped_lock(&lock_); - if (!valid_thread_) // Set if previously detached. - valid_thread_ = current_thread; - return IsThreadRefEqual(valid_thread_, current_thread); -} - -void ThreadCheckerImpl::DetachFromThread() { - CritScope scoped_lock(&lock_); - valid_thread_ = 0; -} - -} // namespace rtc diff --git a/rtc_base/thread_checker_impl.h b/rtc_base/thread_checker_impl.h deleted file mode 100644 index c39e10f951..0000000000 --- a/rtc_base/thread_checker_impl.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2014 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. - */ - -// Borrowed from Chromium's src/base/threading/thread_checker_impl.h. - -#ifndef RTC_BASE_THREAD_CHECKER_IMPL_H_ -#define RTC_BASE_THREAD_CHECKER_IMPL_H_ - -#include "rtc_base/critical_section.h" -#include "rtc_base/platform_thread_types.h" - -namespace rtc { - -// Real implementation of ThreadChecker, 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 ThreadChecker class to get the -// right version for your build configuration. -class ThreadCheckerImpl { - public: - ThreadCheckerImpl(); - ~ThreadCheckerImpl(); - - bool CalledOnValidThread() const; - - // Changes the thread that is checked for in CalledOnValidThread. This may - // be useful when an object may be created on one thread and then used - // exclusively on another thread. - void DetachFromThread(); - - private: - CriticalSection lock_; - // This is mutable so that CalledOnValidThread can set it. - // It's guarded by |lock_|. - mutable PlatformThreadRef valid_thread_; -}; - -} // namespace rtc - -#endif // RTC_BASE_THREAD_CHECKER_IMPL_H_ diff --git a/video/video_send_stream.h b/video/video_send_stream.h index 827f991d62..9466c74699 100644 --- a/video/video_send_stream.h +++ b/video/video_send_stream.h @@ -23,6 +23,7 @@ #include "rtc_base/critical_section.h" #include "rtc_base/event.h" #include "rtc_base/task_queue.h" +#include "rtc_base/thread_checker.h" #include "video/send_delay_stats.h" #include "video/send_statistics_proxy.h"