1 // Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4
5 #include "libcef/common/task_runner_impl.h"
6 #include "libcef/common/task_runner_manager.h"
7
8 #include "base/bind.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/task/post_task.h"
12 #include "base/threading/thread_task_runner_handle.h"
13 #include "content/public/browser/browser_task_traits.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/child_process_launcher_utils.h"
16
17 using content::BrowserThread;
18
19 // CefTaskRunner
20
21 // static
GetForCurrentThread()22 CefRefPtr<CefTaskRunner> CefTaskRunner::GetForCurrentThread() {
23 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
24 CefTaskRunnerImpl::GetCurrentTaskRunner();
25 if (task_runner.get())
26 return new CefTaskRunnerImpl(task_runner);
27 return nullptr;
28 }
29
30 // static
GetForThread(CefThreadId threadId)31 CefRefPtr<CefTaskRunner> CefTaskRunner::GetForThread(CefThreadId threadId) {
32 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
33 CefTaskRunnerImpl::GetTaskRunner(threadId);
34 if (task_runner.get())
35 return new CefTaskRunnerImpl(task_runner);
36
37 LOG(WARNING) << "Invalid thread id " << threadId;
38 return nullptr;
39 }
40
41 // CefTaskRunnerImpl
42
CefTaskRunnerImpl(scoped_refptr<base::SingleThreadTaskRunner> task_runner)43 CefTaskRunnerImpl::CefTaskRunnerImpl(
44 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
45 : task_runner_(task_runner) {
46 DCHECK(task_runner_.get());
47 }
48
49 // static
GetTaskRunner(CefThreadId threadId)50 scoped_refptr<base::SingleThreadTaskRunner> CefTaskRunnerImpl::GetTaskRunner(
51 CefThreadId threadId) {
52 auto* manager = CefTaskRunnerManager::Get();
53 if (!manager)
54 return nullptr;
55
56 int id = -1;
57 switch (threadId) {
58 case TID_UI:
59 id = BrowserThread::UI;
60 break;
61 case TID_FILE_BACKGROUND:
62 return manager->GetBackgroundTaskRunner();
63 case TID_FILE_USER_VISIBLE:
64 return manager->GetUserVisibleTaskRunner();
65 case TID_FILE_USER_BLOCKING:
66 return manager->GetUserBlockingTaskRunner();
67 case TID_PROCESS_LAUNCHER:
68 return content::GetProcessLauncherTaskRunner();
69 case TID_IO:
70 id = BrowserThread::IO;
71 break;
72 case TID_RENDERER:
73 return manager->GetRenderTaskRunner();
74 default:
75 break;
76 };
77
78 if (id >= 0 &&
79 BrowserThread::IsThreadInitialized(static_cast<BrowserThread::ID>(id))) {
80 // Specify USER_BLOCKING so that BrowserTaskExecutor::GetTaskRunner always
81 // gives us the same TaskRunner object.
82 return base::CreateSingleThreadTaskRunner(
83 {static_cast<BrowserThread::ID>(id),
84 base::TaskPriority::USER_BLOCKING});
85 }
86
87 return nullptr;
88 }
89
90 // static
91 scoped_refptr<base::SingleThreadTaskRunner>
GetCurrentTaskRunner()92 CefTaskRunnerImpl::GetCurrentTaskRunner() {
93 auto* manager = CefTaskRunnerManager::Get();
94 if (!manager)
95 return nullptr;
96
97 scoped_refptr<base::SingleThreadTaskRunner> task_runner;
98
99 // For named browser process threads return the same TaskRunner as
100 // GetTaskRunner(). Otherwise BelongsToThread() will return incorrect results.
101 BrowserThread::ID current_id;
102 if (BrowserThread::GetCurrentThreadIdentifier(¤t_id) &&
103 BrowserThread::IsThreadInitialized(current_id)) {
104 // Specify USER_BLOCKING so that BrowserTaskExecutor::GetTaskRunner always
105 // gives us the same TaskRunner object.
106 task_runner = base::CreateSingleThreadTaskRunner(
107 {current_id, base::TaskPriority::USER_BLOCKING});
108 }
109
110 if (!task_runner.get()) {
111 // Check for a MessageLoopProxy. This covers all of the named browser and
112 // render process threads, plus a few extra.
113 task_runner = base::ThreadTaskRunnerHandle::Get();
114 }
115
116 if (!task_runner.get()) {
117 // Check for a WebWorker thread.
118 return manager->GetWebWorkerTaskRunner();
119 }
120
121 return task_runner;
122 }
123
IsSame(CefRefPtr<CefTaskRunner> that)124 bool CefTaskRunnerImpl::IsSame(CefRefPtr<CefTaskRunner> that) {
125 CefTaskRunnerImpl* impl = static_cast<CefTaskRunnerImpl*>(that.get());
126 return (impl && task_runner_ == impl->task_runner_);
127 }
128
BelongsToCurrentThread()129 bool CefTaskRunnerImpl::BelongsToCurrentThread() {
130 return task_runner_->RunsTasksInCurrentSequence();
131 }
132
BelongsToThread(CefThreadId threadId)133 bool CefTaskRunnerImpl::BelongsToThread(CefThreadId threadId) {
134 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
135 GetTaskRunner(threadId);
136 return (task_runner_ == task_runner);
137 }
138
PostTask(CefRefPtr<CefTask> task)139 bool CefTaskRunnerImpl::PostTask(CefRefPtr<CefTask> task) {
140 return task_runner_->PostTask(FROM_HERE,
141 base::BindOnce(&CefTask::Execute, task.get()));
142 }
143
PostDelayedTask(CefRefPtr<CefTask> task,int64 delay_ms)144 bool CefTaskRunnerImpl::PostDelayedTask(CefRefPtr<CefTask> task,
145 int64 delay_ms) {
146 return task_runner_->PostDelayedTask(
147 FROM_HERE, base::BindOnce(&CefTask::Execute, task.get()),
148 base::Milliseconds(delay_ms));
149 }
150