From da0fcfec7aa70d363d57bc4bb63e94bb65db2941 Mon Sep 17 00:00:00 2001 From: George Wright Date: Thu, 23 Jan 2020 10:53:17 -0800 Subject: [PATCH] Re-arm timer as necessary in MessageLoopFuchsia --- engine/src/flutter/fml/BUILD.gn | 6 ++-- .../src/flutter/fml/message_loop_unittests.cc | 30 +++++++++++++++++++ .../platform/fuchsia/message_loop_fuchsia.cc | 15 +++++++--- .../platform/fuchsia/message_loop_fuchsia.h | 3 ++ 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/engine/src/flutter/fml/BUILD.gn b/engine/src/flutter/fml/BUILD.gn index 8aea291dbcd..b0a325442b9 100644 --- a/engine/src/flutter/fml/BUILD.gn +++ b/engine/src/flutter/fml/BUILD.gn @@ -227,6 +227,7 @@ executable("fml_unittests") { "memory/weak_ptr_unittest.cc", "message_loop_task_queues_merge_unmerge_unittests.cc", "message_loop_task_queues_unittests.cc", + "message_loop_unittests.cc", "message_unittests.cc", "paths_unittests.cc", "platform/darwin/string_range_sanitization_unittests.mm", @@ -243,10 +244,7 @@ executable("fml_unittests") { # TODO(gw280): Figure out why these tests don't work currently on Fuchsia if (!is_fuchsia) { - sources += [ - "file_unittest.cc", - "message_loop_unittests.cc", - ] + sources += [ "file_unittest.cc" ] } deps = [ diff --git a/engine/src/flutter/fml/message_loop_unittests.cc b/engine/src/flutter/fml/message_loop_unittests.cc index 6a64be53359..8edc7170741 100644 --- a/engine/src/flutter/fml/message_loop_unittests.cc +++ b/engine/src/flutter/fml/message_loop_unittests.cc @@ -10,6 +10,7 @@ #include "flutter/fml/build_config.h" #include "flutter/fml/concurrent_message_loop.h" #include "flutter/fml/message_loop.h" +#include "flutter/fml/message_loop_impl.h" #include "flutter/fml/synchronization/count_down_latch.h" #include "flutter/fml/synchronization/waitable_event.h" #include "flutter/fml/task_runner.h" @@ -309,3 +310,32 @@ TEST(MessageLoop, CanCreateConcurrentMessageLoop) { latch.Wait(); ASSERT_GE(thread_ids.size(), 1u); } + +TEST(MessageLoop, TIME_SENSITIVE(WakeUpTimersAreSingletons)) { + auto loop_impl = fml::MessageLoopImpl::Create(); + + const auto t1 = fml::TimeDelta::FromMilliseconds(10); + const auto t2 = fml::TimeDelta::FromMilliseconds(20); + + const auto begin = fml::TimePoint::Now(); + + // Register a task scheduled for 10ms in the future. This schedules a + // WakeUp call on the MessageLoopImpl with that fml::TimePoint + loop_impl->PostTask( + [&]() { + auto delta = fml::TimePoint::Now() - begin; + auto ms = delta.ToMillisecondsF(); + ASSERT_GE(ms, 18); + ASSERT_LE(ms, 22); + + loop_impl->Terminate(); + }, + fml::TimePoint::Now() + t1); + + // Call WakeUp manually to change the WakeUp time to the future. If the + // timer is correctly set up to be rearmed instead of a new timer scheduled, + // the above task will be executed at t2 instead of t1 now. + loop_impl->WakeUp(fml::TimePoint::Now() + t2); + + loop_impl->Run(); +} diff --git a/engine/src/flutter/fml/platform/fuchsia/message_loop_fuchsia.cc b/engine/src/flutter/fml/platform/fuchsia/message_loop_fuchsia.cc index 4e44c913cac..44ceecdf6e4 100644 --- a/engine/src/flutter/fml/platform/fuchsia/message_loop_fuchsia.cc +++ b/engine/src/flutter/fml/platform/fuchsia/message_loop_fuchsia.cc @@ -5,13 +5,16 @@ #include "flutter/fml/platform/fuchsia/message_loop_fuchsia.h" #include -#include #include namespace fml { MessageLoopFuchsia::MessageLoopFuchsia() - : loop_(&kAsyncLoopConfigAttachToCurrentThread) {} + : loop_(&kAsyncLoopConfigAttachToCurrentThread) { + auto handler = [this](async_dispatcher_t* dispatcher, async::Task* task, + zx_status_t status) { RunExpiredTasksNow(); }; + task_.set_handler(handler); +} MessageLoopFuchsia::~MessageLoopFuchsia() = default; @@ -30,8 +33,12 @@ void MessageLoopFuchsia::WakeUp(fml::TimePoint time_point) { due_time = zx::nsec((time_point - now).ToNanoseconds()); } - auto status = async::PostDelayedTask( - loop_.dispatcher(), [this]() { RunExpiredTasksNow(); }, due_time); + std::scoped_lock lock(task_mutex_); + + auto status = task_.Cancel(); + FML_DCHECK(status == ZX_OK || status == ZX_ERR_NOT_FOUND); + + status = task_.PostDelayed(loop_.dispatcher(), due_time); FML_DCHECK(status == ZX_OK); } diff --git a/engine/src/flutter/fml/platform/fuchsia/message_loop_fuchsia.h b/engine/src/flutter/fml/platform/fuchsia/message_loop_fuchsia.h index f54c587c4a2..b494d89761e 100644 --- a/engine/src/flutter/fml/platform/fuchsia/message_loop_fuchsia.h +++ b/engine/src/flutter/fml/platform/fuchsia/message_loop_fuchsia.h @@ -6,6 +6,7 @@ #define FLUTTER_FML_PLATFORM_FUCHSIA_MESSAGE_LOOP_FUCHSIA_H_ #include +#include #include "flutter/fml/macros.h" #include "flutter/fml/message_loop_impl.h" @@ -25,6 +26,8 @@ class MessageLoopFuchsia : public MessageLoopImpl { void WakeUp(fml::TimePoint time_point) override; async::Loop loop_; + std::mutex task_mutex_; + async::Task task_; FML_FRIEND_MAKE_REF_COUNTED(MessageLoopFuchsia); FML_FRIEND_REF_COUNTED_THREAD_SAFE(MessageLoopFuchsia);