• 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/sequenced_worker_pool.h"
12 #include "base/threading/thread_local.h"
13 #include "base/threading/thread_task_runner_handle.h"
14 
15 namespace base {
16 
17 namespace {
18 
19 base::LazyInstance<base::ThreadLocalPointer<SequencedTaskRunnerHandle>>::Leaky
20     lazy_tls_ptr = LAZY_INSTANCE_INITIALIZER;
21 
22 }  // namespace
23 
24 // static
Get()25 scoped_refptr<SequencedTaskRunner> SequencedTaskRunnerHandle::Get() {
26   // Return the registered SequencedTaskRunner, if any.
27   const SequencedTaskRunnerHandle* handle = lazy_tls_ptr.Pointer()->Get();
28   if (handle) {
29     // Various modes of setting SequencedTaskRunnerHandle don't combine.
30     DCHECK(!base::ThreadTaskRunnerHandle::IsSet());
31     DCHECK(!SequencedWorkerPool::GetSequencedTaskRunnerForCurrentThread());
32     return handle->task_runner_;
33   }
34 
35   // Return the SequencedTaskRunner obtained from SequencedWorkerPool, if any.
36   scoped_refptr<base::SequencedTaskRunner> task_runner =
37       SequencedWorkerPool::GetSequencedTaskRunnerForCurrentThread();
38   if (task_runner) {
39     DCHECK(!base::ThreadTaskRunnerHandle::IsSet());
40     return task_runner;
41   }
42 
43   // Return the SingleThreadTaskRunner for the current thread otherwise.
44   return base::ThreadTaskRunnerHandle::Get();
45 }
46 
47 // static
IsSet()48 bool SequencedTaskRunnerHandle::IsSet() {
49   return lazy_tls_ptr.Pointer()->Get() ||
50          SequencedWorkerPool::GetWorkerPoolForCurrentThread() ||
51          base::ThreadTaskRunnerHandle::IsSet();
52 }
53 
SequencedTaskRunnerHandle(scoped_refptr<SequencedTaskRunner> task_runner)54 SequencedTaskRunnerHandle::SequencedTaskRunnerHandle(
55     scoped_refptr<SequencedTaskRunner> task_runner)
56     : task_runner_(std::move(task_runner)) {
57   DCHECK(task_runner_->RunsTasksOnCurrentThread());
58   DCHECK(!SequencedTaskRunnerHandle::IsSet());
59   lazy_tls_ptr.Pointer()->Set(this);
60 }
61 
~SequencedTaskRunnerHandle()62 SequencedTaskRunnerHandle::~SequencedTaskRunnerHandle() {
63   DCHECK(task_runner_->RunsTasksOnCurrentThread());
64   DCHECK_EQ(lazy_tls_ptr.Pointer()->Get(), this);
65   lazy_tls_ptr.Pointer()->Set(nullptr);
66 }
67 
68 }  // namespace base
69