Add test to verify TaskQueue memory access order.
Bug: webrtc:10138 Change-Id: I53e8a3a612ad44feced8d63a4035d79b7e0f22a9 Reviewed-on: https://webrtc-review.googlesource.com/c/120601 Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Commit-Queue: Artem Titov <titovartem@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26497}
This commit is contained in:
@ -208,5 +208,37 @@ TEST_P(TaskQueueTest, PostALot) {
|
|||||||
EXPECT_EQ(tasks_cleaned_up, kTaskCount);
|
EXPECT_EQ(tasks_cleaned_up, kTaskCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test posting two tasks that have shared state not protected by a
|
||||||
|
// lock. The TaskQueue should guarantee memory read-write order and
|
||||||
|
// FIFO task execution order, so the second task should always see the
|
||||||
|
// changes that were made by the first task.
|
||||||
|
//
|
||||||
|
// If the TaskQueue doesn't properly synchronize the execution of
|
||||||
|
// tasks, there will be a data race, which is undefined behavior. The
|
||||||
|
// EXPECT calls may randomly catch this, but to make the most of this
|
||||||
|
// unit test, run it under TSan or some other tool that is able to
|
||||||
|
// directly detect data races.
|
||||||
|
TEST_P(TaskQueueTest, PostTwoWithSharedUnprotectedState) {
|
||||||
|
struct SharedState {
|
||||||
|
// First task will set this value to 1 and second will assert it.
|
||||||
|
int state = 0;
|
||||||
|
} state;
|
||||||
|
|
||||||
|
auto queue = CreateTaskQueue(GetParam(), "PostTwoWithSharedUnprotectedState");
|
||||||
|
rtc::Event done;
|
||||||
|
queue->PostTask(rtc::NewClosure([&state, &queue, &done] {
|
||||||
|
// Post tasks from queue to guarantee, that 1st task won't be
|
||||||
|
// executed before the second one will be posted.
|
||||||
|
queue->PostTask(rtc::NewClosure([&state] { state.state = 1; }));
|
||||||
|
queue->PostTask(rtc::NewClosure([&state, &done] {
|
||||||
|
EXPECT_EQ(state.state, 1);
|
||||||
|
done.Set();
|
||||||
|
}));
|
||||||
|
// Check, that state changing tasks didn't start yet.
|
||||||
|
EXPECT_EQ(state.state, 0);
|
||||||
|
}));
|
||||||
|
EXPECT_TRUE(done.Wait(1000));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -367,4 +367,37 @@ TEST(TaskQueueTest, PostALot) {
|
|||||||
EXPECT_EQ(kTaskCount, tasks_cleaned_up);
|
EXPECT_EQ(kTaskCount, tasks_cleaned_up);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test posting two tasks that have shared state not protected by a
|
||||||
|
// lock. The TaskQueue should guarantee memory read-write order and
|
||||||
|
// FIFO task execution order, so the second task should always see the
|
||||||
|
// changes that were made by the first task.
|
||||||
|
//
|
||||||
|
// If the TaskQueue doesn't properly synchronize the execution of
|
||||||
|
// tasks, there will be a data race, which is undefined behavior. The
|
||||||
|
// EXPECT calls may randomly catch this, but to make the most of this
|
||||||
|
// unit test, run it under TSan or some other tool that is able to
|
||||||
|
// directly detect data races.
|
||||||
|
TEST(TaskQueueTest, PostTwoWithSharedUnprotectedState) {
|
||||||
|
static const char kQueueName[] = "PostTwoWithSharedUnprotectedState";
|
||||||
|
struct SharedState {
|
||||||
|
// First task will set this value to 1 and second will assert it.
|
||||||
|
int state = 0;
|
||||||
|
} state;
|
||||||
|
|
||||||
|
TaskQueue queue(kQueueName);
|
||||||
|
rtc::Event done;
|
||||||
|
queue.PostTask([&state, &queue, &done] {
|
||||||
|
// Post tasks from queue to guarantee, that 1st task won't be
|
||||||
|
// executed before the second one will be posted.
|
||||||
|
queue.PostTask([&state] { state.state = 1; });
|
||||||
|
queue.PostTask([&state, &done] {
|
||||||
|
EXPECT_EQ(state.state, 1);
|
||||||
|
done.Set();
|
||||||
|
});
|
||||||
|
// Check, that state changing tasks didn't start yet.
|
||||||
|
EXPECT_EQ(state.state, 0);
|
||||||
|
});
|
||||||
|
EXPECT_TRUE(done.Wait(1000));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace rtc
|
} // namespace rtc
|
||||||
|
Reference in New Issue
Block a user