diff options
Diffstat (limited to 'chromium/content/browser/browser_process_sub_thread.cc')
-rw-r--r-- | chromium/content/browser/browser_process_sub_thread.cc | 138 |
1 files changed, 118 insertions, 20 deletions
diff --git a/chromium/content/browser/browser_process_sub_thread.cc b/chromium/content/browser/browser_process_sub_thread.cc index 71f1396dbde..0902fb6bfd0 100644 --- a/chromium/content/browser/browser_process_sub_thread.cc +++ b/chromium/content/browser/browser_process_sub_thread.cc @@ -4,57 +4,121 @@ #include "content/browser/browser_process_sub_thread.h" -#include "base/debug/leak_tracker.h" +#include "base/compiler_specific.h" +#include "base/debug/alias.h" #include "base/threading/thread_restrictions.h" #include "base/trace_event/memory_dump_manager.h" -#include "build/build_config.h" #include "content/browser/browser_child_process_host_impl.h" +#include "content/browser/browser_thread_impl.h" #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h" #include "content/browser/notification_service_impl.h" +#include "content/public/browser/browser_thread_delegate.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request.h" +#if defined(OS_ANDROID) +#include "base/android/jni_android.h" +#endif + #if defined(OS_WIN) #include "base/win/scoped_com_initializer.h" #endif namespace content { -BrowserProcessSubThread::BrowserProcessSubThread(BrowserThread::ID identifier) - : BrowserThreadImpl(identifier) {} +namespace { +BrowserThreadDelegate* g_io_thread_delegate = nullptr; +} // namespace -BrowserProcessSubThread::BrowserProcessSubThread( - BrowserThread::ID identifier, - base::MessageLoop* message_loop) - : BrowserThreadImpl(identifier, message_loop) {} +// static +void BrowserThread::SetIOThreadDelegate(BrowserThreadDelegate* delegate) { + // |delegate| can only be set/unset while BrowserThread::IO isn't up. + DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::IO)); + // and it cannot be set twice. + DCHECK(!g_io_thread_delegate || !delegate); + + g_io_thread_delegate = delegate; +} + +BrowserProcessSubThread::BrowserProcessSubThread(BrowserThread::ID identifier) + : base::Thread(BrowserThreadImpl::GetThreadName(identifier)), + identifier_(identifier) { + // Not bound to creation thread. + DETACH_FROM_THREAD(browser_thread_checker_); +} BrowserProcessSubThread::~BrowserProcessSubThread() { Stop(); } +void BrowserProcessSubThread::RegisterAsBrowserThread() { + DCHECK(IsRunning()); + + DCHECK(!browser_thread_); + browser_thread_.reset(new BrowserThreadImpl(identifier_, task_runner())); + + // Unretained(this) is safe as |this| outlives its underlying thread. + task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + &BrowserProcessSubThread::CompleteInitializationOnBrowserThread, + Unretained(this))); +} + +void BrowserProcessSubThread::AllowBlockingForTesting() { + DCHECK(!IsRunning()); + is_blocking_allowed_for_testing_ = true; +} + void BrowserProcessSubThread::Init() { + DCHECK_CALLED_ON_VALID_THREAD(browser_thread_checker_); + #if defined(OS_WIN) - com_initializer_.reset(new base::win::ScopedCOMInitializer()); + com_initializer_ = std::make_unique<base::win::ScopedCOMInitializer>(); #endif - notification_service_.reset(new NotificationServiceImpl()); + if (!is_blocking_allowed_for_testing_) { + base::DisallowBlocking(); + base::DisallowBaseSyncPrimitives(); + } +} - BrowserThreadImpl::Init(); +void BrowserProcessSubThread::Run(base::RunLoop* run_loop) { + DCHECK_CALLED_ON_VALID_THREAD(browser_thread_checker_); - if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { - // Though this thread is called the "IO" thread, it actually just routes - // messages around; it shouldn't be allowed to perform any blocking disk - // I/O. - base::ThreadRestrictions::SetIOAllowed(false); - base::ThreadRestrictions::DisallowWaiting(); +#if defined(OS_ANDROID) + // Not to reset thread name to "Thread-???" by VM, attach VM with thread name. + // Though it may create unnecessary VM thread objects, keeping thread name + // gives more benefit in debugging in the platform. + if (!thread_name().empty()) { + base::android::AttachCurrentThreadWithName(thread_name()); + } +#endif + + switch (identifier_) { + case BrowserThread::UI: + // The main thread is usually promoted as the UI thread and doesn't go + // through Run() but some tests do run a separate UI thread. + UIThreadRun(run_loop); + break; + case BrowserThread::IO: + IOThreadRun(run_loop); + return; + case BrowserThread::ID_COUNT: + NOTREACHED(); + break; } } void BrowserProcessSubThread::CleanUp() { + DCHECK_CALLED_ON_VALID_THREAD(browser_thread_checker_); + + // Run extra cleanup if this thread represents BrowserThread::IO. if (BrowserThread::CurrentlyOn(BrowserThread::IO)) - IOThreadPreCleanUp(); + IOThreadCleanUp(); - BrowserThreadImpl::CleanUp(); + if (identifier_ == BrowserThread::IO && g_io_thread_delegate) + g_io_thread_delegate->CleanUp(); notification_service_.reset(); @@ -63,7 +127,41 @@ void BrowserProcessSubThread::CleanUp() { #endif } -void BrowserProcessSubThread::IOThreadPreCleanUp() { +void BrowserProcessSubThread::CompleteInitializationOnBrowserThread() { + DCHECK_CALLED_ON_VALID_THREAD(browser_thread_checker_); + + notification_service_ = std::make_unique<NotificationServiceImpl>(); + + if (identifier_ == BrowserThread::IO && g_io_thread_delegate) { + // Allow blocking calls while initializing the IO thread. + base::ScopedAllowBlocking allow_blocking_for_init; + g_io_thread_delegate->Init(); + } +} + +// We disable optimizations for Run specifications so the compiler doesn't merge +// them all together. +MSVC_DISABLE_OPTIMIZE() +MSVC_PUSH_DISABLE_WARNING(4748) + +NOINLINE void BrowserProcessSubThread::UIThreadRun(base::RunLoop* run_loop) { + const int line_number = __LINE__; + Thread::Run(run_loop); + base::debug::Alias(&line_number); +} + +NOINLINE void BrowserProcessSubThread::IOThreadRun(base::RunLoop* run_loop) { + const int line_number = __LINE__; + Thread::Run(run_loop); + base::debug::Alias(&line_number); +} + +MSVC_POP_WARNING() +MSVC_ENABLE_OPTIMIZE(); + +void BrowserProcessSubThread::IOThreadCleanUp() { + DCHECK_CALLED_ON_VALID_THREAD(browser_thread_checker_); + // Kill all things that might be holding onto // net::URLRequest/net::URLRequestContexts. |