Commit 6d22abcc authored by Alex Clarke's avatar Alex Clarke Committed by Commit Bot

TaskQueueImpl: Make sequence_manager const

This simplification is a step towards a lock-free main thread PostTask path.

Split off from: https://chromium-review.googlesource.com/c/chromium/src/+/1304557

Bug: 897751
Change-Id: I6aa2fd98b000b634785f2fee94afa3b11e70423d
Reviewed-on: https://chromium-review.googlesource.com/c/1317568
Commit-Queue: Alex Clarke <alexclarke@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605311}
parent 2660cad6
...@@ -3349,12 +3349,15 @@ TEST_P(SequenceManagerTest, TaskQueueTaskRunnerDetach) { ...@@ -3349,12 +3349,15 @@ TEST_P(SequenceManagerTest, TaskQueueTaskRunnerDetach) {
// Create without a sequence manager. // Create without a sequence manager.
std::unique_ptr<TimeDomain> time_domain = std::unique_ptr<TimeDomain> time_domain =
std::make_unique<internal::RealTimeDomain>(); std::make_unique<MockTimeDomain>(TimeTicks());
std::unique_ptr<TaskQueueImpl> queue2 = std::make_unique<TaskQueueImpl>( std::unique_ptr<TaskQueueImpl> queue2 = std::make_unique<TaskQueueImpl>(
nullptr, time_domain.get(), TaskQueue::Spec("stub")); nullptr, time_domain.get(), TaskQueue::Spec("stub"));
scoped_refptr<SingleThreadTaskRunner> task_runner2 = scoped_refptr<SingleThreadTaskRunner> task_runner2 =
queue2->CreateTaskRunner(0); queue2->CreateTaskRunner(0);
EXPECT_FALSE(task_runner2->PostTask(FROM_HERE, BindOnce(&NopTask))); EXPECT_FALSE(task_runner2->PostTask(FROM_HERE, BindOnce(&NopTask)));
// Tidy up.
queue2->UnregisterTaskQueue();
} }
TEST_P(SequenceManagerTest, DestructorPostChainDuringShutdown) { TEST_P(SequenceManagerTest, DestructorPostChainDuringShutdown) {
......
...@@ -231,9 +231,8 @@ class BASE_EXPORT TaskQueueImpl { ...@@ -231,9 +231,8 @@ class BASE_EXPORT TaskQueueImpl {
bool RequiresTaskTiming() const; bool RequiresTaskTiming() const;
WeakPtr<SequenceManagerImpl> GetSequenceManagerWeakPtr(); WeakPtr<SequenceManagerImpl> GetSequenceManagerWeakPtr();
SequenceManagerImpl* sequence_manager() {
return main_thread_only().sequence_manager; SequenceManagerImpl* sequence_manager() const { return sequence_manager_; }
}
// Returns true if this queue is unregistered or task queue manager is deleted // Returns true if this queue is unregistered or task queue manager is deleted
// and this queue can be safely deleted on any thread. // and this queue can be safely deleted on any thread.
...@@ -250,9 +249,6 @@ class BASE_EXPORT TaskQueueImpl { ...@@ -250,9 +249,6 @@ class BASE_EXPORT TaskQueueImpl {
// constructed due to not having TaskQueue. // constructed due to not having TaskQueue.
void SetQueueEnabledForTest(bool enabled); void SetQueueEnabledForTest(bool enabled);
// TODO(alexclarke): Remove when possible.
void ClearSequenceManagerForTesting();
protected: protected:
void SetDelayedWakeUpForTesting(Optional<DelayedWakeUp> wake_up); void SetDelayedWakeUpForTesting(Optional<DelayedWakeUp> wake_up);
...@@ -261,17 +257,17 @@ class BASE_EXPORT TaskQueueImpl { ...@@ -261,17 +257,17 @@ class BASE_EXPORT TaskQueueImpl {
friend class WorkQueueTest; friend class WorkQueueTest;
struct AnyThread { struct AnyThread {
AnyThread(SequenceManagerImpl* sequence_manager, TimeDomain* time_domain); explicit AnyThread(TimeDomain* time_domain);
~AnyThread(); ~AnyThread();
// SequenceManagerImpl, TimeDomain and Observer are maintained in two // TimeDomain and Observer are maintained in two copies: inside AnyThread
// copies: inside AnyThread and inside MainThreadOnly. They can be changed // and inside MainThreadOnly. They can be changed only from main thread, so
// only from main thread, so it should be locked before accessing from other // it should be locked before accessing from other threads.
// threads.
SequenceManagerImpl* sequence_manager;
TimeDomain* time_domain; TimeDomain* time_domain;
// Callback corresponding to TaskQueue::Observer::OnQueueNextChanged. // Callback corresponding to TaskQueue::Observer::OnQueueNextChanged.
OnNextWakeUpChangedCallback on_next_wake_up_changed_callback; OnNextWakeUpChangedCallback on_next_wake_up_changed_callback;
bool unregistered = false;
}; };
// A queue for holding delayed tasks before their delay has expired. // A queue for holding delayed tasks before their delay has expired.
...@@ -304,15 +300,12 @@ class BASE_EXPORT TaskQueueImpl { ...@@ -304,15 +300,12 @@ class BASE_EXPORT TaskQueueImpl {
}; };
struct MainThreadOnly { struct MainThreadOnly {
MainThreadOnly(SequenceManagerImpl* sequence_manager, MainThreadOnly(TaskQueueImpl* task_queue, TimeDomain* time_domain);
TaskQueueImpl* task_queue,
TimeDomain* time_domain);
~MainThreadOnly(); ~MainThreadOnly();
// Another copy of SequenceManagerImpl, TimeDomain and Observer // Another copy of SequenceManagerImpl, TimeDomain and Observer
// for lock-free access from the main thread. // for lock-free access from the main thread.
// See description inside struct AnyThread for details. // See description inside struct AnyThread for details.
SequenceManagerImpl* sequence_manager;
TimeDomain* time_domain; TimeDomain* time_domain;
// Callback corresponding to TaskQueue::Observer::OnQueueNextChanged. // Callback corresponding to TaskQueue::Observer::OnQueueNextChanged.
OnNextWakeUpChangedCallback on_next_wake_up_changed_callback; OnNextWakeUpChangedCallback on_next_wake_up_changed_callback;
...@@ -390,6 +383,7 @@ class BASE_EXPORT TaskQueueImpl { ...@@ -390,6 +383,7 @@ class BASE_EXPORT TaskQueueImpl {
void ActivateDelayedFenceIfNeeded(TimeTicks now); void ActivateDelayedFenceIfNeeded(TimeTicks now);
const char* name_; const char* name_;
SequenceManagerImpl* const sequence_manager_;
scoped_refptr<AssociatedThreadId> associated_thread_; scoped_refptr<AssociatedThreadId> associated_thread_;
......
...@@ -186,7 +186,7 @@ TEST_F(TimeDomainTest, SetNextDelayedDoWork_OnlyCalledForEarlierTasks) { ...@@ -186,7 +186,7 @@ TEST_F(TimeDomainTest, SetNextDelayedDoWork_OnlyCalledForEarlierTasks) {
} }
TEST_F(TimeDomainTest, UnregisterQueue) { TEST_F(TimeDomainTest, UnregisterQueue) {
std::unique_ptr<TaskQueueImplForTest> task_queue2_ = std::unique_ptr<TaskQueueImplForTest> task_queue2 =
std::make_unique<TaskQueueImplForTest>(nullptr, time_domain_.get(), std::make_unique<TaskQueueImplForTest>(nullptr, time_domain_.get(),
TaskQueue::Spec("test")); TaskQueue::Spec("test"));
...@@ -196,8 +196,7 @@ TEST_F(TimeDomainTest, UnregisterQueue) { ...@@ -196,8 +196,7 @@ TEST_F(TimeDomainTest, UnregisterQueue) {
EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, wake_up1)).Times(1); EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, wake_up1)).Times(1);
task_queue_->SetDelayedWakeUpForTesting(internal::DelayedWakeUp{wake_up1, 0}); task_queue_->SetDelayedWakeUpForTesting(internal::DelayedWakeUp{wake_up1, 0});
TimeTicks wake_up2 = now + TimeDelta::FromMilliseconds(100); TimeTicks wake_up2 = now + TimeDelta::FromMilliseconds(100);
task_queue2_->SetDelayedWakeUpForTesting( task_queue2->SetDelayedWakeUpForTesting(internal::DelayedWakeUp{wake_up2, 0});
internal::DelayedWakeUp{wake_up2, 0});
EXPECT_EQ(task_queue_.get(), time_domain_->NextScheduledTaskQueue()); EXPECT_EQ(task_queue_.get(), time_domain_->NextScheduledTaskQueue());
...@@ -206,16 +205,21 @@ TEST_F(TimeDomainTest, UnregisterQueue) { ...@@ -206,16 +205,21 @@ TEST_F(TimeDomainTest, UnregisterQueue) {
EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, wake_up2)).Times(1); EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, wake_up2)).Times(1);
time_domain_->UnregisterQueue(task_queue_.get()); time_domain_->UnregisterQueue(task_queue_.get());
task_queue_ = std::unique_ptr<TaskQueueImplForTest>(); EXPECT_EQ(task_queue2.get(), time_domain_->NextScheduledTaskQueue());
EXPECT_EQ(task_queue2_.get(), time_domain_->NextScheduledTaskQueue());
task_queue_->UnregisterTaskQueue();
task_queue_ = nullptr;
testing::Mock::VerifyAndClearExpectations(time_domain_.get()); testing::Mock::VerifyAndClearExpectations(time_domain_.get());
EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, TimeTicks::Max())) EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, TimeTicks::Max()))
.Times(1); .Times(1);
time_domain_->UnregisterQueue(task_queue2_.get()); time_domain_->UnregisterQueue(task_queue2.get());
EXPECT_FALSE(time_domain_->NextScheduledTaskQueue()); EXPECT_FALSE(time_domain_->NextScheduledTaskQueue());
task_queue2->UnregisterTaskQueue();
task_queue2 = nullptr;
} }
TEST_F(TimeDomainTest, WakeUpReadyDelayedQueues) { TEST_F(TimeDomainTest, WakeUpReadyDelayedQueues) {
...@@ -369,6 +373,10 @@ TEST_F(TimeDomainTest, HighResolutionWakeUps) { ...@@ -369,6 +373,10 @@ TEST_F(TimeDomainTest, HighResolutionWakeUps) {
time_domain_->SetNextWakeUpForQueue( time_domain_->SetNextWakeUpForQueue(
&q1, nullopt, internal::WakeUpResolution::kLow, &lazy_now); &q1, nullopt, internal::WakeUpResolution::kLow, &lazy_now);
EXPECT_FALSE(time_domain_->HasPendingHighResolutionTasks()); EXPECT_FALSE(time_domain_->HasPendingHighResolutionTasks());
// Tidy up.
q1.UnregisterTaskQueue();
q2.UnregisterTaskQueue();
} }
} // namespace sequence_manager } // namespace sequence_manager
......
...@@ -36,7 +36,11 @@ class WorkQueueTest : public testing::Test { ...@@ -36,7 +36,11 @@ class WorkQueueTest : public testing::Test {
public: public:
void SetUp() override { void SetUp() override {
dummy_sequence_manager_ = SequenceManagerImpl::CreateUnbound(nullptr); dummy_sequence_manager_ = SequenceManagerImpl::CreateUnbound(nullptr);
scoped_refptr<AssociatedThreadId> thread_checker =
dummy_sequence_manager_->associated_thread();
thread_checker->BindToCurrentThread();
time_domain_.reset(new RealTimeDomain()); time_domain_.reset(new RealTimeDomain());
dummy_sequence_manager_->RegisterTimeDomain(time_domain_.get());
task_queue_ = std::make_unique<TaskQueueImpl>(dummy_sequence_manager_.get(), task_queue_ = std::make_unique<TaskQueueImpl>(dummy_sequence_manager_.get(),
time_domain_.get(), time_domain_.get(),
TaskQueue::Spec("test")); TaskQueue::Spec("test"));
...@@ -49,8 +53,8 @@ class WorkQueueTest : public testing::Test { ...@@ -49,8 +53,8 @@ class WorkQueueTest : public testing::Test {
void TearDown() override { void TearDown() override {
work_queue_sets_->RemoveQueue(work_queue_.get()); work_queue_sets_->RemoveQueue(work_queue_.get());
task_queue_->UnregisterTaskQueue();
task_queue_->ClearSequenceManagerForTesting(); dummy_sequence_manager_->UnregisterTimeDomain(time_domain_.get());
} }
protected: protected:
......
...@@ -206,6 +206,7 @@ void WorkerThreadScheduler::Shutdown() { ...@@ -206,6 +206,7 @@ void WorkerThreadScheduler::Shutdown() {
"WorkerThread.Runtime", delta, base::TimeDelta::FromSeconds(1), "WorkerThread.Runtime", delta, base::TimeDelta::FromSeconds(1),
base::TimeDelta::FromDays(1), 50 /* bucket count */); base::TimeDelta::FromDays(1), 50 /* bucket count */);
task_queue_throttler_.reset(); task_queue_throttler_.reset();
idle_helper_.Shutdown();
helper()->Shutdown(); helper()->Shutdown();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment