// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/threading/thread_checker_impl.h" #include "base/threading/thread_task_runner_handle.h" namespace base { ThreadCheckerImpl::ThreadCheckerImpl() { AutoLock auto_lock(lock_); EnsureAssigned(); } ThreadCheckerImpl::~ThreadCheckerImpl() = default; bool ThreadCheckerImpl::CalledOnValidThread() const { AutoLock auto_lock(lock_); 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_); thread_id_ = PlatformThreadRef(); task_token_ = TaskToken(); sequence_token_ = SequenceToken(); } 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