1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/public/test/test_browser_thread_bundle.h" 6 7#include "base/message_loop/message_loop.h" 8#include "base/run_loop.h" 9#include "content/browser/browser_thread_impl.h" 10#include "content/public/test/test_browser_thread.h" 11 12namespace content { 13 14TestBrowserThreadBundle::TestBrowserThreadBundle() { 15 Init(DEFAULT); 16} 17 18TestBrowserThreadBundle::TestBrowserThreadBundle(int options) { 19 Init(options); 20} 21 22TestBrowserThreadBundle::~TestBrowserThreadBundle() { 23 // To avoid memory leaks, we must ensure that any tasks posted to the blocking 24 // pool via PostTaskAndReply are able to reply back to the originating thread. 25 // Thus we must flush the blocking pool while the browser threads still exist. 26 base::RunLoop().RunUntilIdle(); 27 BrowserThreadImpl::FlushThreadPoolHelper(); 28 29 // To ensure a clean teardown, each thread's message loop must be flushed 30 // just before the thread is destroyed. But destroying a fake thread does not 31 // automatically flush the message loop, so we have to do it manually. 32 // See http://crbug.com/247525 for discussion. 33 base::RunLoop().RunUntilIdle(); 34 io_thread_.reset(); 35 base::RunLoop().RunUntilIdle(); 36 cache_thread_.reset(); 37 base::RunLoop().RunUntilIdle(); 38 process_launcher_thread_.reset(); 39 base::RunLoop().RunUntilIdle(); 40 file_user_blocking_thread_.reset(); 41 base::RunLoop().RunUntilIdle(); 42 file_thread_.reset(); 43 base::RunLoop().RunUntilIdle(); 44 db_thread_.reset(); 45 base::RunLoop().RunUntilIdle(); 46 // This is the point at which we normally shut down the thread pool. So flush 47 // it again in case any shutdown tasks have been posted to the pool from the 48 // threads above. 49 BrowserThreadImpl::FlushThreadPoolHelper(); 50 base::RunLoop().RunUntilIdle(); 51 ui_thread_.reset(); 52 base::RunLoop().RunUntilIdle(); 53} 54 55void TestBrowserThreadBundle::Init(int options) { 56 if (options & IO_MAINLOOP) { 57 message_loop_.reset(new base::MessageLoopForIO()); 58 } else { 59 message_loop_.reset(new base::MessageLoopForUI()); 60 } 61 62 ui_thread_.reset(new TestBrowserThread(BrowserThread::UI, 63 message_loop_.get())); 64 65 if (options & REAL_DB_THREAD) { 66 db_thread_.reset(new TestBrowserThread(BrowserThread::DB)); 67 db_thread_->Start(); 68 } else { 69 db_thread_.reset(new TestBrowserThread(BrowserThread::DB, 70 message_loop_.get())); 71 } 72 73 if (options & REAL_FILE_THREAD) { 74 file_thread_.reset(new TestBrowserThread(BrowserThread::FILE)); 75 file_thread_->Start(); 76 } else { 77 file_thread_.reset(new TestBrowserThread(BrowserThread::FILE, 78 message_loop_.get())); 79 } 80 81 if (options & REAL_FILE_USER_BLOCKING_THREAD) { 82 file_user_blocking_thread_.reset( 83 new TestBrowserThread(BrowserThread::FILE_USER_BLOCKING)); 84 file_user_blocking_thread_->Start(); 85 } else { 86 file_user_blocking_thread_.reset( 87 new TestBrowserThread(BrowserThread::FILE_USER_BLOCKING, 88 message_loop_.get())); 89 } 90 91 if (options & REAL_PROCESS_LAUNCHER_THREAD) { 92 process_launcher_thread_.reset( 93 new TestBrowserThread(BrowserThread::PROCESS_LAUNCHER)); 94 process_launcher_thread_->Start(); 95 } else { 96 process_launcher_thread_.reset( 97 new TestBrowserThread(BrowserThread::PROCESS_LAUNCHER, 98 message_loop_.get())); 99 } 100 101 if (options & REAL_CACHE_THREAD) { 102 cache_thread_.reset(new TestBrowserThread(BrowserThread::CACHE)); 103 cache_thread_->Start(); 104 } else { 105 cache_thread_.reset(new TestBrowserThread(BrowserThread::CACHE, 106 message_loop_.get())); 107 } 108 109 if (options & REAL_IO_THREAD) { 110 io_thread_.reset(new TestBrowserThread(BrowserThread::IO)); 111 io_thread_->StartIOThread(); 112 } else { 113 io_thread_.reset( 114 new TestBrowserThread(BrowserThread::IO, message_loop_.get())); 115 } 116} 117 118} // namespace content 119