OLD | NEW |
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> | 7 #include <string> |
8 | 8 |
9 #include "base/atomicops.h" | 9 #include "base/atomicops.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 message_loop->PostNonNestableDelayedTask(from_here, task, delay); | 168 message_loop->PostNonNestableDelayedTask(from_here, task, delay); |
169 } | 169 } |
170 } | 170 } |
171 | 171 |
172 if (!guaranteed_to_outlive_target_thread) | 172 if (!guaranteed_to_outlive_target_thread) |
173 globals.lock.Release(); | 173 globals.lock.Release(); |
174 | 174 |
175 return !!message_loop; | 175 return !!message_loop; |
176 } | 176 } |
177 | 177 |
178 // An implementation of MessageLoopProxy to be used in conjunction | |
179 // with BrowserThread. | |
180 class BrowserThreadMessageLoopProxy : public base::MessageLoopProxy { | |
181 public: | |
182 explicit BrowserThreadMessageLoopProxy(BrowserThread::ID identifier) | |
183 : id_(identifier) { | |
184 } | |
185 | |
186 // MessageLoopProxy implementation. | |
187 virtual bool PostDelayedTask( | |
188 const tracked_objects::Location& from_here, | |
189 const base::Closure& task, int64 delay_ms) OVERRIDE { | |
190 return BrowserThread::PostDelayedTask(id_, from_here, task, delay_ms); | |
191 } | |
192 virtual bool PostDelayedTask( | |
193 const tracked_objects::Location& from_here, | |
194 const base::Closure& task, base::TimeDelta delay) OVERRIDE { | |
195 return BrowserThread::PostDelayedTask(id_, from_here, task, delay); | |
196 } | |
197 | |
198 virtual bool PostNonNestableDelayedTask( | |
199 const tracked_objects::Location& from_here, | |
200 const base::Closure& task, | |
201 int64 delay_ms) OVERRIDE { | |
202 return BrowserThread::PostNonNestableDelayedTask(id_, from_here, task, | |
203 delay_ms); | |
204 } | |
205 virtual bool PostNonNestableDelayedTask( | |
206 const tracked_objects::Location& from_here, | |
207 const base::Closure& task, | |
208 base::TimeDelta delay) OVERRIDE { | |
209 return BrowserThread::PostNonNestableDelayedTask(id_, from_here, task, | |
210 delay); | |
211 } | |
212 | |
213 virtual bool RunsTasksOnCurrentThread() const OVERRIDE { | |
214 return BrowserThread::CurrentlyOn(id_); | |
215 } | |
216 | |
217 protected: | |
218 virtual ~BrowserThreadMessageLoopProxy() {} | |
219 | |
220 private: | |
221 BrowserThread::ID id_; | |
222 DISALLOW_COPY_AND_ASSIGN(BrowserThreadMessageLoopProxy); | |
223 }; | |
224 | |
225 // static | 178 // static |
226 bool BrowserThread::PostBlockingPoolTask( | 179 bool BrowserThread::PostBlockingPoolTask( |
227 const tracked_objects::Location& from_here, | 180 const tracked_objects::Location& from_here, |
228 const base::Closure& task) { | 181 const base::Closure& task) { |
229 return g_globals.Get().blocking_pool->PostWorkerTask(from_here, task); | 182 return g_globals.Get().blocking_pool->PostWorkerTask(from_here, task); |
230 } | 183 } |
231 | 184 |
232 bool BrowserThread::PostBlockingPoolTaskAndReply( | 185 bool BrowserThread::PostBlockingPoolTaskAndReply( |
233 const tracked_objects::Location& from_here, | 186 const tracked_objects::Location& from_here, |
234 const base::Closure& task, | 187 const base::Closure& task, |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 return true; | 335 return true; |
383 } | 336 } |
384 } | 337 } |
385 | 338 |
386 return false; | 339 return false; |
387 } | 340 } |
388 | 341 |
389 // static | 342 // static |
390 scoped_refptr<base::MessageLoopProxy> | 343 scoped_refptr<base::MessageLoopProxy> |
391 BrowserThread::GetMessageLoopProxyForThread(ID identifier) { | 344 BrowserThread::GetMessageLoopProxyForThread(ID identifier) { |
392 scoped_refptr<base::MessageLoopProxy> proxy( | 345 if (g_globals == NULL) |
393 new BrowserThreadMessageLoopProxy(identifier)); | 346 return NULL; |
394 return proxy; | 347 |
| 348 BrowserThread::ID current_thread; |
| 349 bool guaranteed_to_outlive_target_thread = |
| 350 GetCurrentThreadIdentifier(¤t_thread) && |
| 351 current_thread <= identifier; |
| 352 |
| 353 BrowserThreadGlobals& globals = g_globals.Get(); |
| 354 if (!guaranteed_to_outlive_target_thread) |
| 355 globals.lock.Acquire(); |
| 356 |
| 357 base::Thread* thread = globals.threads[identifier]; |
| 358 if (!thread) { |
| 359 if (!guaranteed_to_outlive_target_thread) |
| 360 globals.lock.Release(); |
| 361 return NULL; |
| 362 } |
| 363 scoped_refptr<base::MessageLoopProxy> loop = thread->message_loop_proxy(); |
| 364 |
| 365 if (!guaranteed_to_outlive_target_thread) |
| 366 globals.lock.Release(); |
| 367 |
| 368 return loop; |
395 } | 369 } |
396 | 370 |
397 // static | 371 // static |
398 MessageLoop* BrowserThread::UnsafeGetMessageLoopForThread(ID identifier) { | 372 MessageLoop* BrowserThread::UnsafeGetMessageLoopForThread(ID identifier) { |
399 if (g_globals == NULL) | 373 if (g_globals == NULL) |
400 return NULL; | 374 return NULL; |
401 | 375 |
402 BrowserThreadGlobals& globals = g_globals.Get(); | 376 BrowserThreadGlobals& globals = g_globals.Get(); |
403 base::AutoLock lock(globals.lock); | 377 base::AutoLock lock(globals.lock); |
404 base::Thread* thread = globals.threads[identifier]; | 378 base::Thread* thread = globals.threads[identifier]; |
(...skipping 10 matching lines...) Expand all Loading... |
415 AtomicWord* storage = reinterpret_cast<AtomicWord*>( | 389 AtomicWord* storage = reinterpret_cast<AtomicWord*>( |
416 &globals.thread_delegates[identifier]); | 390 &globals.thread_delegates[identifier]); |
417 AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( | 391 AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( |
418 storage, reinterpret_cast<AtomicWord>(delegate)); | 392 storage, reinterpret_cast<AtomicWord>(delegate)); |
419 | 393 |
420 // This catches registration when previously registered. | 394 // This catches registration when previously registered. |
421 DCHECK(!delegate || !old_pointer); | 395 DCHECK(!delegate || !old_pointer); |
422 } | 396 } |
423 | 397 |
424 } // namespace content | 398 } // namespace content |
OLD | NEW |