// Copyright 2012 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/task/sequenced_task_runner.h" #include #include "base/functional/bind.h" #include "base/task/default_delayed_task_handle_delegate.h" #include "base/time/time.h" #include "third_party/abseil-cpp/absl/base/attributes.h" namespace base { namespace { ABSL_CONST_INIT thread_local SequencedTaskRunner::CurrentDefaultHandle* current_default_handle = nullptr; } // namespace bool SequencedTaskRunner::PostNonNestableTask(const Location& from_here, OnceClosure task) { return PostNonNestableDelayedTask(from_here, std::move(task), base::TimeDelta()); } DelayedTaskHandle SequencedTaskRunner::PostCancelableDelayedTask( subtle::PostDelayedTaskPassKey, const Location& from_here, OnceClosure task, TimeDelta delay) { auto delayed_task_handle_delegate = std::make_unique(); task = delayed_task_handle_delegate->BindCallback(std::move(task)); DelayedTaskHandle delayed_task_handle( std::move(delayed_task_handle_delegate)); PostDelayedTask(from_here, std::move(task), delay); return delayed_task_handle; } DelayedTaskHandle SequencedTaskRunner::PostCancelableDelayedTaskAt( subtle::PostDelayedTaskPassKey pass_key, const Location& from_here, OnceClosure task, TimeTicks delayed_run_time, subtle::DelayPolicy deadline_policy) { auto delayed_task_handle_delegate = std::make_unique(); task = delayed_task_handle_delegate->BindCallback(std::move(task)); DelayedTaskHandle delayed_task_handle( std::move(delayed_task_handle_delegate)); if (!PostDelayedTaskAt(pass_key, from_here, std::move(task), delayed_run_time, deadline_policy)) { DCHECK(!delayed_task_handle.IsValid()); } return delayed_task_handle; } bool SequencedTaskRunner::PostDelayedTaskAt( subtle::PostDelayedTaskPassKey, const Location& from_here, OnceClosure task, TimeTicks delayed_run_time, subtle::DelayPolicy deadline_policy) { return PostDelayedTask(from_here, std::move(task), delayed_run_time.is_null() ? base::TimeDelta() : delayed_run_time - TimeTicks::Now()); } bool SequencedTaskRunner::RunOrPostTask(subtle::RunOrPostTaskPassKey, const Location& from_here, OnceClosure task) { return PostTask(from_here, std::move(task)); } // static const scoped_refptr& SequencedTaskRunner::GetCurrentDefault() { CHECK(HasCurrentDefault()) << "Error: This caller requires a sequenced context (i.e. the current " "task needs to run from a SequencedTaskRunner). If you're in a test " "refer to //docs/threading_and_tasks_testing.md."; return current_default_handle->task_runner_; } // static bool SequencedTaskRunner::HasCurrentDefault() { return !!current_default_handle && !!current_default_handle->task_runner_; } SequencedTaskRunner::CurrentDefaultHandle::CurrentDefaultHandle( scoped_refptr task_runner) : CurrentDefaultHandle(std::move(task_runner), MayAlreadyExist{}) { CHECK(!previous_handle_ || !previous_handle_->task_runner_); } SequencedTaskRunner::CurrentDefaultHandle::~CurrentDefaultHandle() { DCHECK_EQ(current_default_handle, this); current_default_handle = previous_handle_; } SequencedTaskRunner::CurrentDefaultHandle::CurrentDefaultHandle( scoped_refptr task_runner, MayAlreadyExist) : task_runner_(std::move(task_runner)), previous_handle_(current_default_handle) { // Support overriding the current default with a null task runner or a task // runner that runs its tasks in the current sequence. DCHECK(!task_runner_ || task_runner_->RunsTasksInCurrentSequence()); current_default_handle = this; } bool SequencedTaskRunner::DeleteOrReleaseSoonInternal( const Location& from_here, void (*deleter)(const void*), const void* object) { return PostNonNestableTask(from_here, BindOnce(deleter, object)); } OnTaskRunnerDeleter::OnTaskRunnerDeleter( scoped_refptr task_runner) : task_runner_(std::move(task_runner)) { } OnTaskRunnerDeleter::~OnTaskRunnerDeleter() = default; OnTaskRunnerDeleter::OnTaskRunnerDeleter(OnTaskRunnerDeleter&&) = default; OnTaskRunnerDeleter& OnTaskRunnerDeleter::operator=( OnTaskRunnerDeleter&&) = default; } // namespace base