Commit 7102717f authored by tzik's avatar tzik Committed by Commit Bot

Protect mock time variables in TestMockTimeTaskRunner by a lock

|now_| and |now_ticks_| in TestMockTimeTaskRunner were read or written
without a lock. So, when PostDelayedTask() and NowTicks() are called
on different threads, it hits TSan failure.

This CL adds lock for all access to them to avoid the data race.

Change-Id: I562e2bfbd46b481b41faa05906b19c8664654812
Reviewed-on: https://chromium-review.googlesource.com/798819Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Taiju Tsuiki <tzik@chromium.org>
Cr-Commit-Position: refs/heads/master@{#520779}
parent 71c74265
...@@ -209,7 +209,7 @@ void TestMockTimeTaskRunner::FastForwardBy(TimeDelta delta) { ...@@ -209,7 +209,7 @@ void TestMockTimeTaskRunner::FastForwardBy(TimeDelta delta) {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
DCHECK_GE(delta, TimeDelta()); DCHECK_GE(delta, TimeDelta());
const TimeTicks original_now_ticks = now_ticks_; const TimeTicks original_now_ticks = NowTicks();
ProcessAllTasksNoLaterThan(delta); ProcessAllTasksNoLaterThan(delta);
ForwardClocksUntilTickTime(original_now_ticks + delta); ForwardClocksUntilTickTime(original_now_ticks + delta);
} }
...@@ -232,12 +232,12 @@ void TestMockTimeTaskRunner::ClearPendingTasks() { ...@@ -232,12 +232,12 @@ void TestMockTimeTaskRunner::ClearPendingTasks() {
} }
Time TestMockTimeTaskRunner::Now() const { Time TestMockTimeTaskRunner::Now() const {
DCHECK(thread_checker_.CalledOnValidThread()); AutoLock scoped_lock(tasks_lock_);
return now_; return now_;
} }
TimeTicks TestMockTimeTaskRunner::NowTicks() const { TimeTicks TestMockTimeTaskRunner::NowTicks() const {
DCHECK(thread_checker_.CalledOnValidThread()); AutoLock scoped_lock(tasks_lock_);
return now_ticks_; return now_ticks_;
} }
...@@ -278,7 +278,7 @@ size_t TestMockTimeTaskRunner::GetPendingTaskCount() const { ...@@ -278,7 +278,7 @@ size_t TestMockTimeTaskRunner::GetPendingTaskCount() const {
TimeDelta TestMockTimeTaskRunner::NextPendingTaskDelay() const { TimeDelta TestMockTimeTaskRunner::NextPendingTaskDelay() const {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
return tasks_.empty() ? TimeDelta::Max() return tasks_.empty() ? TimeDelta::Max()
: tasks_.top().GetTimeToRun() - now_ticks_; : tasks_.top().GetTimeToRun() - NowTicks();
} }
// TODO(gab): Combine |thread_checker_| with a SequenceToken to differentiate // TODO(gab): Combine |thread_checker_| with a SequenceToken to differentiate
...@@ -330,7 +330,7 @@ void TestMockTimeTaskRunner::ProcessAllTasksNoLaterThan(TimeDelta max_delta) { ...@@ -330,7 +330,7 @@ void TestMockTimeTaskRunner::ProcessAllTasksNoLaterThan(TimeDelta max_delta) {
undo_override = ThreadTaskRunnerHandle::OverrideForTesting(this); undo_override = ThreadTaskRunnerHandle::OverrideForTesting(this);
} }
const TimeTicks original_now_ticks = now_ticks_; const TimeTicks original_now_ticks = NowTicks();
while (!quit_run_loop_) { while (!quit_run_loop_) {
OnBeforeSelectingTask(); OnBeforeSelectingTask();
TestPendingTask task_info; TestPendingTask task_info;
...@@ -347,11 +347,14 @@ void TestMockTimeTaskRunner::ProcessAllTasksNoLaterThan(TimeDelta max_delta) { ...@@ -347,11 +347,14 @@ void TestMockTimeTaskRunner::ProcessAllTasksNoLaterThan(TimeDelta max_delta) {
void TestMockTimeTaskRunner::ForwardClocksUntilTickTime(TimeTicks later_ticks) { void TestMockTimeTaskRunner::ForwardClocksUntilTickTime(TimeTicks later_ticks) {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
if (later_ticks <= now_ticks_) {
return; AutoLock scoped_lock(tasks_lock_);
if (later_ticks <= now_ticks_)
return;
now_ += later_ticks - now_ticks_; now_ += later_ticks - now_ticks_;
now_ticks_ = later_ticks; now_ticks_ = later_ticks;
}
OnAfterTimePassed(); OnAfterTimePassed();
} }
......
...@@ -246,7 +246,7 @@ class TestMockTimeTaskRunner : public SingleThreadTaskRunner, ...@@ -246,7 +246,7 @@ class TestMockTimeTaskRunner : public SingleThreadTaskRunner,
// |tasks_lock_| is held. // |tasks_lock_| is held.
size_t next_task_ordinal_ = 0; size_t next_task_ordinal_ = 0;
Lock tasks_lock_; mutable Lock tasks_lock_;
ConditionVariable tasks_lock_cv_; ConditionVariable tasks_lock_cv_;
// Members used to in TestMockTimeTaskRunners of Type::kBoundToThread to take // Members used to in TestMockTimeTaskRunners of Type::kBoundToThread to take
......
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