diff options
Diffstat (limited to 'base/threading/thread_checker_impl.cc')
-rw-r--r-- | base/threading/thread_checker_impl.cc | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/base/threading/thread_checker_impl.cc b/base/threading/thread_checker_impl.cc index eb87bae772..d5ccbdb943 100644 --- a/base/threading/thread_checker_impl.cc +++ b/base/threading/thread_checker_impl.cc @@ -4,31 +4,54 @@ #include "base/threading/thread_checker_impl.h" +#include "base/threading/thread_task_runner_handle.h" + namespace base { -ThreadCheckerImpl::ThreadCheckerImpl() - : valid_thread_id_() { - EnsureThreadIdAssigned(); +ThreadCheckerImpl::ThreadCheckerImpl() { + AutoLock auto_lock(lock_); + EnsureAssigned(); } -ThreadCheckerImpl::~ThreadCheckerImpl() {} +ThreadCheckerImpl::~ThreadCheckerImpl() = default; bool ThreadCheckerImpl::CalledOnValidThread() const { - EnsureThreadIdAssigned(); AutoLock auto_lock(lock_); - return valid_thread_id_ == PlatformThread::CurrentRef(); + EnsureAssigned(); + + // Always return true when called from the task from which this + // ThreadCheckerImpl was assigned to a thread. + if (task_token_ == TaskToken::GetForCurrentThread()) + return true; + + // If this ThreadCheckerImpl is bound to a valid SequenceToken, it must be + // equal to the current SequenceToken and there must be a registered + // ThreadTaskRunnerHandle. Otherwise, the fact that the current task runs on + // the thread to which this ThreadCheckerImpl is bound is fortuitous. + if (sequence_token_.IsValid() && + (sequence_token_ != SequenceToken::GetForCurrentThread() || + !ThreadTaskRunnerHandle::IsSet())) { + return false; + } + + return thread_id_ == PlatformThread::CurrentRef(); } void ThreadCheckerImpl::DetachFromThread() { AutoLock auto_lock(lock_); - valid_thread_id_ = PlatformThreadRef(); + thread_id_ = PlatformThreadRef(); + task_token_ = TaskToken(); + sequence_token_ = SequenceToken(); } -void ThreadCheckerImpl::EnsureThreadIdAssigned() const { - AutoLock auto_lock(lock_); - if (valid_thread_id_.is_null()) { - valid_thread_id_ = PlatformThread::CurrentRef(); - } +void ThreadCheckerImpl::EnsureAssigned() const { + lock_.AssertAcquired(); + if (!thread_id_.is_null()) + return; + + thread_id_ = PlatformThread::CurrentRef(); + task_token_ = TaskToken::GetForCurrentThread(); + sequence_token_ = SequenceToken::GetForCurrentThread(); } } // namespace base |