diff --git a/internal/platform/implementation/windows/timer.cc b/internal/platform/implementation/windows/timer.cc index c27846ef..c4e35241 100644 --- a/internal/platform/implementation/windows/timer.cc +++ b/internal/platform/implementation/windows/timer.cc @@ -1,4 +1,4 @@ -// Copyright 2021 Google LLC +// Copyright 2021-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,10 +14,9 @@ #include "internal/platform/implementation/windows/timer.h" -#include - -#include "absl/synchronization/mutex.h" +#include "absl/functional/any_invocable.h" #include "internal/platform/logging.h" +#include "internal/platform/mutex_lock.h" namespace nearby { namespace windows { @@ -26,7 +25,7 @@ Timer::~Timer() { Stop(); } bool Timer::Create(int delay, int interval, absl::AnyInvocable callback) { - absl::MutexLock lock(&mutex_); + MutexLock lock(&mutex_); if ((delay < 0) || (interval < 0)) { NEARBY_LOGS(WARNING) << "Delay and interval shouldn\'t be negative value."; @@ -46,10 +45,17 @@ bool Timer::Create(int delay, int interval, delay_ = delay; interval_ = interval; callback_ = std::move(callback); + timer_callback_ = [&]() { + MutexLock lock(&mutex_); + if (timer_queue_handle_ != nullptr && callback_ != nullptr) { + callback_(); + } + }; if (!CreateTimerQueueTimer(&handle_, timer_queue_handle_, static_cast(TimerRoutine), - &callback_, delay, interval, WT_EXECUTEDEFAULT)) { + &timer_callback_, delay, interval, + WT_EXECUTEDEFAULT)) { if (!DeleteTimerQueueEx(timer_queue_handle_, nullptr)) { NEARBY_LOGS(ERROR) << "Failed to create timer in timer queue."; } @@ -61,7 +67,7 @@ bool Timer::Create(int delay, int interval, } bool Timer::Stop() { - absl::MutexLock lock(&mutex_); + MutexLock lock(&mutex_); if (timer_queue_handle_ == nullptr) { return true; @@ -86,7 +92,7 @@ bool Timer::Stop() { } bool Timer::FireNow() { - absl::MutexLock lock(&mutex_); + MutexLock lock(&mutex_); if (!timer_queue_handle_ || !callback_) { return false; @@ -101,8 +107,7 @@ bool Timer::FireNow() { << "Failed to fire the task due to cannot create executor."; return false; } - - task_executor_->Execute([&]() { callback_(); }); + task_executor_->Execute([&]() { timer_callback_(); }); return true; } diff --git a/internal/platform/implementation/windows/timer.h b/internal/platform/implementation/windows/timer.h index 8b9d9806..fe2d2ae9 100644 --- a/internal/platform/implementation/windows/timer.h +++ b/internal/platform/implementation/windows/timer.h @@ -1,4 +1,4 @@ -// Copyright 2021 Google LLC +// Copyright 2021-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,9 +20,10 @@ #include #include "absl/base/thread_annotations.h" -#include "absl/synchronization/mutex.h" +#include "absl/functional/any_invocable.h" #include "internal/platform/implementation/timer.h" #include "internal/platform/implementation/windows/submittable_executor.h" +#include "internal/platform/mutex.h" namespace nearby { namespace windows { @@ -41,10 +42,11 @@ class Timer : public api::Timer { private: static void CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired); - mutable absl::Mutex mutex_; + mutable RecursiveMutex mutex_; int delay_ ABSL_GUARDED_BY(mutex_); int interval_ ABSL_GUARDED_BY(mutex_); absl::AnyInvocable callback_; + absl::AnyInvocable timer_callback_ = nullptr; HANDLE handle_ ABSL_GUARDED_BY(mutex_) = nullptr; HANDLE timer_queue_handle_ ABSL_GUARDED_BY(mutex_) = nullptr; std::unique_ptr task_executor_ ABSL_GUARDED_BY(mutex_) = diff --git a/internal/platform/implementation/windows/timer_test.cc b/internal/platform/implementation/windows/timer_test.cc index 725397cd..be3e7964 100644 --- a/internal/platform/implementation/windows/timer_test.cc +++ b/internal/platform/implementation/windows/timer_test.cc @@ -1,4 +1,4 @@ -// Copyright 2021 Google LLC +// Copyright 2021-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,12 +14,8 @@ #include "internal/platform/implementation/timer.h" -#include // NOLINT -// NOLINT -#include -#include // NOLINT - #include "gtest/gtest.h" +#include "absl/time/time.h" #include "internal/platform/implementation/platform.h" namespace nearby { @@ -46,7 +42,7 @@ TEST(Timer, DISABLED_TestRepeatTimer) { ASSERT_TRUE(timer != nullptr); EXPECT_TRUE(timer->Create(300, 300, [&]() { ++count; })); - std::this_thread::sleep_for(std::chrono::seconds(1)); + absl::SleepFor(absl::Seconds(1)); EXPECT_TRUE(timer->Stop()); EXPECT_EQ(count, 3); } @@ -57,8 +53,27 @@ TEST(Timer, DISABLED_TestFireNow) { auto timer = nearby::api::ImplementationPlatform::CreateTimer(); EXPECT_TRUE(timer != nullptr); - EXPECT_TRUE(timer->Create(3000, 3000, [&]() { ++count; })); + EXPECT_TRUE(timer->Create(3000, 3000, [&]() { + absl::SleepFor(absl::Milliseconds(1000)); + ++count; + })); EXPECT_TRUE(timer->FireNow()); + absl::SleepFor(absl::Milliseconds(100)); + EXPECT_TRUE(timer->Stop()); + EXPECT_EQ(count, 1); +} + +TEST(Timer, DISABLED_TestWaitForRunningCallback) { + int count = 0; + + auto timer = nearby::api::ImplementationPlatform::CreateTimer(); + + EXPECT_TRUE(timer != nullptr); + EXPECT_TRUE(timer->Create(1000, 0, [&]() { + absl::SleepFor(absl::Milliseconds(3000)); + ++count; + })); + absl::SleepFor(absl::Milliseconds(1050)); EXPECT_TRUE(timer->Stop()); EXPECT_EQ(count, 1); }