Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: content/common/mojo/embedded_application_runner.cc

Issue 1978843003: Move in-GPU mojo:media app to new thread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/mojo/embedded_application_runner.h" 5 #include "content/common/mojo/embedded_application_runner.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/memory/ref_counted.h" 11 #include "base/memory/ref_counted.h"
12 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
13 #include "base/threading/thread.h"
13 #include "base/threading/thread_checker.h" 14 #include "base/threading/thread_checker.h"
14 #include "base/threading/thread_task_runner_handle.h" 15 #include "base/threading/thread_task_runner_handle.h"
15 #include "services/shell/public/cpp/shell_connection.h" 16 #include "services/shell/public/cpp/shell_connection.h"
16 17
17 namespace content { 18 namespace content {
18 19
19 class EmbeddedApplicationRunner::Instance 20 class EmbeddedApplicationRunner::Instance
20 : public base::RefCountedThreadSafe<Instance> { 21 : public base::RefCountedThreadSafe<Instance> {
21 public: 22 public:
22 explicit Instance( 23 Instance(const base::StringPiece& name,
23 const EmbeddedApplicationRunner::FactoryCallback& callback, 24 const MojoApplicationInfo& info,
24 const base::Closure& quit_closure) 25 const base::Closure& quit_closure)
25 : factory_callback_(callback), 26 : name_(name.as_string()),
27 factory_callback_(info.application_factory),
28 use_own_thread_(!info.application_task_runner && info.use_own_thread),
26 quit_closure_(quit_closure), 29 quit_closure_(quit_closure),
27 quit_task_runner_(base::ThreadTaskRunnerHandle::Get()) { 30 quit_task_runner_(base::ThreadTaskRunnerHandle::Get()),
28 // This object may be used exclusively from a single thread which may be 31 application_task_runner_(info.application_task_runner) {
29 // different from the one that created it. 32 application_thread_checker_.DetachFromThread();
30 thread_checker_.DetachFromThread(); 33
34 if (!use_own_thread_ && !application_task_runner_)
35 application_task_runner_ = base::ThreadTaskRunnerHandle::Get();
31 } 36 }
32 37
33 void BindShellClientRequest(shell::mojom::ShellClientRequest request) { 38 void BindShellClientRequest(shell::mojom::ShellClientRequest request) {
34 DCHECK(thread_checker_.CalledOnValidThread()); 39 DCHECK(runner_thread_checker_.CalledOnValidThread());
40
41 if (use_own_thread_ && !thread_) {
42 // Start a new thread if necessary.
43 thread_.reset(new base::Thread(name_));
44 thread_->Start();
45 application_task_runner_ = thread_->task_runner();
46 }
47
48 DCHECK(application_task_runner_);
49 application_task_runner_->PostTask(
50 FROM_HERE,
51 base::Bind(&Instance::BindShellClientRequestOnApplicationThread, this,
52 base::Passed(&request)));
53 }
54
55 void ShutDown() {
56 DCHECK(runner_thread_checker_.CalledOnValidThread());
57 if (thread_) {
58 application_task_runner_ = nullptr;
59 thread_.reset();
60 }
61 }
62
63 private:
64 void BindShellClientRequestOnApplicationThread(
65 shell::mojom::ShellClientRequest request) {
66 DCHECK(application_thread_checker_.CalledOnValidThread());
35 67
36 if (!shell_client_) { 68 if (!shell_client_) {
37 shell_client_ = factory_callback_.Run( 69 shell_client_ = factory_callback_.Run(
38 base::Bind(&Instance::Quit, base::Unretained(this))); 70 base::Bind(&Instance::Quit, base::Unretained(this)));
39 } 71 }
40 72
41 shell::ShellConnection* new_connection = 73 shell::ShellConnection* new_connection =
42 new shell::ShellConnection(shell_client_.get(), std::move(request)); 74 new shell::ShellConnection(shell_client_.get(), std::move(request));
43 shell_connections_.push_back(base::WrapUnique(new_connection)); 75 shell_connections_.push_back(base::WrapUnique(new_connection));
44 new_connection->SetConnectionLostClosure( 76 new_connection->SetConnectionLostClosure(
45 base::Bind(&Instance::OnShellConnectionLost, base::Unretained(this), 77 base::Bind(&Instance::OnShellConnectionLost, base::Unretained(this),
46 new_connection)); 78 new_connection));
47 } 79 }
48 80
49 private: 81 private:
50 friend class base::RefCountedThreadSafe<Instance>; 82 friend class base::RefCountedThreadSafe<Instance>;
51 83
52 ~Instance() { DCHECK(thread_checker_.CalledOnValidThread()); } 84 ~Instance() {
85 // If this instance had its own thread, it MUST be explicitly destroyed by
86 // ShutDown() on the runner's thread by the time this destructor is run.
87 DCHECK(!thread_);
88 }
53 89
54 void OnShellConnectionLost(shell::ShellConnection* connection) { 90 void OnShellConnectionLost(shell::ShellConnection* connection) {
55 DCHECK(thread_checker_.CalledOnValidThread()); 91 DCHECK(application_thread_checker_.CalledOnValidThread());
56 92
57 for (auto it = shell_connections_.begin(); it != shell_connections_.end(); 93 for (auto it = shell_connections_.begin(); it != shell_connections_.end();
58 ++it) { 94 ++it) {
59 if (it->get() == connection) { 95 if (it->get() == connection) {
60 shell_connections_.erase(it); 96 shell_connections_.erase(it);
61 break; 97 break;
62 } 98 }
63 } 99 }
64 } 100 }
65 101
66 void Quit() { 102 void Quit() {
103 DCHECK(application_thread_checker_.CalledOnValidThread());
104
67 shell_connections_.clear(); 105 shell_connections_.clear();
68 shell_client_.reset(); 106 shell_client_.reset();
69 quit_task_runner_->PostTask(FROM_HERE, quit_closure_); 107 quit_task_runner_->PostTask(
108 FROM_HERE, base::Bind(&Instance::QuitOnRunnerThread, this));
70 } 109 }
71 110
72 base::ThreadChecker thread_checker_; 111 void QuitOnRunnerThread() {
73 const FactoryCallback factory_callback_; 112 DCHECK(runner_thread_checker_.CalledOnValidThread());
113 ShutDown();
114 quit_closure_.Run();
115 }
116
117 const std::string name_;
118 const MojoApplicationInfo::ApplicationFactory factory_callback_;
119 const bool use_own_thread_;
120 const base::Closure quit_closure_;
121 const scoped_refptr<base::SingleThreadTaskRunner> quit_task_runner_;
122
123 // Thread checker used to ensure certain operations happen only on the
124 // runner's (i.e. our owner's) thread.
125 base::ThreadChecker runner_thread_checker_;
126
127 // Thread checker used to ensure certain operations happen only on the
128 // application task runner's thread.
129 base::ThreadChecker application_thread_checker_;
130
131 // These fields must only be accessed from the runner's thread.
132 std::unique_ptr<base::Thread> thread_;
133 scoped_refptr<base::SingleThreadTaskRunner> application_task_runner_;
134
135 // These fields must only be accessed from the application thread, except in
136 // the destructor which may run on either the runner thread or the application
137 // thread.
74 std::unique_ptr<shell::ShellClient> shell_client_; 138 std::unique_ptr<shell::ShellClient> shell_client_;
75 std::vector<std::unique_ptr<shell::ShellConnection>> shell_connections_; 139 std::vector<std::unique_ptr<shell::ShellConnection>> shell_connections_;
76 const base::Closure quit_closure_;
77 const scoped_refptr<base::SingleThreadTaskRunner> quit_task_runner_;
78 140
79 DISALLOW_COPY_AND_ASSIGN(Instance); 141 DISALLOW_COPY_AND_ASSIGN(Instance);
80 }; 142 };
81 143
82 EmbeddedApplicationRunner::EmbeddedApplicationRunner( 144 EmbeddedApplicationRunner::EmbeddedApplicationRunner(
83 const FactoryCallback& callback, 145 const base::StringPiece& name,
84 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) 146 const MojoApplicationInfo& info)
85 : application_task_runner_( 147 : weak_factory_(this) {
86 task_runner ? task_runner : base::ThreadTaskRunnerHandle::Get()), 148 instance_ = new Instance(name, info,
87 weak_factory_(this) {
88 instance_ = new Instance(callback,
89 base::Bind(&EmbeddedApplicationRunner::OnQuit, 149 base::Bind(&EmbeddedApplicationRunner::OnQuit,
90 weak_factory_.GetWeakPtr())); 150 weak_factory_.GetWeakPtr()));
91 } 151 }
92 152
93 EmbeddedApplicationRunner::~EmbeddedApplicationRunner() { 153 EmbeddedApplicationRunner::~EmbeddedApplicationRunner() {
154 instance_->ShutDown();
94 } 155 }
95 156
96 void EmbeddedApplicationRunner::BindShellClientRequest( 157 void EmbeddedApplicationRunner::BindShellClientRequest(
97 shell::mojom::ShellClientRequest request) { 158 shell::mojom::ShellClientRequest request) {
98 application_task_runner_->PostTask( 159 instance_->BindShellClientRequest(std::move(request));
99 FROM_HERE,
100 base::Bind(&Instance::BindShellClientRequest, instance_,
101 base::Passed(&request)));
102 } 160 }
103 161
104 void EmbeddedApplicationRunner::SetQuitClosure( 162 void EmbeddedApplicationRunner::SetQuitClosure(
105 const base::Closure& quit_closure) { 163 const base::Closure& quit_closure) {
106 quit_closure_ = quit_closure; 164 quit_closure_ = quit_closure;
107 } 165 }
108 166
109 void EmbeddedApplicationRunner::OnQuit() { 167 void EmbeddedApplicationRunner::OnQuit() {
110 quit_closure_.Run(); 168 if (!quit_closure_.is_null())
169 quit_closure_.Run();
111 } 170 }
112 171
113 } // namespace content 172 } // namespace content
OLDNEW
« no previous file with comments | « content/common/mojo/embedded_application_runner.h ('k') | content/gpu/gpu_process_control_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698