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

Side by Side Diff: content/browser/browser_main_loop.cc

Issue 8477004: Have content/ create and destroy its own threads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: With this patchset, Chrome runs and exits normally on Linux. Created 9 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/browser/browser_main_loop.h" 5 #include "content/browser/browser_main_loop.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 hi_res_timer_manager_.reset(new HighResolutionTimerManager); 255 hi_res_timer_manager_.reset(new HighResolutionTimerManager);
256 256
257 network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); 257 network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
258 258
259 for (size_t i = 0; i < parts_list_.size(); ++i) 259 for (size_t i = 0; i < parts_list_.size(); ++i)
260 parts_list_[i]->PostMainMessageLoopStart(); 260 parts_list_[i]->PostMainMessageLoopStart();
261 } 261 }
262 262
263 void BrowserMainLoop::RunMainMessageLoopParts( 263 void BrowserMainLoop::RunMainMessageLoopParts(
264 bool* completed_main_message_loop) { 264 bool* completed_main_message_loop) {
265 IOThreadDelegate* io_thread_delegate = NULL;
266 for (size_t i = 0; i < parts_list_.size(); ++i) {
267 IOThreadDelegate* current_delegate =
268 parts_list_[i]->PreMainMessageLoopRun();
269 if (current_delegate) {
270 DCHECK(!io_thread_delegate) << "Only one delegate allowed.";
271 io_thread_delegate = current_delegate;
272 }
273 }
274
275 base::Thread::Options io_message_loop_options;
276 io_message_loop_options.message_loop_type = MessageLoop::TYPE_IO;
277 base::Thread::Options ui_message_loop_options;
278 ui_message_loop_options.message_loop_type = MessageLoop::TYPE_UI;
279
280 db_thread_.reset(new BrowserProcessSubThread(BrowserThread::DB));
281 db_thread_->Start();
282
283 file_thread_.reset(new BrowserProcessSubThread(BrowserThread::FILE));
284 #if defined(OS_WIN)
285 // On Windows, the FILE thread needs to be have a UI message loop
286 // which pumps messages in such a way that Google Update can
287 // communicate back to us.
288 file_thread_->StartWithOptions(ui_message_loop_options);
289 #else
290 file_thread_->StartWithOptions(io_message_loop_options);
291 #endif
292
293 process_launcher_thread_.reset(
294 new BrowserProcessSubThread(BrowserThread::PROCESS_LAUNCHER));
295 process_launcher_thread_->Start();
296
297 cache_thread_.reset(new BrowserProcessSubThread(BrowserThread::CACHE));
298 cache_thread_->StartWithOptions(io_message_loop_options);
299 io_thread_.reset(new BrowserProcessIOThread(io_thread_delegate));
300 io_thread_->StartWithOptions(io_message_loop_options);
301 #if defined(OS_CHROMEOS)
302 web_socket_proxy_thread_.reset(
303 new BrowserProcessSubThread(BrowserThread::WEB_SOCKET_PROXY));
304 web_socket_proxy_thread_->StartWithOptions(io_message_loop_options);
305 #endif
306
265 for (size_t i = 0; i < parts_list_.size(); ++i) 307 for (size_t i = 0; i < parts_list_.size(); ++i)
266 parts_list_[i]->PreMainMessageLoopRun(); 308 parts_list_[i]->PreMainMessageLoopRunThreadsCreated();
267 309
268 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); 310 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
269 // If the UI thread blocks, the whole UI is unresponsive. 311 // If the UI thread blocks, the whole UI is unresponsive.
270 // Do not allow disk IO from the UI thread. 312 // Do not allow disk IO from the UI thread.
271 base::ThreadRestrictions::SetIOAllowed(false); 313 base::ThreadRestrictions::SetIOAllowed(false);
272 314
273 // Iterate through each of the parts. If any of them ran the main 315 // Iterate through each of the parts. If any of them ran the main
274 // message loop then they should return |true|. Otherwise 316 // message loop then they should return |true|. Otherwise
275 // BrowserMainLoop::MainMessageLoopRun loop will be run. 317 // BrowserMainLoop::MainMessageLoopRun loop will be run.
276 bool ran_main_loop = false; 318 bool ran_main_loop = false;
277 for (size_t i = 0; i < parts_list_.size(); ++i) { 319 for (size_t i = 0; i < parts_list_.size(); ++i) {
278 int result_code = result_code_; 320 int result_code = result_code_;
279 if (parts_list_[i]->MainMessageLoopRun(&result_code)) { 321 if (parts_list_[i]->MainMessageLoopRun(&result_code)) {
280 ran_main_loop = true; 322 ran_main_loop = true;
281 result_code_ = result_code; 323 result_code_ = result_code;
282 } 324 }
283 } 325 }
284 if (!ran_main_loop) 326 if (!ran_main_loop)
285 MainMessageLoopRun(); 327 MainMessageLoopRun();
286 328
287 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); 329 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
288 330
289 if (completed_main_message_loop) 331 if (completed_main_message_loop)
290 *completed_main_message_loop = true; 332 *completed_main_message_loop = true;
291 333
334 // Teardown may start in PostMainMessageLoopRun, and during teardown we
335 // need to be able to perform IO.
336 base::ThreadRestrictions::SetIOAllowed(true);
337 BrowserThread::PostTask(
338 BrowserThread::IO,
339 FROM_HERE,
340 NewRunnableFunction(&base::ThreadRestrictions::SetIOAllowed, true));
341
292 for (size_t i = 0; i < parts_list_.size(); ++i) 342 for (size_t i = 0; i < parts_list_.size(); ++i)
293 parts_list_[i]->PostMainMessageLoopRun(); 343 parts_list_[i]->PostMainMessageLoopRun();
344
345 // Must be size_t so we can subtract from it.
346 for (size_t thread_id = BrowserThread::ID_COUNT - 1;
347 thread_id >= BrowserThread::DB;
348 --thread_id) {
349 // Find the thread object we want to stop. Looping over all valid
350 // BrowserThread IDs and DCHECKing on a missing case in the switch
351 // statement helps avoid a mismatch between this code and the
352 // BrowserThread::ID enumeration.
353 //
354 // The destruction order is the reverse order of occurrence in the
355 // BrowserThread::ID list. The rationale for the order is as
356 // follows (need to be filled in a bit):
357 //
358 // - (Not sure why the WEB_SOCKET_PROXY thread is stopped first.)
359 //
360 // - The IO thread is the only user of the CACHE thread.
361 //
362 // - The PROCESS_LAUNCHER thread must be stopped after IO in case
363 // the IO thread posted a task to terminate a process on the
364 // process launcher thread.
365 //
366 // - (Not sure why FILE needs to stop before WEBKIT.)
367 //
368 // - The WEBKIT thread (which currently is the responsibility of
369 // the embedder to stop, by destroying ResourceDispatcherHost
370 // before the DB thread is stopped)
371 //
372 // - (Not sure why DB stops last.)
373 scoped_ptr<BrowserProcessSubThread>* thread_to_stop = NULL;
374 switch (thread_id) {
375 case BrowserThread::UI:
376 case BrowserThread::ID_COUNT:
377 NOTREACHED();
378 break;
379 case BrowserThread::DB:
380 thread_to_stop = &db_thread_;
381 break;
382 case BrowserThread::WEBKIT:
383 // For now, the WebKit thread in the browser is owned by
384 // ResourceDispatcherHost, not by the content framework. Until
385 // this is fixed, we don't stop the thread but still call
386 // Pre/PostStopThread for the ID.
387 break;
388 case BrowserThread::FILE:
389 thread_to_stop = &file_thread_;
390 break;
391 case BrowserThread::PROCESS_LAUNCHER:
392 thread_to_stop = &process_launcher_thread_;
393 break;
394 case BrowserThread::CACHE:
395 thread_to_stop = &cache_thread_;
396 break;
397 case BrowserThread::IO:
398 thread_to_stop = &io_thread_;
399 break;
400 #if defined(OS_CHROMEOS)
401 case BrowserThread::WEB_SOCKET_PROXY:
402 thread_to_stop = &web_socket_proxy_thread_;
403 break;
404 #endif
405 }
406
407 BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id);
408
409 for (size_t i = 0; i < parts_list_.size(); ++i)
410 parts_list_[i]->PreStopThread(id);
411 if (thread_to_stop)
412 thread_to_stop->reset();
413 for (size_t i = 0; i < parts_list_.size(); ++i)
414 parts_list_[i]->PostStopThread(id);
415 }
416
417 for (size_t i = 0; i < parts_list_.size(); ++i)
418 parts_list_[i]->FinalCleanup();
294 } 419 }
295 420
296 void BrowserMainLoop::InitializeMainThread() { 421 void BrowserMainLoop::InitializeMainThread() {
297 const char* kThreadName = "CrBrowserMain"; 422 const char* kThreadName = "CrBrowserMain";
298 base::PlatformThread::SetName(kThreadName); 423 base::PlatformThread::SetName(kThreadName);
299 main_message_loop_->set_thread_name(kThreadName); 424 main_message_loop_->set_thread_name(kThreadName);
300 tracked_objects::ThreadData::InitializeThreadContext(kThreadName); 425 tracked_objects::ThreadData::InitializeThreadContext(kThreadName);
301 426
302 // Register the main thread by instantiating it, but don't call any methods. 427 // Register the main thread by instantiating it, but don't call any methods.
303 main_thread_.reset(new BrowserThreadImpl(BrowserThread::UI, 428 main_thread_.reset(new BrowserThreadImpl(BrowserThread::UI,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 MessageLoopForUI::current()->PostTask(FROM_HERE, parameters_.ui_task); 474 MessageLoopForUI::current()->PostTask(FROM_HERE, parameters_.ui_task);
350 475
351 #if defined(OS_MACOSX) 476 #if defined(OS_MACOSX)
352 MessageLoopForUI::current()->Run(); 477 MessageLoopForUI::current()->Run();
353 #else 478 #else
354 MessageLoopForUI::current()->RunWithDispatcher(NULL); 479 MessageLoopForUI::current()->RunWithDispatcher(NULL);
355 #endif 480 #endif
356 } 481 }
357 482
358 } // namespace content 483 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698