summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortzik <tzik@chromium.org>2017-12-01 10:00:26 +0900
committerQijiang Fan <fqj@google.com>2020-06-05 07:55:48 +0900
commit33fcbd5f380b2635078c9483549007268e00b756 (patch)
tree983424d09acffad90881a3bfecd7e4cacb696805
parent79e76ed2e1d284a1824eac58ddc8e9f31df65186 (diff)
downloadlibchrome-33fcbd5f380b2635078c9483549007268e00b756.tar.gz
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/798819 Reviewed-by: Daniel Cheng <dcheng@chromium.org> Commit-Queue: Taiju Tsuiki <tzik@chromium.org> Cr-Commit-Position: refs/heads/master@{#520779} CrOS-Libchrome-Original-Commit: 7102717fe035117917054b4349b2b85d40ee5e2c
-rw-r--r--base/test/test_mock_time_task_runner.cc21
-rw-r--r--base/test/test_mock_time_task_runner.h2
2 files changed, 13 insertions, 10 deletions
diff --git a/base/test/test_mock_time_task_runner.cc b/base/test/test_mock_time_task_runner.cc
index d97e35a929..1264113a1f 100644
--- a/base/test/test_mock_time_task_runner.cc
+++ b/base/test/test_mock_time_task_runner.cc
@@ -209,7 +209,7 @@ void TestMockTimeTaskRunner::FastForwardBy(TimeDelta delta) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK_GE(delta, TimeDelta());
- const TimeTicks original_now_ticks = now_ticks_;
+ const TimeTicks original_now_ticks = NowTicks();
ProcessAllTasksNoLaterThan(delta);
ForwardClocksUntilTickTime(original_now_ticks + delta);
}
@@ -232,12 +232,12 @@ void TestMockTimeTaskRunner::ClearPendingTasks() {
}
Time TestMockTimeTaskRunner::Now() const {
- DCHECK(thread_checker_.CalledOnValidThread());
+ AutoLock scoped_lock(tasks_lock_);
return now_;
}
TimeTicks TestMockTimeTaskRunner::NowTicks() const {
- DCHECK(thread_checker_.CalledOnValidThread());
+ AutoLock scoped_lock(tasks_lock_);
return now_ticks_;
}
@@ -278,7 +278,7 @@ size_t TestMockTimeTaskRunner::GetPendingTaskCount() const {
TimeDelta TestMockTimeTaskRunner::NextPendingTaskDelay() const {
DCHECK(thread_checker_.CalledOnValidThread());
return tasks_.empty() ? TimeDelta::Max()
- : tasks_.top().GetTimeToRun() - now_ticks_;
+ : tasks_.top().GetTimeToRun() - NowTicks();
}
// TODO(gab): Combine |thread_checker_| with a SequenceToken to differentiate
@@ -330,7 +330,7 @@ void TestMockTimeTaskRunner::ProcessAllTasksNoLaterThan(TimeDelta max_delta) {
undo_override = ThreadTaskRunnerHandle::OverrideForTesting(this);
}
- const TimeTicks original_now_ticks = now_ticks_;
+ const TimeTicks original_now_ticks = NowTicks();
while (!quit_run_loop_) {
OnBeforeSelectingTask();
TestPendingTask task_info;
@@ -347,11 +347,14 @@ void TestMockTimeTaskRunner::ProcessAllTasksNoLaterThan(TimeDelta max_delta) {
void TestMockTimeTaskRunner::ForwardClocksUntilTickTime(TimeTicks later_ticks) {
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_ticks_ = later_ticks;
+ now_ += later_ticks - now_ticks_;
+ now_ticks_ = later_ticks;
+ }
OnAfterTimePassed();
}
diff --git a/base/test/test_mock_time_task_runner.h b/base/test/test_mock_time_task_runner.h
index 1fe9809a52..ffa91c9d37 100644
--- a/base/test/test_mock_time_task_runner.h
+++ b/base/test/test_mock_time_task_runner.h
@@ -246,7 +246,7 @@ class TestMockTimeTaskRunner : public SingleThreadTaskRunner,
// |tasks_lock_| is held.
size_t next_task_ordinal_ = 0;
- Lock tasks_lock_;
+ mutable Lock tasks_lock_;
ConditionVariable tasks_lock_cv_;
// Members used to in TestMockTimeTaskRunners of Type::kBoundToThread to take