Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(315)

Side by Side Diff: content/browser/browser_thread_impl.cc

Issue 2558943002: Explicitly make BrowserThread::SetDelegate specific to the IO thread. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/io_thread.cc ('k') | content/public/browser/browser_thread.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_thread_impl.h" 5 #include "content/browser/browser_thread_impl.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <string> 9 #include <string>
10 10
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 new BrowserThreadTaskRunner(static_cast<BrowserThread::ID>(i)); 92 new BrowserThreadTaskRunner(static_cast<BrowserThread::ID>(i));
93 } 93 }
94 } 94 }
95 95
96 scoped_refptr<base::SingleThreadTaskRunner> proxies[BrowserThread::ID_COUNT]; 96 scoped_refptr<base::SingleThreadTaskRunner> proxies[BrowserThread::ID_COUNT];
97 }; 97 };
98 98
99 base::LazyInstance<BrowserThreadTaskRunners>::Leaky g_task_runners = 99 base::LazyInstance<BrowserThreadTaskRunners>::Leaky g_task_runners =
100 LAZY_INSTANCE_INITIALIZER; 100 LAZY_INSTANCE_INITIALIZER;
101 101
102 using BrowserThreadDelegateAtomicPtr = base::subtle::AtomicWord;
103
102 struct BrowserThreadGlobals { 104 struct BrowserThreadGlobals {
103 BrowserThreadGlobals() 105 BrowserThreadGlobals()
104 : blocking_pool( 106 : blocking_pool(
105 new base::SequencedWorkerPool(3, 107 new base::SequencedWorkerPool(3,
106 "BrowserBlocking", 108 "BrowserBlocking",
107 base::TaskPriority::USER_VISIBLE)) { 109 base::TaskPriority::USER_VISIBLE)) {
108 memset(threads, 0, BrowserThread::ID_COUNT * sizeof(threads[0])); 110 memset(threads, 0, BrowserThread::ID_COUNT * sizeof(threads[0]));
109 memset(thread_ids, 0, BrowserThread::ID_COUNT * sizeof(thread_ids[0])); 111 memset(thread_ids, 0, BrowserThread::ID_COUNT * sizeof(thread_ids[0]));
110 memset(thread_delegates, 0,
111 BrowserThread::ID_COUNT * sizeof(thread_delegates[0]));
112 } 112 }
113 113
114 // This lock protects |threads| and |thread_ids|. Do not read or modify those 114 // This lock protects |threads| and |thread_ids|. Do not read or modify those
115 // arrays without holding this lock. Do not block while holding this lock. 115 // arrays without holding this lock. Do not block while holding this lock.
116 base::Lock lock; 116 base::Lock lock;
117 117
118 // This array is protected by |lock|. IDs in this array are populated as soon 118 // This array is protected by |lock|. IDs in this array are populated as soon
119 // as their respective thread is started and are never reset. 119 // as their respective thread is started and are never reset.
120 base::PlatformThreadId thread_ids[BrowserThread::ID_COUNT]; 120 base::PlatformThreadId thread_ids[BrowserThread::ID_COUNT];
121 121
122 // This array is protected by |lock|. The threads are not owned by this 122 // This array is protected by |lock|. The threads are not owned by this
123 // array. Typically, the threads are owned on the UI thread by 123 // array. Typically, the threads are owned on the UI thread by
124 // BrowserMainLoop. BrowserThreadImpl objects remove themselves from this 124 // BrowserMainLoop. BrowserThreadImpl objects remove themselves from this
125 // array upon destruction. 125 // array upon destruction.
126 BrowserThreadImpl* threads[BrowserThread::ID_COUNT]; 126 BrowserThreadImpl* threads[BrowserThread::ID_COUNT];
127 127
128 // Only atomic operations are used on this array. The delegates are not owned 128 // Only atomic operations are used on this pointer. The delegate isn't owned
129 // by this array, rather by whoever calls BrowserThread::SetDelegate. 129 // by BrowserThreadGlobals, rather by whoever calls
130 BrowserThreadDelegate* thread_delegates[BrowserThread::ID_COUNT]; 130 // BrowserThread::SetIOThreadDelegate.
131 BrowserThreadDelegateAtomicPtr io_thread_delegate = 0;
131 132
132 const scoped_refptr<base::SequencedWorkerPool> blocking_pool; 133 const scoped_refptr<base::SequencedWorkerPool> blocking_pool;
133 }; 134 };
134 135
135 base::LazyInstance<BrowserThreadGlobals>::Leaky 136 base::LazyInstance<BrowserThreadGlobals>::Leaky
136 g_globals = LAZY_INSTANCE_INITIALIZER; 137 g_globals = LAZY_INSTANCE_INITIALIZER;
137 138
138 } // namespace 139 } // namespace
139 140
140 BrowserThreadImpl::BrowserThreadImpl(ID identifier) 141 BrowserThreadImpl::BrowserThreadImpl(ID identifier)
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 // We don't want to create a pool if none exists. 179 // We don't want to create a pool if none exists.
179 if (g_globals == nullptr) 180 if (g_globals == nullptr)
180 return; 181 return;
181 g_globals.Get().blocking_pool->FlushForTesting(); 182 g_globals.Get().blocking_pool->FlushForTesting();
182 disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting(); 183 disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting();
183 } 184 }
184 185
185 void BrowserThreadImpl::Init() { 186 void BrowserThreadImpl::Init() {
186 BrowserThreadGlobals& globals = g_globals.Get(); 187 BrowserThreadGlobals& globals = g_globals.Get();
187 188
188 if (BrowserThread::CurrentlyOn(BrowserThread::DB) || 189 if (identifier_ == BrowserThread::DB ||
189 BrowserThread::CurrentlyOn(BrowserThread::FILE) || 190 identifier_ == BrowserThread::FILE ||
190 BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING) || 191 identifier_ == BrowserThread::FILE_USER_BLOCKING ||
191 BrowserThread::CurrentlyOn(BrowserThread::PROCESS_LAUNCHER) || 192 identifier_ == BrowserThread::PROCESS_LAUNCHER ||
192 BrowserThread::CurrentlyOn(BrowserThread::CACHE)) { 193 identifier_ == BrowserThread::CACHE) {
193 base::MessageLoop* message_loop = base::MessageLoop::current(); 194 base::MessageLoop* message_loop = base::MessageLoop::current();
194 message_loop->DisallowNesting(); 195 message_loop->DisallowNesting();
195 message_loop->DisallowTaskObservers(); 196 message_loop->DisallowTaskObservers();
196 } 197 }
197 198
198 using base::subtle::AtomicWord; 199 if (identifier_ == BrowserThread::IO) {
199 AtomicWord* storage = 200 BrowserThreadDelegateAtomicPtr delegate =
200 reinterpret_cast<AtomicWord*>(&globals.thread_delegates[identifier_]); 201 base::subtle::NoBarrier_Load(&globals.io_thread_delegate);
201 AtomicWord stored_pointer = base::subtle::NoBarrier_Load(storage); 202 if (delegate)
202 BrowserThreadDelegate* delegate = 203 reinterpret_cast<BrowserThreadDelegate*>(delegate)->Init();
203 reinterpret_cast<BrowserThreadDelegate*>(stored_pointer); 204 }
204 if (delegate)
205 delegate->Init();
206 } 205 }
207 206
208 // We disable optimizations for this block of functions so the compiler doesn't 207 // We disable optimizations for this block of functions so the compiler doesn't
209 // merge them all together. 208 // merge them all together.
210 MSVC_DISABLE_OPTIMIZE() 209 MSVC_DISABLE_OPTIMIZE()
211 MSVC_PUSH_DISABLE_WARNING(4748) 210 MSVC_PUSH_DISABLE_WARNING(4748)
212 211
213 NOINLINE void BrowserThreadImpl::UIThreadRun(base::RunLoop* run_loop) { 212 NOINLINE void BrowserThreadImpl::UIThreadRun(base::RunLoop* run_loop) {
214 volatile int line_number = __LINE__; 213 volatile int line_number = __LINE__;
215 Thread::Run(run_loop); 214 Thread::Run(run_loop);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 } 291 }
293 292
294 // |identifier_| must be set to a valid enum value in the constructor, so it 293 // |identifier_| must be set to a valid enum value in the constructor, so it
295 // should be impossible to reach here. 294 // should be impossible to reach here.
296 CHECK(false); 295 CHECK(false);
297 } 296 }
298 297
299 void BrowserThreadImpl::CleanUp() { 298 void BrowserThreadImpl::CleanUp() {
300 BrowserThreadGlobals& globals = g_globals.Get(); 299 BrowserThreadGlobals& globals = g_globals.Get();
301 300
302 using base::subtle::AtomicWord; 301 if (identifier_ == BrowserThread::IO) {
303 AtomicWord* storage = 302 BrowserThreadDelegateAtomicPtr delegate =
304 reinterpret_cast<AtomicWord*>(&globals.thread_delegates[identifier_]); 303 base::subtle::NoBarrier_Load(&globals.io_thread_delegate);
305 AtomicWord stored_pointer = base::subtle::NoBarrier_Load(storage); 304 if (delegate)
306 BrowserThreadDelegate* delegate = 305 reinterpret_cast<BrowserThreadDelegate*>(delegate)->CleanUp();
307 reinterpret_cast<BrowserThreadDelegate*>(stored_pointer); 306 }
308
309 if (delegate)
310 delegate->CleanUp();
311 307
312 // PostTaskHelper() accesses the message loop while holding this lock. 308 // PostTaskHelper() accesses the message loop while holding this lock.
313 // However, the message loop will soon be destructed without any locking. So 309 // However, the message loop will soon be destructed without any locking. So
314 // to prevent a race with accessing the message loop in PostTaskHelper(), 310 // to prevent a race with accessing the message loop in PostTaskHelper(),
315 // remove this thread from the global array now. 311 // remove this thread from the global array now.
316 base::AutoLock lock(globals.lock); 312 base::AutoLock lock(globals.lock);
317 globals.threads[identifier_] = nullptr; 313 globals.threads[identifier_] = nullptr;
318 } 314 }
319 315
320 void BrowserThreadImpl::Initialize() { 316 void BrowserThreadImpl::Initialize() {
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 560
565 return false; 561 return false;
566 } 562 }
567 563
568 // static 564 // static
569 scoped_refptr<base::SingleThreadTaskRunner> 565 scoped_refptr<base::SingleThreadTaskRunner>
570 BrowserThread::GetTaskRunnerForThread(ID identifier) { 566 BrowserThread::GetTaskRunnerForThread(ID identifier) {
571 return g_task_runners.Get().proxies[identifier]; 567 return g_task_runners.Get().proxies[identifier];
572 } 568 }
573 569
574 void BrowserThread::SetDelegate(ID identifier, 570 // static
575 BrowserThreadDelegate* delegate) { 571 void BrowserThread::SetIOThreadDelegate(BrowserThreadDelegate* delegate) {
576 using base::subtle::AtomicWord;
577 BrowserThreadGlobals& globals = g_globals.Get(); 572 BrowserThreadGlobals& globals = g_globals.Get();
578 AtomicWord* storage = reinterpret_cast<AtomicWord*>( 573 BrowserThreadDelegateAtomicPtr old_delegate =
579 &globals.thread_delegates[identifier]); 574 base::subtle::NoBarrier_AtomicExchange(
580 AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( 575 &globals.io_thread_delegate,
581 storage, reinterpret_cast<AtomicWord>(delegate)); 576 reinterpret_cast<BrowserThreadDelegateAtomicPtr>(delegate));
582 577
583 // This catches registration when previously registered. 578 // This catches registration when previously registered.
584 DCHECK(!delegate || !old_pointer); 579 DCHECK(!delegate || !old_delegate);
585 } 580 }
586 581
587 } // namespace content 582 } // namespace content
OLDNEW
« no previous file with comments | « chrome/browser/io_thread.cc ('k') | content/public/browser/browser_thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698