Index: content/browser/browser_main_loop.cc |
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc |
index 90454164084436f1e10429069274f170ef439b03..18d08bc79ccd896a019696c80012920116052305 100644 |
--- a/content/browser/browser_main_loop.cc |
+++ b/content/browser/browser_main_loop.cc |
@@ -227,6 +227,38 @@ void BrowserMainLoop::EarlyInitialization() { |
} |
void BrowserMainLoop::MainMessageLoopStart() { |
+ base::Thread::Options io_message_loop_options; |
+ io_message_loop_options.message_loop_type = MessageLoop::TYPE_IO; |
+ base::Thread::Options ui_message_loop_options; |
+ ui_message_loop_options.message_loop_type = MessageLoop::TYPE_UI; |
+ |
+ db_thread_.reset(new BrowserProcessSubThread(BrowserThread::DB)); |
+ db_thread_->Start(); |
+ |
+ file_thread_.reset(new BrowserProcessSubThread(BrowserThread::FILE)); |
+#if defined(OS_WIN) |
+ // On Windows, the FILE thread needs to be have a UI message loop |
+ // 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
|
+ // communicate back to us. |
+ file_thread_->StartWithOptions(ui_message_loop_options); |
+#else |
+ file_thread_->StartWithOptions(io_message_loop_options); |
+#endif |
+ |
+ process_launcher_thread_.reset( |
+ new BrowserProcessSubThread(BrowserThread::PROCESS_LAUNCHER)); |
+ process_launcher_thread_->Start(); |
+ |
+ cache_thread_.reset(new BrowserProcessSubThread(BrowserThread::CACHE)); |
+ cache_thread_->StartWithOptions(io_message_loop_options); |
+ io_thread_.reset(new BrowserProcessSubThread(BrowserThread::IO)); |
+ io_thread_->StartWithOptions(io_message_loop_options); |
+#if defined(OS_CHROMEOS) |
+ web_socket_proxy_thread_.reset( |
+ new BrowserProcessSubThread(BrowserThread::WEB_SOCKET_PROXY)); |
+ web_socket_proxy_thread_->StartWithOptions(io_message_loop_options); |
+#endif |
+ |
for (size_t i = 0; i < parts_list_.size(); ++i) |
parts_list_[i]->PreMainMessageLoopStart(); |
@@ -286,6 +318,78 @@ void BrowserMainLoop::RunMainMessageLoopParts( |
for (size_t i = 0; i < parts_list_.size(); ++i) |
parts_list_[i]->PostMainMessageLoopRun(); |
+ |
+ // Must be size_t so we can subtract from it. |
+ for (size_t thread_id = BrowserThread::ID_COUNT - 1; |
+ thread_id >= BrowserThread::DB; |
+ --thread_id) { |
+ // Find the thread object we want to stop. Looping over all valid |
+ // BrowserThread IDs and DCHECKing on a missing case in the switch |
+ // statement helps avoid a mismatch between this code and the |
+ // BrowserThread::ID enumeration. |
+ // |
+ // The destruction order is the reverse order of occurrence in the |
+ // BrowserThread::ID list. The rationale for the order is as |
+ // follows (need to be filled in a bit): |
+ // |
+ // - (Not sure why the WEB_SOCKET_PROXY thread is stopped first.) |
+ // |
+ // - The IO thread is the only user of the CACHE thread. |
+ // |
+ // - The PROCESS_LAUNCHER thread must be stopped after IO in case |
+ // the IO thread posted a task to terminate a process on the |
+ // process launcher thread. |
+ // |
+ // - (Not sure why FILE needs to stop before WEBKIT.) |
+ // |
+ // - The WEBKIT thread (which currently is the responsibility of |
+ // the embedder to stop, by destroying ResourceDispatcherHost |
+ // before the DB thread is stopped) |
+ // |
+ // - (Not sure why DB stops last.) |
+ scoped_ptr<BrowserProcessSubThread>* thread_to_stop = NULL; |
+ switch (thread_id) { |
+ case BrowserThread::UI: |
+ case BrowserThread::ID_COUNT: |
+ NOTREACHED(); |
+ break; |
+ case BrowserThread::DB: |
+ thread_to_stop = &db_thread_; |
+ break; |
+ case BrowserThread::WEBKIT: |
+ // For now, the WebKit thread in the browser is owned by |
+ // ResourceDispatcherHost, not by the content framework. Until |
+ // this is fixed, we don't stop the thread but still call |
+ // Pre/PostStopThread for the ID. |
+ break; |
+ case BrowserThread::FILE: |
+ thread_to_stop = &file_thread_; |
+ break; |
+ case BrowserThread::PROCESS_LAUNCHER: |
+ thread_to_stop = &process_launcher_thread_; |
+ break; |
+ case BrowserThread::CACHE: |
+ thread_to_stop = &cache_thread_; |
+ break; |
+ case BrowserThread::IO: |
+ thread_to_stop = &io_thread_; |
+ break; |
+#if defined(OS_CHROMEOS) |
+ case BrowserThread::WEB_SOCKET_PROXY: |
+ thread_to_stop = &web_socket_proxy_thread_; |
+ break; |
+#endif |
+ } |
+ |
+ BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id); |
+ |
+ for (size_t i = 0; i < parts_list_.size(); ++i) |
+ parts_list_[i]->PreStopThread(id); |
+ if (thread_to_stop) |
+ thread_to_stop->reset(); |
+ for (size_t i = 0; i < parts_list_.size(); ++i) |
+ parts_list_[i]->PostStopThread(id); |
+ } |
} |
void BrowserMainLoop::InitializeMainThread() { |