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 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/atomicops.h" | 10 #include "base/atomicops.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 // with BrowserThread. | 55 // with BrowserThread. |
56 // TODO(gab): Consider replacing this with |g_globals->task_runners| -- only | 56 // TODO(gab): Consider replacing this with |g_globals->task_runners| -- only |
57 // works if none are requested before starting the threads. | 57 // works if none are requested before starting the threads. |
58 class BrowserThreadTaskRunner : public base::SingleThreadTaskRunner { | 58 class BrowserThreadTaskRunner : public base::SingleThreadTaskRunner { |
59 public: | 59 public: |
60 explicit BrowserThreadTaskRunner(BrowserThread::ID identifier) | 60 explicit BrowserThreadTaskRunner(BrowserThread::ID identifier) |
61 : id_(identifier) {} | 61 : id_(identifier) {} |
62 | 62 |
63 // SingleThreadTaskRunner implementation. | 63 // SingleThreadTaskRunner implementation. |
64 bool PostDelayedTask(const tracked_objects::Location& from_here, | 64 bool PostDelayedTask(const tracked_objects::Location& from_here, |
65 const base::Closure& task, | 65 base::Closure task, |
66 base::TimeDelta delay) override { | 66 base::TimeDelta delay) override { |
67 return BrowserThread::PostDelayedTask(id_, from_here, task, delay); | 67 return BrowserThread::PostDelayedTask(id_, from_here, std::move(task), |
| 68 delay); |
68 } | 69 } |
69 | 70 |
70 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, | 71 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, |
71 const base::Closure& task, | 72 base::Closure task, |
72 base::TimeDelta delay) override { | 73 base::TimeDelta delay) override { |
73 return BrowserThread::PostNonNestableDelayedTask(id_, from_here, task, | 74 return BrowserThread::PostNonNestableDelayedTask(id_, from_here, |
74 delay); | 75 std::move(task), delay); |
75 } | 76 } |
76 | 77 |
77 bool RunsTasksOnCurrentThread() const override { | 78 bool RunsTasksOnCurrentThread() const override { |
78 return BrowserThread::CurrentlyOn(id_); | 79 return BrowserThread::CurrentlyOn(id_); |
79 } | 80 } |
80 | 81 |
81 protected: | 82 protected: |
82 ~BrowserThreadTaskRunner() override {} | 83 ~BrowserThreadTaskRunner() override {} |
83 | 84 |
84 private: | 85 private: |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 // succeed to post to B. This is pretty much the only observable difference | 483 // succeed to post to B. This is pretty much the only observable difference |
483 // between a redirected thread and a real one and is one we're willing to live | 484 // between a redirected thread and a real one and is one we're willing to live |
484 // with for this experiment. TODO(gab): fix this before enabling the | 485 // with for this experiment. TODO(gab): fix this before enabling the |
485 // experiment by default on trunk, http://crbug.com/653916. | 486 // experiment by default on trunk, http://crbug.com/653916. |
486 } | 487 } |
487 | 488 |
488 // static | 489 // static |
489 bool BrowserThreadImpl::PostTaskHelper( | 490 bool BrowserThreadImpl::PostTaskHelper( |
490 BrowserThread::ID identifier, | 491 BrowserThread::ID identifier, |
491 const tracked_objects::Location& from_here, | 492 const tracked_objects::Location& from_here, |
492 const base::Closure& task, | 493 base::Closure task, |
493 base::TimeDelta delay, | 494 base::TimeDelta delay, |
494 bool nestable) { | 495 bool nestable) { |
495 DCHECK_GE(identifier, 0); | 496 DCHECK_GE(identifier, 0); |
496 DCHECK_LT(identifier, ID_COUNT); | 497 DCHECK_LT(identifier, ID_COUNT); |
497 // Optimization: to avoid unnecessary locks, we listed the ID enumeration in | 498 // Optimization: to avoid unnecessary locks, we listed the ID enumeration in |
498 // order of lifetime. So no need to lock if we know that the target thread | 499 // order of lifetime. So no need to lock if we know that the target thread |
499 // outlives current thread as that implies the current thread only ever sees | 500 // outlives current thread as that implies the current thread only ever sees |
500 // the target thread in its RUNNING state. | 501 // the target thread in its RUNNING state. |
501 // Note: since the array is so small, ok to loop instead of creating a map, | 502 // Note: since the array is so small, ok to loop instead of creating a map, |
502 // which would require a lock because std::map isn't thread safe, defeating | 503 // which would require a lock because std::map isn't thread safe, defeating |
503 // the whole purpose of this optimization. | 504 // the whole purpose of this optimization. |
504 BrowserThread::ID current_thread = ID_COUNT; | 505 BrowserThread::ID current_thread = ID_COUNT; |
505 bool target_thread_outlives_current = | 506 bool target_thread_outlives_current = |
506 GetCurrentThreadIdentifier(¤t_thread) && | 507 GetCurrentThreadIdentifier(¤t_thread) && |
507 current_thread >= identifier; | 508 current_thread >= identifier; |
508 | 509 |
509 BrowserThreadGlobals& globals = g_globals.Get(); | 510 BrowserThreadGlobals& globals = g_globals.Get(); |
510 if (!target_thread_outlives_current) | 511 if (!target_thread_outlives_current) |
511 globals.lock.Acquire(); | 512 globals.lock.Acquire(); |
512 | 513 |
513 const bool accepting_tasks = | 514 const bool accepting_tasks = |
514 globals.states[identifier] == BrowserThreadState::RUNNING; | 515 globals.states[identifier] == BrowserThreadState::RUNNING; |
515 if (accepting_tasks) { | 516 if (accepting_tasks) { |
516 base::SingleThreadTaskRunner* task_runner = | 517 base::SingleThreadTaskRunner* task_runner = |
517 globals.task_runners[identifier].get(); | 518 globals.task_runners[identifier].get(); |
518 DCHECK(task_runner); | 519 DCHECK(task_runner); |
519 if (nestable) { | 520 if (nestable) { |
520 task_runner->PostDelayedTask(from_here, task, delay); | 521 task_runner->PostDelayedTask(from_here, std::move(task), delay); |
521 } else { | 522 } else { |
522 task_runner->PostNonNestableDelayedTask(from_here, task, delay); | 523 task_runner->PostNonNestableDelayedTask(from_here, std::move(task), |
| 524 delay); |
523 } | 525 } |
524 } | 526 } |
525 | 527 |
526 if (!target_thread_outlives_current) | 528 if (!target_thread_outlives_current) |
527 globals.lock.Release(); | 529 globals.lock.Release(); |
528 | 530 |
529 return accepting_tasks; | 531 return accepting_tasks; |
530 } | 532 } |
531 | 533 |
532 // static | 534 // static |
533 bool BrowserThread::PostBlockingPoolTask( | 535 bool BrowserThread::PostBlockingPoolTask( |
534 const tracked_objects::Location& from_here, | 536 const tracked_objects::Location& from_here, |
535 const base::Closure& task) { | 537 base::Closure task) { |
536 return g_globals.Get().blocking_pool->PostWorkerTask(from_here, task); | 538 return g_globals.Get().blocking_pool->PostWorkerTask(from_here, |
| 539 std::move(task)); |
537 } | 540 } |
538 | 541 |
539 // static | 542 // static |
540 bool BrowserThread::PostBlockingPoolTaskAndReply( | 543 bool BrowserThread::PostBlockingPoolTaskAndReply( |
541 const tracked_objects::Location& from_here, | 544 const tracked_objects::Location& from_here, |
542 base::Closure task, | 545 base::Closure task, |
543 base::Closure reply) { | 546 base::Closure reply) { |
544 return g_globals.Get().blocking_pool->PostTaskAndReply( | 547 return g_globals.Get().blocking_pool->PostTaskAndReply( |
545 from_here, std::move(task), std::move(reply)); | 548 from_here, std::move(task), std::move(reply)); |
546 } | 549 } |
547 | 550 |
548 // static | 551 // static |
549 bool BrowserThread::PostBlockingPoolSequencedTask( | 552 bool BrowserThread::PostBlockingPoolSequencedTask( |
550 const std::string& sequence_token_name, | 553 const std::string& sequence_token_name, |
551 const tracked_objects::Location& from_here, | 554 const tracked_objects::Location& from_here, |
552 const base::Closure& task) { | 555 base::Closure task) { |
553 return g_globals.Get().blocking_pool->PostNamedSequencedWorkerTask( | 556 return g_globals.Get().blocking_pool->PostNamedSequencedWorkerTask( |
554 sequence_token_name, from_here, task); | 557 sequence_token_name, from_here, std::move(task)); |
555 } | 558 } |
556 | 559 |
557 // static | 560 // static |
558 void BrowserThread::PostAfterStartupTask( | 561 void BrowserThread::PostAfterStartupTask( |
559 const tracked_objects::Location& from_here, | 562 const tracked_objects::Location& from_here, |
560 const scoped_refptr<base::TaskRunner>& task_runner, | 563 const scoped_refptr<base::TaskRunner>& task_runner, |
561 const base::Closure& task) { | 564 base::Closure task) { |
562 GetContentClient()->browser()->PostAfterStartupTask(from_here, task_runner, | 565 GetContentClient()->browser()->PostAfterStartupTask(from_here, task_runner, |
563 task); | 566 std::move(task)); |
564 } | 567 } |
565 | 568 |
566 // static | 569 // static |
567 base::SequencedWorkerPool* BrowserThread::GetBlockingPool() { | 570 base::SequencedWorkerPool* BrowserThread::GetBlockingPool() { |
568 return g_globals.Get().blocking_pool.get(); | 571 return g_globals.Get().blocking_pool.get(); |
569 } | 572 } |
570 | 573 |
571 // static | 574 // static |
572 bool BrowserThread::IsThreadInitialized(ID identifier) { | 575 bool BrowserThread::IsThreadInitialized(ID identifier) { |
573 if (g_globals == nullptr) | 576 if (g_globals == nullptr) |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 BrowserThreadGlobals& globals = g_globals.Get(); | 616 BrowserThreadGlobals& globals = g_globals.Get(); |
614 base::AutoLock lock(globals.lock); | 617 base::AutoLock lock(globals.lock); |
615 DCHECK_GE(identifier, 0); | 618 DCHECK_GE(identifier, 0); |
616 DCHECK_LT(identifier, ID_COUNT); | 619 DCHECK_LT(identifier, ID_COUNT); |
617 return globals.states[identifier] == BrowserThreadState::RUNNING; | 620 return globals.states[identifier] == BrowserThreadState::RUNNING; |
618 } | 621 } |
619 | 622 |
620 // static | 623 // static |
621 bool BrowserThread::PostTask(ID identifier, | 624 bool BrowserThread::PostTask(ID identifier, |
622 const tracked_objects::Location& from_here, | 625 const tracked_objects::Location& from_here, |
623 const base::Closure& task) { | 626 base::Closure task) { |
624 return BrowserThreadImpl::PostTaskHelper( | 627 return BrowserThreadImpl::PostTaskHelper( |
625 identifier, from_here, task, base::TimeDelta(), true); | 628 identifier, from_here, std::move(task), base::TimeDelta(), true); |
626 } | 629 } |
627 | 630 |
628 // static | 631 // static |
629 bool BrowserThread::PostDelayedTask(ID identifier, | 632 bool BrowserThread::PostDelayedTask(ID identifier, |
630 const tracked_objects::Location& from_here, | 633 const tracked_objects::Location& from_here, |
631 const base::Closure& task, | 634 base::Closure task, |
632 base::TimeDelta delay) { | 635 base::TimeDelta delay) { |
633 return BrowserThreadImpl::PostTaskHelper( | 636 return BrowserThreadImpl::PostTaskHelper(identifier, from_here, |
634 identifier, from_here, task, delay, true); | 637 std::move(task), delay, true); |
635 } | 638 } |
636 | 639 |
637 // static | 640 // static |
638 bool BrowserThread::PostNonNestableTask( | 641 bool BrowserThread::PostNonNestableTask( |
639 ID identifier, | 642 ID identifier, |
640 const tracked_objects::Location& from_here, | 643 const tracked_objects::Location& from_here, |
641 const base::Closure& task) { | 644 base::Closure task) { |
642 return BrowserThreadImpl::PostTaskHelper( | 645 return BrowserThreadImpl::PostTaskHelper( |
643 identifier, from_here, task, base::TimeDelta(), false); | 646 identifier, from_here, std::move(task), base::TimeDelta(), false); |
644 } | 647 } |
645 | 648 |
646 // static | 649 // static |
647 bool BrowserThread::PostNonNestableDelayedTask( | 650 bool BrowserThread::PostNonNestableDelayedTask( |
648 ID identifier, | 651 ID identifier, |
649 const tracked_objects::Location& from_here, | 652 const tracked_objects::Location& from_here, |
650 const base::Closure& task, | 653 base::Closure task, |
651 base::TimeDelta delay) { | 654 base::TimeDelta delay) { |
652 return BrowserThreadImpl::PostTaskHelper( | 655 return BrowserThreadImpl::PostTaskHelper(identifier, from_here, |
653 identifier, from_here, task, delay, false); | 656 std::move(task), delay, false); |
654 } | 657 } |
655 | 658 |
656 // static | 659 // static |
657 bool BrowserThread::PostTaskAndReply(ID identifier, | 660 bool BrowserThread::PostTaskAndReply(ID identifier, |
658 const tracked_objects::Location& from_here, | 661 const tracked_objects::Location& from_here, |
659 base::Closure task, | 662 base::Closure task, |
660 base::Closure reply) { | 663 base::Closure reply) { |
661 return GetTaskRunnerForThread(identifier) | 664 return GetTaskRunnerForThread(identifier) |
662 ->PostTaskAndReply(from_here, std::move(task), std::move(reply)); | 665 ->PostTaskAndReply(from_here, std::move(task), std::move(reply)); |
663 } | 666 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 BrowserThreadDelegateAtomicPtr old_delegate = | 699 BrowserThreadDelegateAtomicPtr old_delegate = |
697 base::subtle::NoBarrier_AtomicExchange( | 700 base::subtle::NoBarrier_AtomicExchange( |
698 &globals.io_thread_delegate, | 701 &globals.io_thread_delegate, |
699 reinterpret_cast<BrowserThreadDelegateAtomicPtr>(delegate)); | 702 reinterpret_cast<BrowserThreadDelegateAtomicPtr>(delegate)); |
700 | 703 |
701 // This catches registration when previously registered. | 704 // This catches registration when previously registered. |
702 DCHECK(!delegate || !old_delegate); | 705 DCHECK(!delegate || !old_delegate); |
703 } | 706 } |
704 | 707 |
705 } // namespace content | 708 } // namespace content |
OLD | NEW |