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

Side by Side Diff: chrome/app/mash/mash_runner.cc

Issue 2686353002: mash: Fix shutdown crashes by tearing down ServiceContext before message loop (Closed)
Patch Set: Created 3 years, 10 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
« no previous file with comments | « chrome/app/mash/mash_runner.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "chrome/app/mash/mash_runner.h" 5 #include "chrome/app/mash/mash_runner.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/at_exit.h" 9 #include "base/at_exit.h"
10 #include "base/base_paths.h" 10 #include "base/base_paths.h"
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 base::TaskScheduler::CreateAndSetSimpleTaskScheduler( 152 base::TaskScheduler::CreateAndSetSimpleTaskScheduler(
153 base::SysInfo::NumberOfProcessors()); 153 base::SysInfo::NumberOfProcessors());
154 154
155 if (IsChild()) 155 if (IsChild())
156 return RunChild(); 156 return RunChild();
157 157
158 return RunMain(); 158 return RunMain();
159 } 159 }
160 160
161 int MashRunner::RunMain() { 161 int MashRunner::RunMain() {
162 base::MessageLoop message_loop(base::MessageLoop::TYPE_UI);
163
162 base::SequencedWorkerPool::EnableWithRedirectionToTaskSchedulerForProcess(); 164 base::SequencedWorkerPool::EnableWithRedirectionToTaskSchedulerForProcess();
163 165
164 mojo::edk::Init(); 166 mojo::edk::Init();
165 167
166 base::Thread ipc_thread("IPC thread"); 168 base::Thread ipc_thread("IPC thread");
167 ipc_thread.StartWithOptions( 169 ipc_thread.StartWithOptions(
168 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); 170 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
169 mojo::edk::ScopedIPCSupport ipc_support( 171 mojo::edk::ScopedIPCSupport ipc_support(
170 ipc_thread.task_runner(), 172 ipc_thread.task_runner(),
171 mojo::edk::ScopedIPCSupport::ShutdownPolicy::FAST); 173 mojo::edk::ScopedIPCSupport::ShutdownPolicy::FAST);
172 174
173 int exit_value = RunServiceManagerInMain(); 175 int exit_value = RunServiceManagerInMain();
174 176
175 ipc_thread.Stop(); 177 ipc_thread.Stop();
176 base::TaskScheduler::GetInstance()->Shutdown(); 178 base::TaskScheduler::GetInstance()->Shutdown();
177 return exit_value; 179 return exit_value;
178 } 180 }
179 181
180 int MashRunner::RunServiceManagerInMain() { 182 int MashRunner::RunServiceManagerInMain() {
181 // TODO(sky): refactor BackgroundServiceManager so can supply own context, we 183 // TODO(sky): refactor BackgroundServiceManager so can supply own context, we
182 // shouldn't we using context as it has a lot of stuff we don't really want 184 // shouldn't we using context as it has a lot of stuff we don't really want
183 // in chrome. 185 // in chrome.
184 ServiceProcessLauncherDelegateImpl service_process_launcher_delegate; 186 ServiceProcessLauncherDelegateImpl service_process_launcher_delegate;
185 service_manager::BackgroundServiceManager background_service_manager( 187 service_manager::BackgroundServiceManager background_service_manager(
186 &service_process_launcher_delegate, CreateChromeMashCatalog()); 188 &service_process_launcher_delegate, CreateChromeMashCatalog());
187 service_manager::mojom::ServicePtr service; 189 service_manager::mojom::ServicePtr service;
188 context_.reset(new service_manager::ServiceContext( 190 service_manager::ServiceContext context(
189 base::MakeUnique<mash::MashPackagedService>(), 191 base::MakeUnique<mash::MashPackagedService>(),
190 service_manager::mojom::ServiceRequest(&service))); 192 service_manager::mojom::ServiceRequest(&service));
191 background_service_manager.RegisterService( 193 background_service_manager.RegisterService(
192 service_manager::Identity( 194 service_manager::Identity(
193 kChromeMashServiceName, service_manager::mojom::kRootUserID), 195 kChromeMashServiceName, service_manager::mojom::kRootUserID),
194 std::move(service), nullptr); 196 std::move(service), nullptr);
195 197
196 // Quit the main process if an important child (e.g. window manager) dies. 198 // Quit the main process if an important child (e.g. window manager) dies.
197 // On Chrome OS the OS-level session_manager will restart the main process. 199 // On Chrome OS the OS-level session_manager will restart the main process.
198 base::RunLoop run_loop; 200 base::RunLoop run_loop;
199 int exit_value = 0; 201 int exit_value = 0;
200 background_service_manager.SetInstanceQuitCallback( 202 background_service_manager.SetInstanceQuitCallback(
201 base::Bind(&OnInstanceQuitInMain, &run_loop, &exit_value)); 203 base::Bind(&OnInstanceQuitInMain, &run_loop, &exit_value));
202 204
203 // Ping services that we know we want to launch on startup (UI service, 205 // Ping services that we know we want to launch on startup (UI service,
204 // window manager, quick launch app). 206 // window manager, quick launch app).
205 context_->connector()->Connect(ui::mojom::kServiceName); 207 context.connector()->Connect(ui::mojom::kServiceName);
206 context_->connector()->Connect(mash::common::GetWindowManagerServiceName()); 208 context.connector()->Connect(mash::common::GetWindowManagerServiceName());
207 context_->connector()->Connect(mash::quick_launch::mojom::kServiceName); 209 context.connector()->Connect(mash::quick_launch::mojom::kServiceName);
208 210
209 run_loop.Run(); 211 run_loop.Run();
210 212
211 context_.reset(); 213 // |context| must be destroyed before the message loop.
212 return exit_value; 214 return exit_value;
213 } 215 }
214 216
215 int MashRunner::RunChild() { 217 int MashRunner::RunChild() {
216 service_manager::WaitForDebuggerIfNecessary(); 218 service_manager::WaitForDebuggerIfNecessary();
217 219
218 base::i18n::InitializeICU(); 220 base::i18n::InitializeICU();
219 InitializeResources(); 221 InitializeResources();
220 service_manager::RunStandaloneService( 222 service_manager::RunStandaloneService(
221 base::Bind(&MashRunner::StartChildApp, base::Unretained(this))); 223 base::Bind(&MashRunner::StartChildApp, base::Unretained(this)));
222 return 0; 224 return 0;
223 } 225 }
224 226
225 void MashRunner::StartChildApp( 227 void MashRunner::StartChildApp(
226 service_manager::mojom::ServiceRequest service_request) { 228 service_manager::mojom::ServiceRequest service_request) {
227 // TODO(sad): Normally, this would be a TYPE_DEFAULT message loop. However, 229 // TODO(sad): Normally, this would be a TYPE_DEFAULT message loop. However,
228 // TYPE_UI is needed for mojo:ui. But it is not known whether the child app is 230 // TYPE_UI is needed for mojo:ui. But it is not known whether the child app is
229 // going to be mojo:ui at this point. So always create a TYPE_UI message loop 231 // going to be mojo:ui at this point. So always create a TYPE_UI message loop
230 // for now. 232 // for now.
231 base::MessageLoop message_loop(base::MessageLoop::TYPE_UI); 233 base::MessageLoop message_loop(base::MessageLoop::TYPE_UI);
232 base::RunLoop run_loop; 234 base::RunLoop run_loop;
233 context_.reset(new service_manager::ServiceContext( 235 service_manager::ServiceContext context(
234 base::MakeUnique<mash::MashPackagedService>(), 236 base::MakeUnique<mash::MashPackagedService>(),
235 std::move(service_request))); 237 std::move(service_request));
236 // Quit the child process if it loses its connection to service manager. 238 // Quit the child process if it loses its connection to service manager.
237 context_->SetConnectionLostClosure(run_loop.QuitClosure()); 239 context.SetConnectionLostClosure(run_loop.QuitClosure());
238 run_loop.Run(); 240 run_loop.Run();
241 // |context| must be destroyed before |message_loop|.
239 } 242 }
240 243
241 int MashMain() { 244 int MashMain() {
242 #if !defined(OFFICIAL_BUILD) && defined(OS_WIN) 245 #if !defined(OFFICIAL_BUILD) && defined(OS_WIN)
243 base::RouteStdioToConsole(false); 246 base::RouteStdioToConsole(false);
244 #endif 247 #endif
245 // TODO(sky): wire this up correctly. 248 // TODO(sky): wire this up correctly.
246 service_manager::InitializeLogging(); 249 service_manager::InitializeLogging();
247 250
248 #if defined(OS_LINUX) 251 #if defined(OS_LINUX)
249 base::AtExitManager exit_manager; 252 base::AtExitManager exit_manager;
250 #endif 253 #endif
251 254
252 #if !defined(OFFICIAL_BUILD) 255 #if !defined(OFFICIAL_BUILD)
253 // Initialize stack dumping before initializing sandbox to make sure symbol 256 // Initialize stack dumping before initializing sandbox to make sure symbol
254 // names in all loaded libraries will be cached. 257 // names in all loaded libraries will be cached.
255 // NOTE: On Chrome OS, crash reporting for the root process and non-browser 258 // NOTE: On Chrome OS, crash reporting for the root process and non-browser
256 // service processes is handled by the OS-level crash_reporter. 259 // service processes is handled by the OS-level crash_reporter.
257 base::debug::EnableInProcessStackDumping(); 260 base::debug::EnableInProcessStackDumping();
258 #endif 261 #endif
259 262
260 std::unique_ptr<base::MessageLoop> message_loop;
261 if (!IsChild())
262 message_loop.reset(new base::MessageLoop(base::MessageLoop::TYPE_UI));
263
264 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 263 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
265 switches::kTraceToConsole)) { 264 switches::kTraceToConsole)) {
266 base::trace_event::TraceConfig trace_config = 265 base::trace_event::TraceConfig trace_config =
267 tracing::GetConfigForTraceToConsole(); 266 tracing::GetConfigForTraceToConsole();
268 base::trace_event::TraceLog::GetInstance()->SetEnabled( 267 base::trace_event::TraceLog::GetInstance()->SetEnabled(
269 trace_config, 268 trace_config,
270 base::trace_event::TraceLog::RECORDING_MODE); 269 base::trace_event::TraceLog::RECORDING_MODE);
271 } 270 }
272 271
273 MashRunner mash_runner; 272 MashRunner mash_runner;
(...skipping 12 matching lines...) Expand all
286 command_line->GetSwitchValueASCII(switches::kWaitForDebugger)) { 285 command_line->GetSwitchValueASCII(switches::kWaitForDebugger)) {
287 return; 286 return;
288 } 287 }
289 288
290 // Include the pid as logging may not have been initialized yet (the pid 289 // Include the pid as logging may not have been initialized yet (the pid
291 // printed out by logging is wrong). 290 // printed out by logging is wrong).
292 LOG(WARNING) << "waiting for debugger to attach for service " << service_name 291 LOG(WARNING) << "waiting for debugger to attach for service " << service_name
293 << " pid=" << base::Process::Current().Pid(); 292 << " pid=" << base::Process::Current().Pid();
294 base::debug::WaitForDebugger(120, true); 293 base::debug::WaitForDebugger(120, true);
295 } 294 }
OLDNEW
« no previous file with comments | « chrome/app/mash/mash_runner.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698