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.h> | 7 #include <string.h> |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 | 52 |
53 // An implementation of SingleThreadTaskRunner to be used in conjunction | 53 // An implementation of SingleThreadTaskRunner to be used in conjunction |
54 // with BrowserThread. | 54 // with BrowserThread. |
55 class BrowserThreadTaskRunner : public base::SingleThreadTaskRunner { | 55 class BrowserThreadTaskRunner : public base::SingleThreadTaskRunner { |
56 public: | 56 public: |
57 explicit BrowserThreadTaskRunner(BrowserThread::ID identifier) | 57 explicit BrowserThreadTaskRunner(BrowserThread::ID identifier) |
58 : id_(identifier) {} | 58 : id_(identifier) {} |
59 | 59 |
60 // SingleThreadTaskRunner implementation. | 60 // SingleThreadTaskRunner implementation. |
61 bool PostDelayedTask(const tracked_objects::Location& from_here, | 61 bool PostDelayedTask(const tracked_objects::Location& from_here, |
62 const base::Closure& task, | 62 base::OnceClosure task, |
63 base::TimeDelta delay) override { | 63 base::TimeDelta delay) override { |
64 return BrowserThread::PostDelayedTask(id_, from_here, task, delay); | 64 return BrowserThread::PostDelayedTask(id_, from_here, std::move(task), |
| 65 delay); |
65 } | 66 } |
66 | 67 |
67 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, | 68 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, |
68 const base::Closure& task, | 69 base::OnceClosure task, |
69 base::TimeDelta delay) override { | 70 base::TimeDelta delay) override { |
70 return BrowserThread::PostNonNestableDelayedTask(id_, from_here, task, | 71 return BrowserThread::PostNonNestableDelayedTask(id_, from_here, |
71 delay); | 72 std::move(task), delay); |
72 } | 73 } |
73 | 74 |
74 bool RunsTasksOnCurrentThread() const override { | 75 bool RunsTasksOnCurrentThread() const override { |
75 return BrowserThread::CurrentlyOn(id_); | 76 return BrowserThread::CurrentlyOn(id_); |
76 } | 77 } |
77 | 78 |
78 protected: | 79 protected: |
79 ~BrowserThreadTaskRunner() override {} | 80 ~BrowserThreadTaskRunner() override {} |
80 | 81 |
81 private: | 82 private: |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 bool BrowserThreadImpl::StartAndWaitForTesting() { | 355 bool BrowserThreadImpl::StartAndWaitForTesting() { |
355 if (!Start()) | 356 if (!Start()) |
356 return false; | 357 return false; |
357 WaitUntilThreadStarted(); | 358 WaitUntilThreadStarted(); |
358 return true; | 359 return true; |
359 } | 360 } |
360 // static | 361 // static |
361 bool BrowserThreadImpl::PostTaskHelper( | 362 bool BrowserThreadImpl::PostTaskHelper( |
362 BrowserThread::ID identifier, | 363 BrowserThread::ID identifier, |
363 const tracked_objects::Location& from_here, | 364 const tracked_objects::Location& from_here, |
364 const base::Closure& task, | 365 base::OnceClosure task, |
365 base::TimeDelta delay, | 366 base::TimeDelta delay, |
366 bool nestable) { | 367 bool nestable) { |
367 DCHECK_GE(identifier, 0); | 368 DCHECK_GE(identifier, 0); |
368 DCHECK_LT(identifier, ID_COUNT); | 369 DCHECK_LT(identifier, ID_COUNT); |
369 // Optimization: to avoid unnecessary locks, we listed the ID enumeration in | 370 // Optimization: to avoid unnecessary locks, we listed the ID enumeration in |
370 // order of lifetime. So no need to lock if we know that the target thread | 371 // order of lifetime. So no need to lock if we know that the target thread |
371 // outlives current thread. | 372 // outlives current thread. |
372 // Note: since the array is so small, ok to loop instead of creating a map, | 373 // Note: since the array is so small, ok to loop instead of creating a map, |
373 // which would require a lock because std::map isn't thread safe, defeating | 374 // which would require a lock because std::map isn't thread safe, defeating |
374 // the whole purpose of this optimization. | 375 // the whole purpose of this optimization. |
375 BrowserThread::ID current_thread = ID_COUNT; | 376 BrowserThread::ID current_thread = ID_COUNT; |
376 bool target_thread_outlives_current = | 377 bool target_thread_outlives_current = |
377 GetCurrentThreadIdentifier(¤t_thread) && | 378 GetCurrentThreadIdentifier(¤t_thread) && |
378 current_thread >= identifier; | 379 current_thread >= identifier; |
379 | 380 |
380 BrowserThreadGlobals& globals = g_globals.Get(); | 381 BrowserThreadGlobals& globals = g_globals.Get(); |
381 if (!target_thread_outlives_current) | 382 if (!target_thread_outlives_current) |
382 globals.lock.Acquire(); | 383 globals.lock.Acquire(); |
383 | 384 |
384 base::MessageLoop* message_loop = | 385 base::MessageLoop* message_loop = |
385 globals.threads[identifier] ? globals.threads[identifier]->message_loop() | 386 globals.threads[identifier] ? globals.threads[identifier]->message_loop() |
386 : nullptr; | 387 : nullptr; |
387 if (message_loop) { | 388 if (message_loop) { |
388 if (nestable) { | 389 if (nestable) { |
389 message_loop->task_runner()->PostDelayedTask(from_here, task, delay); | 390 message_loop->task_runner()->PostDelayedTask(from_here, std::move(task), |
| 391 delay); |
390 } else { | 392 } else { |
391 message_loop->task_runner()->PostNonNestableDelayedTask(from_here, task, | 393 message_loop->task_runner()->PostNonNestableDelayedTask( |
392 delay); | 394 from_here, std::move(task), delay); |
393 } | 395 } |
394 } | 396 } |
395 | 397 |
396 if (!target_thread_outlives_current) | 398 if (!target_thread_outlives_current) |
397 globals.lock.Release(); | 399 globals.lock.Release(); |
398 | 400 |
399 return !!message_loop; | 401 return !!message_loop; |
400 } | 402 } |
401 | 403 |
402 // static | 404 // static |
403 bool BrowserThread::PostBlockingPoolTask( | 405 bool BrowserThread::PostBlockingPoolTask( |
404 const tracked_objects::Location& from_here, | 406 const tracked_objects::Location& from_here, |
405 const base::Closure& task) { | 407 base::OnceClosure task) { |
406 return g_globals.Get().blocking_pool->PostWorkerTask(from_here, task); | 408 return g_globals.Get().blocking_pool->PostWorkerTask(from_here, |
| 409 std::move(task)); |
407 } | 410 } |
408 | 411 |
409 // static | 412 // static |
410 bool BrowserThread::PostBlockingPoolTaskAndReply( | 413 bool BrowserThread::PostBlockingPoolTaskAndReply( |
411 const tracked_objects::Location& from_here, | 414 const tracked_objects::Location& from_here, |
412 const base::Closure& task, | 415 base::OnceClosure task, |
413 const base::Closure& reply) { | 416 base::OnceClosure reply) { |
414 return g_globals.Get().blocking_pool->PostTaskAndReply( | 417 return g_globals.Get().blocking_pool->PostTaskAndReply( |
415 from_here, task, reply); | 418 from_here, std::move(task), std::move(reply)); |
416 } | 419 } |
417 | 420 |
418 // static | 421 // static |
419 bool BrowserThread::PostBlockingPoolSequencedTask( | 422 bool BrowserThread::PostBlockingPoolSequencedTask( |
420 const std::string& sequence_token_name, | 423 const std::string& sequence_token_name, |
421 const tracked_objects::Location& from_here, | 424 const tracked_objects::Location& from_here, |
422 const base::Closure& task) { | 425 base::OnceClosure task) { |
423 return g_globals.Get().blocking_pool->PostNamedSequencedWorkerTask( | 426 return g_globals.Get().blocking_pool->PostNamedSequencedWorkerTask( |
424 sequence_token_name, from_here, task); | 427 sequence_token_name, from_here, std::move(task)); |
425 } | 428 } |
426 | 429 |
427 // static | 430 // static |
428 void BrowserThread::PostAfterStartupTask( | 431 void BrowserThread::PostAfterStartupTask( |
429 const tracked_objects::Location& from_here, | 432 const tracked_objects::Location& from_here, |
430 const scoped_refptr<base::TaskRunner>& task_runner, | 433 const scoped_refptr<base::TaskRunner>& task_runner, |
431 const base::Closure& task) { | 434 base::OnceClosure task) { |
432 GetContentClient()->browser()->PostAfterStartupTask(from_here, task_runner, | 435 GetContentClient()->browser()->PostAfterStartupTask(from_here, task_runner, |
433 task); | 436 std::move(task)); |
434 } | 437 } |
435 | 438 |
436 // static | 439 // static |
437 base::SequencedWorkerPool* BrowserThread::GetBlockingPool() { | 440 base::SequencedWorkerPool* BrowserThread::GetBlockingPool() { |
438 return g_globals.Get().blocking_pool.get(); | 441 return g_globals.Get().blocking_pool.get(); |
439 } | 442 } |
440 | 443 |
441 // static | 444 // static |
442 bool BrowserThread::IsThreadInitialized(ID identifier) { | 445 bool BrowserThread::IsThreadInitialized(ID identifier) { |
443 if (g_globals == nullptr) | 446 if (g_globals == nullptr) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 base::AutoLock lock(globals.lock); | 485 base::AutoLock lock(globals.lock); |
483 DCHECK_GE(identifier, 0); | 486 DCHECK_GE(identifier, 0); |
484 DCHECK_LT(identifier, ID_COUNT); | 487 DCHECK_LT(identifier, ID_COUNT); |
485 return globals.threads[identifier] && | 488 return globals.threads[identifier] && |
486 globals.threads[identifier]->message_loop(); | 489 globals.threads[identifier]->message_loop(); |
487 } | 490 } |
488 | 491 |
489 // static | 492 // static |
490 bool BrowserThread::PostTask(ID identifier, | 493 bool BrowserThread::PostTask(ID identifier, |
491 const tracked_objects::Location& from_here, | 494 const tracked_objects::Location& from_here, |
492 const base::Closure& task) { | 495 base::OnceClosure task) { |
493 return BrowserThreadImpl::PostTaskHelper( | 496 return BrowserThreadImpl::PostTaskHelper( |
494 identifier, from_here, task, base::TimeDelta(), true); | 497 identifier, from_here, std::move(task), base::TimeDelta(), true); |
495 } | 498 } |
496 | 499 |
497 // static | 500 // static |
498 bool BrowserThread::PostDelayedTask(ID identifier, | 501 bool BrowserThread::PostDelayedTask(ID identifier, |
499 const tracked_objects::Location& from_here, | 502 const tracked_objects::Location& from_here, |
500 const base::Closure& task, | 503 base::OnceClosure task, |
501 base::TimeDelta delay) { | 504 base::TimeDelta delay) { |
502 return BrowserThreadImpl::PostTaskHelper( | 505 return BrowserThreadImpl::PostTaskHelper(identifier, from_here, |
503 identifier, from_here, task, delay, true); | 506 std::move(task), delay, true); |
504 } | 507 } |
505 | 508 |
506 // static | 509 // static |
507 bool BrowserThread::PostNonNestableTask( | 510 bool BrowserThread::PostNonNestableTask( |
508 ID identifier, | 511 ID identifier, |
509 const tracked_objects::Location& from_here, | 512 const tracked_objects::Location& from_here, |
510 const base::Closure& task) { | 513 base::OnceClosure task) { |
511 return BrowserThreadImpl::PostTaskHelper( | 514 return BrowserThreadImpl::PostTaskHelper( |
512 identifier, from_here, task, base::TimeDelta(), false); | 515 identifier, from_here, std::move(task), base::TimeDelta(), false); |
513 } | 516 } |
514 | 517 |
515 // static | 518 // static |
516 bool BrowserThread::PostNonNestableDelayedTask( | 519 bool BrowserThread::PostNonNestableDelayedTask( |
517 ID identifier, | 520 ID identifier, |
518 const tracked_objects::Location& from_here, | 521 const tracked_objects::Location& from_here, |
519 const base::Closure& task, | 522 base::OnceClosure task, |
520 base::TimeDelta delay) { | 523 base::TimeDelta delay) { |
521 return BrowserThreadImpl::PostTaskHelper( | 524 return BrowserThreadImpl::PostTaskHelper(identifier, from_here, |
522 identifier, from_here, task, delay, false); | 525 std::move(task), delay, false); |
523 } | 526 } |
524 | 527 |
525 // static | 528 // static |
526 bool BrowserThread::PostTaskAndReply( | 529 bool BrowserThread::PostTaskAndReply(ID identifier, |
527 ID identifier, | 530 const tracked_objects::Location& from_here, |
528 const tracked_objects::Location& from_here, | 531 base::OnceClosure task, |
529 const base::Closure& task, | 532 base::OnceClosure reply) { |
530 const base::Closure& reply) { | |
531 return GetTaskRunnerForThread(identifier) | 533 return GetTaskRunnerForThread(identifier) |
532 ->PostTaskAndReply(from_here, task, reply); | 534 ->PostTaskAndReply(from_here, std::move(task), std::move(reply)); |
533 } | 535 } |
534 | 536 |
535 // static | 537 // static |
536 bool BrowserThread::GetCurrentThreadIdentifier(ID* identifier) { | 538 bool BrowserThread::GetCurrentThreadIdentifier(ID* identifier) { |
537 if (g_globals == nullptr) | 539 if (g_globals == nullptr) |
538 return false; | 540 return false; |
539 | 541 |
540 base::MessageLoop* cur_message_loop = base::MessageLoop::current(); | 542 base::MessageLoop* cur_message_loop = base::MessageLoop::current(); |
541 BrowserThreadGlobals& globals = g_globals.Get(); | 543 BrowserThreadGlobals& globals = g_globals.Get(); |
542 // Profiler to track potential contention on |globals.lock|. This only does | 544 // Profiler to track potential contention on |globals.lock|. This only does |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 AtomicWord* storage = reinterpret_cast<AtomicWord*>( | 584 AtomicWord* storage = reinterpret_cast<AtomicWord*>( |
583 &globals.thread_delegates[identifier]); | 585 &globals.thread_delegates[identifier]); |
584 AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( | 586 AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( |
585 storage, reinterpret_cast<AtomicWord>(delegate)); | 587 storage, reinterpret_cast<AtomicWord>(delegate)); |
586 | 588 |
587 // This catches registration when previously registered. | 589 // This catches registration when previously registered. |
588 DCHECK(!delegate || !old_pointer); | 590 DCHECK(!delegate || !old_pointer); |
589 } | 591 } |
590 | 592 |
591 } // namespace content | 593 } // namespace content |
OLD | NEW |