• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&current_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