OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |