• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()24 scoped_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()40 bool SequencedTaskRunnerHandle::IsSet() {
41   return sequenced_task_runner_tls.Pointer()->Get() ||
42          ThreadTaskRunnerHandle::IsSet();
43 }
44 
SequencedTaskRunnerHandle(scoped_refptr<SequencedTaskRunner> task_runner)45 SequencedTaskRunnerHandle::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()53 SequencedTaskRunnerHandle::~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