Fix timer cannot be restarted after firing.

PiperOrigin-RevId: 740450323
This commit is contained in:
Francis Tsui
2025-03-25 12:45:42 -07:00
committed by Copybara-Service
parent cee47d9f98
commit 979d6e5bc4
7 changed files with 57 additions and 29 deletions
+1 -1
View File
@@ -35,7 +35,7 @@ class Timer {
// @return Returns true if succeed, otherwise false is returned.
virtual bool Start(int delay, int period,
absl::AnyInvocable<void()> callback) = 0;
virtual bool Stop() = 0;
virtual void Stop() = 0;
virtual bool IsRunning() = 0;
virtual bool FireNow() = 0;
};
+7 -8
View File
@@ -16,7 +16,8 @@
#include <utility>
#include "absl/time/clock.h"
#include "absl/functional/any_invocable.h"
#include "internal/platform/implementation/platform.h"
#include "internal/platform/logging.h"
namespace nearby {
@@ -39,15 +40,13 @@ bool TimerImpl::Start(int delay, int period,
return true;
}
bool TimerImpl::Stop() {
void TimerImpl::Stop() {
if (internal_timer_ == nullptr) {
return true;
return;
}
if (internal_timer_->Stop()) {
internal_timer_ = nullptr;
return true;
}
return false;
// Stop returns false if timer has already fired. We can ignore that.
internal_timer_->Stop();
internal_timer_ = nullptr;
}
bool TimerImpl::IsRunning() { return (internal_timer_ != nullptr); }
+2 -2
View File
@@ -18,7 +18,7 @@
#include <memory>
#include "absl/functional/any_invocable.h"
#include "internal/platform/implementation/platform.h"
#include "internal/platform/implementation/timer.h"
#include "internal/platform/timer.h"
namespace nearby {
@@ -28,7 +28,7 @@ class TimerImpl : public Timer {
bool Start(int delay, int period,
absl::AnyInvocable<void()> callback) override;
bool Stop() override;
void Stop() override;
bool IsRunning() override;
bool FireNow() override;
+34 -4
View File
@@ -15,6 +15,8 @@
#include "internal/platform/timer_impl.h"
#include "gtest/gtest.h"
#include "absl/synchronization/notification.h"
#include "absl/time/time.h"
namespace nearby {
namespace {
@@ -24,7 +26,7 @@ TEST(TimerImpl, TestCreateTimer) {
EXPECT_FALSE(timer.Start(-100, 0, nullptr));
EXPECT_TRUE(timer.Start(100, 100, []() {}));
EXPECT_TRUE(timer.Stop());
timer.Stop();
}
TEST(TimerImpl, TestRunningStatus) {
@@ -32,7 +34,7 @@ TEST(TimerImpl, TestRunningStatus) {
EXPECT_TRUE(timer.Start(100, 100, []() {}));
EXPECT_TRUE(timer.IsRunning());
EXPECT_TRUE(timer.Stop());
timer.Stop();
EXPECT_FALSE(timer.IsRunning());
}
@@ -41,7 +43,7 @@ TEST(TimerImpl, TestStartRunningTimer) {
EXPECT_TRUE(timer.Start(100, 100, []() {}));
EXPECT_FALSE(timer.Start(100, 100, []() {}));
EXPECT_TRUE(timer.Stop());
timer.Stop();
}
TEST(TimerImpl, TestFireNow) {
@@ -50,9 +52,37 @@ TEST(TimerImpl, TestFireNow) {
EXPECT_TRUE(timer.Start(100, 100, [&count]() { ++count; }));
EXPECT_TRUE(timer.FireNow());
EXPECT_TRUE(timer.Stop());
timer.Stop();
EXPECT_EQ(count, 1);
}
TEST(TimerImpl, TestStopAfterFire) {
TimerImpl timer;
absl::Notification notification;
EXPECT_TRUE(timer.Start(0, 0, [&notification]() {
notification.Notify();
}));
notification.WaitForNotificationWithTimeout(absl::Seconds(1));
timer.Stop();
}
TEST(TimerImpl, TestRestartAfterFire) {
TimerImpl timer;
absl::Notification notification;
EXPECT_TRUE(timer.Start(0, 0, [&notification]() {
notification.Notify();
}));
notification.WaitForNotificationWithTimeout(absl::Seconds(1));
timer.Stop();
absl::Notification notification2;
EXPECT_TRUE(timer.Start(100, 100, [&notification2]() {
notification2.Notify();
}));
notification2.WaitForNotificationWithTimeout(absl::Seconds(1));
timer.Stop();
}
} // namespace
} // namespace nearby
+4 -5
View File
@@ -36,9 +36,9 @@ bool FakeTimer::Start(int delay, int period,
return InternalStart(delay, period, std::move(callback));
}
bool FakeTimer::Stop() {
void FakeTimer::Stop() {
MutexLock lock(&mutex_);
return InternalStop();
InternalStop();
}
bool FakeTimer::IsRunning() {
@@ -115,13 +115,12 @@ bool FakeTimer::InternalStart(int delay, int period,
return true;
}
bool FakeTimer::InternalStop() {
void FakeTimer::InternalStop() {
if (timer_data_.id.empty()) {
return true;
return;
}
clock_->RemoveObserver(timer_data_.id);
timer_data_ = {};
return true;
}
} // namespace nearby
+2 -2
View File
@@ -31,7 +31,7 @@ class FakeTimer : public Timer {
bool Start(int delay, int period,
absl::AnyInvocable<void()> callback) override;
bool Stop() override;
void Stop() override;
bool IsRunning() override;
bool FireNow() override;
@@ -49,7 +49,7 @@ class FakeTimer : public Timer {
void ClockUpdated();
bool InternalStart(int delay, int period,
absl::AnyInvocable<void()> callback);
bool InternalStop();
void InternalStop();
mutable RecursiveMutex mutex_;
FakeClock* clock_ = nullptr;
+7 -7
View File
@@ -32,7 +32,7 @@ TEST(FakeTimer, TestOneTimeTimer) {
EXPECT_TRUE(timer.IsRunning());
clock.FastForward(absl::Milliseconds(1000));
EXPECT_EQ(count, 1);
EXPECT_TRUE(timer.Stop());
timer.Stop();
EXPECT_FALSE(timer.IsRunning());
}
@@ -45,7 +45,7 @@ TEST(FakeTimer, TestRepeatTimer) {
EXPECT_TRUE(timer.IsRunning());
clock.FastForward(absl::Milliseconds(1000));
EXPECT_EQ(count, 10);
EXPECT_TRUE(timer.Stop());
timer.Stop();
EXPECT_FALSE(timer.IsRunning());
}
@@ -56,7 +56,7 @@ TEST(FakeTimer, TestInvalidInput) {
auto callback = [&count]() { ++count; };
timer.Start(-100, 100, callback);
EXPECT_FALSE(timer.IsRunning());
EXPECT_TRUE(timer.Stop());
timer.Stop();
}
TEST(FakeTimer, TestStopTimerBeforeClockUpdate) {
@@ -66,7 +66,7 @@ TEST(FakeTimer, TestStopTimerBeforeClockUpdate) {
auto callback = [&count]() { ++count; };
timer.Start(100, 100, callback);
EXPECT_TRUE(timer.IsRunning());
EXPECT_TRUE(timer.Stop());
timer.Stop();
EXPECT_FALSE(timer.IsRunning());
clock.FastForward(absl::Milliseconds(1000));
EXPECT_EQ(count, 0);
@@ -85,7 +85,7 @@ TEST(FakeTimer, TestUpdateMultipleTimesClockForOnetimeTimer) {
EXPECT_EQ(count, 1);
clock.FastForward(absl::Milliseconds(1000));
EXPECT_EQ(count, 1);
EXPECT_TRUE(timer.Stop());
timer.Stop();
EXPECT_FALSE(timer.IsRunning());
}
@@ -98,7 +98,7 @@ TEST(FakeTimer, TestInstantRunTimer) {
EXPECT_TRUE(timer.IsRunning());
clock.FastForward(absl::Milliseconds(1000));
EXPECT_EQ(count, 11);
EXPECT_TRUE(timer.Stop());
timer.Stop();
EXPECT_FALSE(timer.IsRunning());
}
@@ -112,7 +112,7 @@ TEST(FakeTimer, TestTimerDestructor) {
EXPECT_EQ(clock.GetObserversCount(), 1);
EXPECT_TRUE(timer.IsRunning());
EXPECT_EQ(count, 0);
EXPECT_TRUE(timer.Stop());
timer.Stop();
EXPECT_FALSE(timer.IsRunning());
}
EXPECT_EQ(clock.GetObserversCount(), 0);