summaryrefslogtreecommitdiff
path: root/chromium/content/browser/browser_process_sub_thread.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/browser_process_sub_thread.cc')
-rw-r--r--chromium/content/browser/browser_process_sub_thread.cc138
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.