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) {
// Create without a sequence manager.
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>(
nullptr, time_domain.get(), TaskQueue::Spec("stub"));
scoped_refptr<SingleThreadTaskRunner> task_runner2 =
queue2->CreateTaskRunner(0);
EXPECT_FALSE(task_runner2->PostTask(FROM_HERE, BindOnce(&NopTask)));
// Tidy up.
queue2->UnregisterTaskQueue();
}
TEST_P(SequenceManagerTest, DestructorPostChainDuringShutdown) {
......
......@@ -231,9 +231,8 @@ class BASE_EXPORT TaskQueueImpl {
bool RequiresTaskTiming() const;
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
// and this queue can be safely deleted on any thread.
......@@ -250,9 +249,6 @@ class BASE_EXPORT TaskQueueImpl {
// constructed due to not having TaskQueue.
void SetQueueEnabledForTest(bool enabled);
// TODO(alexclarke): Remove when possible.
void ClearSequenceManagerForTesting();
protected:
void SetDelayedWakeUpForTesting(Optional<DelayedWakeUp> wake_up);
......@@ -261,17 +257,17 @@ class BASE_EXPORT TaskQueueImpl {
friend class WorkQueueTest;
struct AnyThread {
AnyThread(SequenceManagerImpl* sequence_manager, TimeDomain* time_domain);
explicit AnyThread(TimeDomain* time_domain);
~AnyThread();
// SequenceManagerImpl, TimeDomain and Observer are maintained in two
// copies: inside AnyThread and inside MainThreadOnly. They can be changed
// only from main thread, so it should be locked before accessing from other
// threads.
SequenceManagerImpl* sequence_manager;
// TimeDomain and Observer are maintained in two copies: inside AnyThread
// and inside MainThreadOnly. They can be changed only from main thread, so
// it should be locked before accessing from other threads.
TimeDomain* time_domain;
// Callback corresponding to TaskQueue::Observer::OnQueueNextChanged.
OnNextWakeUpChangedCallback on_next_wake_up_changed_callback;
bool unregistered = false;
};
// A queue for holding delayed tasks before their delay has expired.
......@@ -304,15 +300,12 @@ class BASE_EXPORT TaskQueueImpl {
};
struct MainThreadOnly {
MainThreadOnly(SequenceManagerImpl* sequence_manager,
TaskQueueImpl* task_queue,
TimeDomain* time_domain);
MainThreadOnly(TaskQueueImpl* task_queue, TimeDomain* time_domain);
~MainThreadOnly();
// Another copy of SequenceManagerImpl, TimeDomain and Observer
// for lock-free access from the main thread.
// See description inside struct AnyThread for details.
SequenceManagerImpl* sequence_manager;
TimeDomain* time_domain;
// Callback corresponding to TaskQueue::Observer::OnQueueNextChanged.
OnNextWakeUpChangedCallback on_next_wake_up_changed_callback;
......@@ -390,6 +383,7 @@ class BASE_EXPORT TaskQueueImpl {
void ActivateDelayedFenceIfNeeded(TimeTicks now);
const char* name_;
SequenceManagerImpl* const sequence_manager_;
scoped_refptr<AssociatedThreadId> associated_thread_;
......
......@@ -186,7 +186,7 @@ TEST_F(TimeDomainTest, SetNextDelayedDoWork_OnlyCalledForEarlierTasks) {
}
TEST_F(TimeDomainTest, UnregisterQueue) {
std::unique_ptr<TaskQueueImplForTest> task_queue2_ =
std::unique_ptr<TaskQueueImplForTest> task_queue2 =
std::make_unique<TaskQueueImplForTest>(nullptr, time_domain_.get(),
TaskQueue::Spec("test"));
......@@ -196,8 +196,7 @@ TEST_F(TimeDomainTest, UnregisterQueue) {
EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, wake_up1)).Times(1);
task_queue_->SetDelayedWakeUpForTesting(internal::DelayedWakeUp{wake_up1, 0});
TimeTicks wake_up2 = now + TimeDelta::FromMilliseconds(100);
task_queue2_->SetDelayedWakeUpForTesting(
internal::DelayedWakeUp{wake_up2, 0});
task_queue2->SetDelayedWakeUpForTesting(internal::DelayedWakeUp{wake_up2, 0});
EXPECT_EQ(task_queue_.get(), time_domain_->NextScheduledTaskQueue());
......@@ -206,16 +205,21 @@ TEST_F(TimeDomainTest, UnregisterQueue) {
EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, wake_up2)).Times(1);
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());
EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, TimeTicks::Max()))
.Times(1);
time_domain_->UnregisterQueue(task_queue2_.get());
time_domain_->UnregisterQueue(task_queue2.get());
EXPECT_FALSE(time_domain_->NextScheduledTaskQueue());
task_queue2->UnregisterTaskQueue();
task_queue2 = nullptr;
}
TEST_F(TimeDomainTest, WakeUpReadyDelayedQueues) {
......@@ -369,6 +373,10 @@ TEST_F(TimeDomainTest, HighResolutionWakeUps) {
time_domain_->SetNextWakeUpForQueue(
&q1, nullopt, internal::WakeUpResolution::kLow, &lazy_now);
EXPECT_FALSE(time_domain_->HasPendingHighResolutionTasks());
// Tidy up.
q1.UnregisterTaskQueue();
q2.UnregisterTaskQueue();
}
} // namespace sequence_manager
......
......@@ -36,7 +36,11 @@ class WorkQueueTest : public testing::Test {
public:
void SetUp() override {
dummy_sequence_manager_ = SequenceManagerImpl::CreateUnbound(nullptr);
scoped_refptr<AssociatedThreadId> thread_checker =
dummy_sequence_manager_->associated_thread();
thread_checker->BindToCurrentThread();
time_domain_.reset(new RealTimeDomain());
dummy_sequence_manager_->RegisterTimeDomain(time_domain_.get());
task_queue_ = std::make_unique<TaskQueueImpl>(dummy_sequence_manager_.get(),
time_domain_.get(),
TaskQueue::Spec("test"));
......@@ -49,8 +53,8 @@ class WorkQueueTest : public testing::Test {
void TearDown() override {
work_queue_sets_->RemoveQueue(work_queue_.get());
task_queue_->ClearSequenceManagerForTesting();
task_queue_->UnregisterTaskQueue();
dummy_sequence_manager_->UnregisterTimeDomain(time_domain_.get());
}
protected:
......
......@@ -206,6 +206,7 @@ void WorkerThreadScheduler::Shutdown() {
"WorkerThread.Runtime", delta, base::TimeDelta::FromSeconds(1),
base::TimeDelta::FromDays(1), 50 /* bucket count */);
task_queue_throttler_.reset();
idle_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