1 // Copyright 2015 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/threading/sequenced_task_runner_handle.h" 6 7 #include <utility> 8 9 #include "base/lazy_instance.h" 10 #include "base/logging.h" 11 #include "base/threading/thread_local.h" 12 #include "base/threading/thread_task_runner_handle.h" 13 14 namespace base { 15 16 namespace { 17 18 LazyInstance<ThreadLocalPointer<SequencedTaskRunnerHandle>>::Leaky 19 sequenced_task_runner_tls = LAZY_INSTANCE_INITIALIZER; 20 21 } // namespace 22 23 // static Get()24scoped_refptr<SequencedTaskRunner> SequencedTaskRunnerHandle::Get() { 25 // Return the registered SequencedTaskRunner, if any. 26 const SequencedTaskRunnerHandle* handle = 27 sequenced_task_runner_tls.Pointer()->Get(); 28 if (handle) 29 return handle->task_runner_; 30 31 // Note if you hit this: the problem is the lack of a sequenced context. The 32 // ThreadTaskRunnerHandle is just the last attempt at finding such a context. 33 CHECK(ThreadTaskRunnerHandle::IsSet()) 34 << "Error: This caller requires a sequenced context (i.e. the " 35 "current task needs to run from a SequencedTaskRunner)."; 36 return ThreadTaskRunnerHandle::Get(); 37 } 38 39 // static IsSet()40bool SequencedTaskRunnerHandle::IsSet() { 41 return sequenced_task_runner_tls.Pointer()->Get() || 42 ThreadTaskRunnerHandle::IsSet(); 43 } 44 SequencedTaskRunnerHandle(scoped_refptr<SequencedTaskRunner> task_runner)45SequencedTaskRunnerHandle::SequencedTaskRunnerHandle( 46 scoped_refptr<SequencedTaskRunner> task_runner) 47 : task_runner_(std::move(task_runner)) { 48 DCHECK(task_runner_->RunsTasksInCurrentSequence()); 49 DCHECK(!SequencedTaskRunnerHandle::IsSet()); 50 sequenced_task_runner_tls.Pointer()->Set(this); 51 } 52 ~SequencedTaskRunnerHandle()53SequencedTaskRunnerHandle::~SequencedTaskRunnerHandle() { 54 DCHECK(task_runner_->RunsTasksInCurrentSequence()); 55 DCHECK_EQ(sequenced_task_runner_tls.Pointer()->Get(), this); 56 sequenced_task_runner_tls.Pointer()->Set(nullptr); 57 } 58 59 } // namespace base 60