| 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 |