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 |