40TEST(MessageLoopTaskQueue, RegisterOneTask) {
44 auto queue_id = task_queue->CreateTaskQueue();
45 auto wakeable = std::make_unique<TestWakeable>(
46 [&time](
fml::TimePoint wake_time) { ASSERT_TRUE(wake_time == time); });
47 task_queue->SetWakeable(queue_id, wakeable.get());
49 task_queue->RegisterTask(queue_id, [] {}, time);
50 ASSERT_TRUE(task_queue->HasPendingTasks(queue_id));
51 ASSERT_TRUE(task_queue->GetNumPendingTasks(queue_id) == 1);
54TEST(MessageLoopTaskQueue, RegisterTwoTasksAndCount) {
56 auto queue_id = task_queue->CreateTaskQueue();
59 ASSERT_TRUE(task_queue->HasPendingTasks(queue_id));
60 ASSERT_TRUE(task_queue->GetNumPendingTasks(queue_id) == 2);
63TEST(MessageLoopTaskQueue, RegisterTasksOnMergedQueuesAndCount) {
65 auto platform_queue = task_queue->CreateTaskQueue();
66 auto raster_queue = task_queue->CreateTaskQueue();
71 ASSERT_TRUE(task_queue->GetNumPendingTasks(platform_queue) == 1);
72 ASSERT_TRUE(task_queue->GetNumPendingTasks(raster_queue) == 1);
74 ASSERT_FALSE(task_queue->Owns(platform_queue, raster_queue));
75 task_queue->Merge(platform_queue, raster_queue);
76 ASSERT_TRUE(task_queue->Owns(platform_queue, raster_queue));
78 ASSERT_TRUE(task_queue->HasPendingTasks(platform_queue));
79 ASSERT_TRUE(task_queue->GetNumPendingTasks(platform_queue) == 2);
81 ASSERT_FALSE(task_queue->HasPendingTasks(raster_queue));
82 ASSERT_TRUE(task_queue->GetNumPendingTasks(raster_queue) == 0);
84 task_queue->Unmerge(platform_queue, raster_queue);
85 ASSERT_FALSE(task_queue->Owns(platform_queue, raster_queue));
86 ASSERT_TRUE(task_queue->GetNumPendingTasks(platform_queue) == 1);
87 ASSERT_TRUE(task_queue->GetNumPendingTasks(raster_queue) == 1);
90TEST(MessageLoopTaskQueue, PreserveTaskOrdering) {
92 auto queue_id = task_queue->CreateTaskQueue();
96 task_queue->RegisterTask(
100 task_queue->RegisterTask(
106 fml::closure invocation = task_queue->GetNextTaskToRun(queue_id, now);
116TEST(MessageLoopTaskQueue, RegisterTasksOnMergedQueuesPreserveTaskOrdering) {
118 auto platform_queue = task_queue->CreateTaskQueue();
119 auto raster1_queue = task_queue->CreateTaskQueue();
120 auto raster2_queue = task_queue->CreateTaskQueue();
124 task_queue->RegisterTask(
128 task_queue->RegisterTask(
132 task_queue->RegisterTask(
135 task_queue->Merge(platform_queue, raster1_queue);
136 ASSERT_TRUE(task_queue->Owns(platform_queue, raster1_queue));
137 task_queue->Merge(platform_queue, raster2_queue);
138 ASSERT_TRUE(task_queue->Owns(platform_queue, raster2_queue));
146 fml::closure invocation = task_queue->GetNextTaskToRun(platform_queue, now);
156TEST(MessageLoopTaskQueue, UnmergeRespectTheOriginalTaskOrderingInQueues) {
158 auto platform_queue = task_queue->CreateTaskQueue();
159 auto raster_queue = task_queue->CreateTaskQueue();
163 task_queue->RegisterTask(
166 task_queue->RegisterTask(
169 task_queue->RegisterTask(
172 task_queue->RegisterTask(
175 task_queue->RegisterTask(
178 task_queue->RegisterTask(
181 ASSERT_TRUE(task_queue->Merge(platform_queue, raster_queue));
182 ASSERT_TRUE(task_queue->Owns(platform_queue, raster_queue));
188 for (
int i = 0; i < 3; i++) {
189 fml::closure invocation = task_queue->GetNextTaskToRun(platform_queue, now);
190 ASSERT_FALSE(!invocation);
192 ASSERT_TRUE(test_val == i);
194 ASSERT_TRUE(task_queue->GetNumPendingTasks(platform_queue) == 3);
195 ASSERT_TRUE(task_queue->GetNumPendingTasks(raster_queue) == 0);
197 ASSERT_TRUE(task_queue->Unmerge(platform_queue, raster_queue));
198 ASSERT_FALSE(task_queue->Owns(platform_queue, raster_queue));
207 ASSERT_TRUE(task_queue->GetNumPendingTasks(platform_queue) == 1);
208 fml::closure invocation = task_queue->GetNextTaskToRun(platform_queue, now);
209 ASSERT_FALSE(!invocation);
211 ASSERT_TRUE(test_val == 4);
212 ASSERT_TRUE(task_queue->GetNumPendingTasks(platform_queue) == 0);
217 ASSERT_TRUE(task_queue->GetNumPendingTasks(raster_queue) == 2);
218 fml::closure invocation = task_queue->GetNextTaskToRun(raster_queue, now);
219 ASSERT_FALSE(!invocation);
221 ASSERT_TRUE(test_val == 3);
224 ASSERT_TRUE(task_queue->GetNumPendingTasks(raster_queue) == 1);
225 fml::closure invocation = task_queue->GetNextTaskToRun(raster_queue, now);
226 ASSERT_FALSE(!invocation);
228 ASSERT_TRUE(test_val == 5);
229 ASSERT_TRUE(task_queue->GetNumPendingTasks(raster_queue) == 0);
242TEST(MessageLoopTaskQueue, AddRemoveNotifyObservers) {
244 auto queue_id = task_queue->CreateTaskQueue();
249 task_queue->AddTaskObserver(queue_id,
key, [&test_val]() { test_val = 1; });
251 ASSERT_TRUE(test_val == 1);
254 task_queue->RemoveTaskObserver(queue_id,
key);
256 ASSERT_TRUE(test_val == 0);
259TEST(MessageLoopTaskQueue, WakeUpIndependentOfTime) {
261 auto queue_id = task_queue->CreateTaskQueue();
264 auto wakeable = std::make_unique<TestWakeable>(
266 task_queue->SetWakeable(queue_id, wakeable.get());
271 ASSERT_TRUE(num_wakes == 2);
274TEST(MessageLoopTaskQueue, WokenUpWithNewerTime) {
276 auto queue_id = task_queue->CreateTaskQueue();
281 auto wakeable = std::make_unique<TestWakeable>(
283 ASSERT_TRUE(wake_time == expected);
287 task_queue->SetWakeable(queue_id, wakeable.get());
293 task_queue->RegisterTask(queue_id, []() {}, now);
298TEST(MessageLoopTaskQueue, NotifyObserversWhileCreatingQueues) {
303 task_queues->AddTaskObserver(queue_id, queue_id + 1, [&]() {
304 first_observer_executing.
Signal();
305 before_second_observer.
Wait();
308 for (
int i = 0; i < 100; i++) {
309 task_queues->AddTaskObserver(queue_id, queue_id + i + 2, [] {});
314 first_observer_executing.
Wait();
316 for (
int i = 0; i < 100; i++) {
317 task_queues->CreateTaskQueue();
320 before_second_observer.
Signal();
321 notify_observers.join();
337TEST(MessageLoopTaskQueue, QueueOwnsMergedTaskQueueId) {
339 auto platform_queue = task_queue->CreateTaskQueue();
340 auto raster_queue = task_queue->CreateTaskQueue();
341 ASSERT_FALSE(task_queue->Owns(platform_queue, raster_queue));
342 ASSERT_FALSE(task_queue->Owns(raster_queue, platform_queue));
343 task_queue->Merge(platform_queue, raster_queue);
344 ASSERT_TRUE(task_queue->Owns(platform_queue, raster_queue));
345 ASSERT_FALSE(task_queue->Owns(raster_queue, platform_queue));
351TEST(MessageLoopTaskQueue, ConcurrentQueueAndTaskCreatingCounts) {
357 constexpr size_t kTaskQueuesCount = 2;
358 constexpr size_t kThreadTaskCount = 500;
360 std::vector<TaskQueueId> task_queue_ids;
361 for (
size_t i = 0; i < kTaskQueuesCount; ++i) {
362 task_queue_ids.emplace_back(task_queues->CreateTaskQueue());
365 ASSERT_EQ(task_queue_ids.size(), kTaskQueuesCount);
369 auto thread_main = [&]() {
370 for (
size_t i = 0; i < kThreadTaskCount; i++) {
371 const auto current_task_queue_id =
372 task_queue_ids[std::rand() % kTaskQueuesCount];
373 const auto empty_task = []() {};
377 task_queues->RegisterTask(current_task_queue_id, empty_task,
384 std::vector<std::thread> threads;
387 threads.emplace_back(std::thread{thread_main});
398 size_t pending_tasks = 0u;
399 std::for_each(task_queue_ids.begin(), task_queue_ids.end(),
400 [&](
const auto&
queue) {
401 pending_tasks += task_queues->GetNumPendingTasks(queue);
404 ASSERT_EQ(pending_tasks,
kThreadCount * kThreadTaskCount);
407TEST(MessageLoopTaskQueue, RegisterTaskWakesUpOwnerQueue) {
409 auto platform_queue = task_queue->CreateTaskQueue();
410 auto raster_queue = task_queue->CreateTaskQueue();
412 std::vector<fml::TimePoint> wakes;
414 auto wakeable1 = std::make_unique<TestWakeable>(
415 [&wakes](
fml::TimePoint wake_time) { wakes.push_back(wake_time); });
416 auto wakeable2 = std::make_unique<TestWakeable>([](
fml::TimePoint wake_time) {
421 task_queue->SetWakeable(platform_queue, wakeable1.get());
422 task_queue->SetWakeable(raster_queue, wakeable2.get());
427 ASSERT_EQ(0UL, wakes.size());
429 task_queue->RegisterTask(platform_queue, []() {}, time1);
431 ASSERT_EQ(1UL, wakes.size());
432 ASSERT_EQ(time1, wakes[0]);
434 task_queue->Merge(platform_queue, raster_queue);
436 task_queue->RegisterTask(raster_queue, []() {}, time2);
438 ASSERT_EQ(3UL, wakes.size());
439 ASSERT_EQ(time1, wakes[1]);
440 ASSERT_EQ(time1, wakes[2]);
static constexpr uint64_t kThreadCount