Chromium Code Reviews| 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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 220 // TODO(abarth): Should this move to InitializeNetworkOptions? This doesn't | 220 // TODO(abarth): Should this move to InitializeNetworkOptions? This doesn't |
| 221 // seem dependent on SSL initialization(). | 221 // seem dependent on SSL initialization(). |
| 222 if (parsed_command_line_.HasSwitch(switches::kEnableTcpFastOpen)) | 222 if (parsed_command_line_.HasSwitch(switches::kEnableTcpFastOpen)) |
| 223 net::set_tcp_fastopen_enabled(true); | 223 net::set_tcp_fastopen_enabled(true); |
| 224 | 224 |
| 225 for (size_t i = 0; i < parts_list_.size(); ++i) | 225 for (size_t i = 0; i < parts_list_.size(); ++i) |
| 226 parts_list_[i]->PostEarlyInitialization(); | 226 parts_list_[i]->PostEarlyInitialization(); |
| 227 } | 227 } |
| 228 | 228 |
| 229 void BrowserMainLoop::MainMessageLoopStart() { | 229 void BrowserMainLoop::MainMessageLoopStart() { |
| 230 base::Thread::Options io_message_loop_options; | |
| 231 io_message_loop_options.message_loop_type = MessageLoop::TYPE_IO; | |
| 232 base::Thread::Options ui_message_loop_options; | |
| 233 ui_message_loop_options.message_loop_type = MessageLoop::TYPE_UI; | |
| 234 | |
| 235 db_thread_.reset(new BrowserProcessSubThread(BrowserThread::DB)); | |
| 236 db_thread_->Start(); | |
| 237 | |
| 238 file_thread_.reset(new BrowserProcessSubThread(BrowserThread::FILE)); | |
| 239 #if defined(OS_WIN) | |
| 240 // On Windows, the FILE thread needs to be have a UI message loop | |
| 241 // which pumps messages in such a way that Google Update can | |
|
jam
2011/11/07 21:43:24
nit: we should avoid talking about Google Update i
Jói
2011/11/18 23:21:44
In general I agree with this principle. In this s
| |
| 242 // communicate back to us. | |
| 243 file_thread_->StartWithOptions(ui_message_loop_options); | |
| 244 #else | |
| 245 file_thread_->StartWithOptions(io_message_loop_options); | |
| 246 #endif | |
| 247 | |
| 248 process_launcher_thread_.reset( | |
| 249 new BrowserProcessSubThread(BrowserThread::PROCESS_LAUNCHER)); | |
| 250 process_launcher_thread_->Start(); | |
| 251 | |
| 252 cache_thread_.reset(new BrowserProcessSubThread(BrowserThread::CACHE)); | |
| 253 cache_thread_->StartWithOptions(io_message_loop_options); | |
| 254 io_thread_.reset(new BrowserProcessSubThread(BrowserThread::IO)); | |
| 255 io_thread_->StartWithOptions(io_message_loop_options); | |
| 256 #if defined(OS_CHROMEOS) | |
| 257 web_socket_proxy_thread_.reset( | |
| 258 new BrowserProcessSubThread(BrowserThread::WEB_SOCKET_PROXY)); | |
| 259 web_socket_proxy_thread_->StartWithOptions(io_message_loop_options); | |
| 260 #endif | |
| 261 | |
| 230 for (size_t i = 0; i < parts_list_.size(); ++i) | 262 for (size_t i = 0; i < parts_list_.size(); ++i) |
| 231 parts_list_[i]->PreMainMessageLoopStart(); | 263 parts_list_[i]->PreMainMessageLoopStart(); |
| 232 | 264 |
| 233 #if defined(OS_WIN) | 265 #if defined(OS_WIN) |
| 234 // If we're running tests (ui_task is non-null), then the ResourceBundle | 266 // If we're running tests (ui_task is non-null), then the ResourceBundle |
| 235 // has already been initialized. | 267 // has already been initialized. |
| 236 if (!parameters_.ui_task) { | 268 if (!parameters_.ui_task) { |
| 237 // Override the configured locale with the user's preferred UI language. | 269 // Override the configured locale with the user's preferred UI language. |
| 238 l10n_util::OverrideLocaleWithUILanguageList(); | 270 l10n_util::OverrideLocaleWithUILanguageList(); |
| 239 } | 271 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 279 if (!ran_main_loop) | 311 if (!ran_main_loop) |
| 280 MainMessageLoopRun(); | 312 MainMessageLoopRun(); |
| 281 | 313 |
| 282 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); | 314 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, ""); |
| 283 | 315 |
| 284 if (completed_main_message_loop) | 316 if (completed_main_message_loop) |
| 285 *completed_main_message_loop = true; | 317 *completed_main_message_loop = true; |
| 286 | 318 |
| 287 for (size_t i = 0; i < parts_list_.size(); ++i) | 319 for (size_t i = 0; i < parts_list_.size(); ++i) |
| 288 parts_list_[i]->PostMainMessageLoopRun(); | 320 parts_list_[i]->PostMainMessageLoopRun(); |
| 321 | |
| 322 // Must be size_t so we can subtract from it. | |
| 323 for (size_t thread_id = BrowserThread::ID_COUNT - 1; | |
| 324 thread_id >= BrowserThread::DB; | |
| 325 --thread_id) { | |
| 326 // Find the thread object we want to stop. Looping over all valid | |
| 327 // BrowserThread IDs and DCHECKing on a missing case in the switch | |
| 328 // statement helps avoid a mismatch between this code and the | |
| 329 // BrowserThread::ID enumeration. | |
| 330 // | |
| 331 // The destruction order is the reverse order of occurrence in the | |
| 332 // BrowserThread::ID list. The rationale for the order is as | |
| 333 // follows (need to be filled in a bit): | |
| 334 // | |
| 335 // - (Not sure why the WEB_SOCKET_PROXY thread is stopped first.) | |
| 336 // | |
| 337 // - The IO thread is the only user of the CACHE thread. | |
| 338 // | |
| 339 // - The PROCESS_LAUNCHER thread must be stopped after IO in case | |
| 340 // the IO thread posted a task to terminate a process on the | |
| 341 // process launcher thread. | |
| 342 // | |
| 343 // - (Not sure why FILE needs to stop before WEBKIT.) | |
| 344 // | |
| 345 // - The WEBKIT thread (which currently is the responsibility of | |
| 346 // the embedder to stop, by destroying ResourceDispatcherHost | |
| 347 // before the DB thread is stopped) | |
| 348 // | |
| 349 // - (Not sure why DB stops last.) | |
| 350 scoped_ptr<BrowserProcessSubThread>* thread_to_stop = NULL; | |
| 351 switch (thread_id) { | |
| 352 case BrowserThread::UI: | |
| 353 case BrowserThread::ID_COUNT: | |
| 354 NOTREACHED(); | |
| 355 break; | |
| 356 case BrowserThread::DB: | |
| 357 thread_to_stop = &db_thread_; | |
| 358 break; | |
| 359 case BrowserThread::WEBKIT: | |
| 360 // For now, the WebKit thread in the browser is owned by | |
| 361 // ResourceDispatcherHost, not by the content framework. Until | |
| 362 // this is fixed, we don't stop the thread but still call | |
| 363 // Pre/PostStopThread for the ID. | |
| 364 break; | |
| 365 case BrowserThread::FILE: | |
| 366 thread_to_stop = &file_thread_; | |
| 367 break; | |
| 368 case BrowserThread::PROCESS_LAUNCHER: | |
| 369 thread_to_stop = &process_launcher_thread_; | |
| 370 break; | |
| 371 case BrowserThread::CACHE: | |
| 372 thread_to_stop = &cache_thread_; | |
| 373 break; | |
| 374 case BrowserThread::IO: | |
| 375 thread_to_stop = &io_thread_; | |
| 376 break; | |
| 377 #if defined(OS_CHROMEOS) | |
| 378 case BrowserThread::WEB_SOCKET_PROXY: | |
| 379 thread_to_stop = &web_socket_proxy_thread_; | |
| 380 break; | |
| 381 #endif | |
| 382 } | |
| 383 | |
| 384 BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id); | |
| 385 | |
| 386 for (size_t i = 0; i < parts_list_.size(); ++i) | |
| 387 parts_list_[i]->PreStopThread(id); | |
| 388 if (thread_to_stop) | |
| 389 thread_to_stop->reset(); | |
| 390 for (size_t i = 0; i < parts_list_.size(); ++i) | |
| 391 parts_list_[i]->PostStopThread(id); | |
| 392 } | |
| 289 } | 393 } |
| 290 | 394 |
| 291 void BrowserMainLoop::InitializeMainThread() { | 395 void BrowserMainLoop::InitializeMainThread() { |
| 292 const char* kThreadName = "CrBrowserMain"; | 396 const char* kThreadName = "CrBrowserMain"; |
| 293 base::PlatformThread::SetName(kThreadName); | 397 base::PlatformThread::SetName(kThreadName); |
| 294 main_message_loop_->set_thread_name(kThreadName); | 398 main_message_loop_->set_thread_name(kThreadName); |
| 295 tracked_objects::ThreadData::InitializeThreadContext(kThreadName); | 399 tracked_objects::ThreadData::InitializeThreadContext(kThreadName); |
| 296 | 400 |
| 297 // Register the main thread by instantiating it, but don't call any methods. | 401 // Register the main thread by instantiating it, but don't call any methods. |
| 298 main_thread_.reset(new BrowserThreadImpl(BrowserThread::UI, | 402 main_thread_.reset(new BrowserThreadImpl(BrowserThread::UI, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 344 MessageLoopForUI::current()->PostTask(FROM_HERE, parameters_.ui_task); | 448 MessageLoopForUI::current()->PostTask(FROM_HERE, parameters_.ui_task); |
| 345 | 449 |
| 346 #if defined(OS_MACOSX) | 450 #if defined(OS_MACOSX) |
| 347 MessageLoopForUI::current()->Run(); | 451 MessageLoopForUI::current()->Run(); |
| 348 #else | 452 #else |
| 349 MessageLoopForUI::current()->RunWithDispatcher(NULL); | 453 MessageLoopForUI::current()->RunWithDispatcher(NULL); |
| 350 #endif | 454 #endif |
| 351 } | 455 } |
| 352 | 456 |
| 353 } // namespace content | 457 } // namespace content |
| OLD | NEW |