mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
internal update
PiperOrigin-RevId: 549351164
This commit is contained in:
committed by
Copybara-Service
parent
be5c5b77bd
commit
c6566b00c7
@@ -47,6 +47,7 @@ cc_library(
|
||||
"//internal/platform/implementation:types",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/functional:any_invocable",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
@@ -76,6 +77,7 @@ cc_test(
|
||||
":test",
|
||||
"//internal/data:data_manager",
|
||||
"//internal/network:types",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation:types",
|
||||
"//internal/platform/implementation/g3", # fixdeps: keep
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
|
||||
@@ -76,4 +76,9 @@ int FakeClock::GetObserversCount() {
|
||||
return observers_.size();
|
||||
}
|
||||
|
||||
void FakeClock::Reset() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return observers_.clear();
|
||||
}
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
@@ -45,6 +45,8 @@ class FakeClock : public Clock {
|
||||
|
||||
int GetObserversCount() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
void Reset() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
private:
|
||||
mutable absl::Mutex mutex_;
|
||||
absl::Time now_ ABSL_GUARDED_BY(mutex_);
|
||||
|
||||
@@ -35,6 +35,18 @@ TEST(FakeClock, TestFastForward) {
|
||||
EXPECT_EQ(clock.GetObserversCount(), 0);
|
||||
}
|
||||
|
||||
TEST(FakeClock, TestReset) {
|
||||
FakeClock clock;
|
||||
int count = 0;
|
||||
auto observer = [&count]() { count++; };
|
||||
clock.AddObserver("test", observer);
|
||||
clock.FastForward(absl::Nanoseconds(1500));
|
||||
EXPECT_EQ(count, 1);
|
||||
EXPECT_EQ(clock.GetObserversCount(), 1);
|
||||
clock.Reset();
|
||||
EXPECT_EQ(clock.GetObserversCount(), 0);
|
||||
}
|
||||
|
||||
TEST(FakeClock, TestObserver) {
|
||||
FakeClock clock;
|
||||
int count = 0;
|
||||
|
||||
+70
-42
@@ -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.
|
||||
@@ -18,82 +18,110 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/mutex_lock.h"
|
||||
|
||||
namespace nearby {
|
||||
|
||||
FakeTimer::FakeTimer(FakeClock* clock) : clock_(clock) {
|
||||
id_ = std::to_string(absl::ToUnixNanos(absl::Now()));
|
||||
clock_->AddObserver(id_, [this]() { ClockUpdated(); });
|
||||
}
|
||||
FakeTimer::FakeTimer(FakeClock* clock) : clock_(clock) {}
|
||||
|
||||
FakeTimer::~FakeTimer() { clock_->RemoveObserver(id_); }
|
||||
FakeTimer::~FakeTimer() { Stop(); }
|
||||
|
||||
bool FakeTimer::Start(int delay, int period,
|
||||
absl::AnyInvocable<void()> callback) {
|
||||
if (is_started_ || delay < 0 || period < 0) {
|
||||
return false;
|
||||
}
|
||||
delay_ = delay;
|
||||
period_ = period;
|
||||
callback_ = std::move(callback);
|
||||
start_time_ = clock_->Now();
|
||||
fired_count_ = 0;
|
||||
is_started_ = true;
|
||||
|
||||
return true;
|
||||
MutexLock lock(&mutex_);
|
||||
return InternalStart(delay, period, std::move(callback));
|
||||
}
|
||||
|
||||
bool FakeTimer::Stop() {
|
||||
is_started_ = false;
|
||||
return true;
|
||||
MutexLock lock(&mutex_);
|
||||
return InternalStop();
|
||||
}
|
||||
|
||||
bool FakeTimer::IsRunning() { return is_started_; }
|
||||
bool FakeTimer::IsRunning() {
|
||||
MutexLock lock(&mutex_);
|
||||
return !timer_data_.id.empty();
|
||||
}
|
||||
|
||||
void FakeTimer::ClockUpdated() {
|
||||
if (!is_started_) {
|
||||
MutexLock lock(&mutex_);
|
||||
TimerData timer_data = timer_data_;
|
||||
if (timer_data.id.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
absl::Time now = clock_->Now();
|
||||
int64_t duration = absl::ToInt64Milliseconds(now - start_time_);
|
||||
FakeClock* clock = clock_;
|
||||
// The timer may be released during callback, save period and delay to avoid
|
||||
// access exception.
|
||||
int period = period_;
|
||||
int delay = delay_;
|
||||
|
||||
if (duration >= delay_ && fired_count_ == 0) {
|
||||
++fired_count_;
|
||||
if (callback_ != nullptr) {
|
||||
callback_();
|
||||
if (!timer_data.is_delay_called &&
|
||||
timer_data.last_time == timer_data.create_time &&
|
||||
timer_data.last_time + absl::Milliseconds(timer_data.delay) <= now) {
|
||||
timer_data.callback();
|
||||
if (timer_data.id == timer_data_.id) {
|
||||
timer_data.is_delay_called = true;
|
||||
timer_data.last_time =
|
||||
timer_data.last_time + absl::Milliseconds(timer_data.delay);
|
||||
timer_data_ = timer_data;
|
||||
}
|
||||
}
|
||||
|
||||
if (period == 0 || duration < delay ||
|
||||
((clock_ != nullptr) && (clock_ != clock))) {
|
||||
if (timer_data.period == 0 || timer_data.id != timer_data_.id) {
|
||||
// timer is changed during callback.
|
||||
return;
|
||||
}
|
||||
|
||||
int count = (duration - delay) / period;
|
||||
int should_fire_count = count - fired_count_ + 1;
|
||||
for (int i = 0; i < should_fire_count; ++i) {
|
||||
++fired_count_;
|
||||
if (callback_ != nullptr) {
|
||||
callback_();
|
||||
timer_data_ = timer_data;
|
||||
while (timer_data.last_time + absl::Milliseconds(timer_data.period) <= now) {
|
||||
timer_data.callback();
|
||||
if (timer_data.id == timer_data_.id) {
|
||||
timer_data.last_time += absl::Milliseconds(timer_data.period);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
timer_data_ = timer_data;
|
||||
}
|
||||
|
||||
bool FakeTimer::FireNow() {
|
||||
if (IsRunning() && callback_) {
|
||||
callback_();
|
||||
if (IsRunning()) {
|
||||
timer_data_.callback();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FakeTimer::InternalStart(int delay, int period,
|
||||
absl::AnyInvocable<void()> callback) {
|
||||
if (delay < 0 || period < 0 || callback == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!timer_data_.id.empty()) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": timer is already running";
|
||||
return false;
|
||||
}
|
||||
|
||||
timer_data_.id = std::to_string(absl::ToUnixNanos(absl::Now()));
|
||||
timer_data_.delay = delay;
|
||||
timer_data_.period = period;
|
||||
callback_ = std::move(callback);
|
||||
timer_data_.callback = [&]() { callback_(); };
|
||||
timer_data_.create_time = clock_->Now();
|
||||
timer_data_.last_time = timer_data_.create_time;
|
||||
clock_->AddObserver(timer_data_.id, [this]() { ClockUpdated(); });
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FakeTimer::InternalStop() {
|
||||
if (timer_data_.id.empty()) {
|
||||
return true;
|
||||
}
|
||||
clock_->RemoveObserver(timer_data_.id);
|
||||
timer_data_ = {};
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
@@ -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.
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "internal/platform/mutex.h"
|
||||
#include "internal/platform/timer.h"
|
||||
#include "internal/test/fake_clock.h"
|
||||
|
||||
@@ -35,16 +36,25 @@ class FakeTimer : public Timer {
|
||||
bool FireNow() override;
|
||||
|
||||
private:
|
||||
void ClockUpdated();
|
||||
struct TimerData {
|
||||
std::string id;
|
||||
int delay;
|
||||
int period;
|
||||
bool is_delay_called = false;
|
||||
absl::Time create_time;
|
||||
absl::Time last_time;
|
||||
std::function<void()> callback;
|
||||
};
|
||||
|
||||
std::string id_;
|
||||
int delay_ = 0;
|
||||
int period_ = 0;
|
||||
int fired_count_ = 0;
|
||||
absl::Time start_time_;
|
||||
bool is_started_ = false;
|
||||
absl::AnyInvocable<void()> callback_;
|
||||
void ClockUpdated();
|
||||
bool InternalStart(int delay, int period,
|
||||
absl::AnyInvocable<void()> callback);
|
||||
bool InternalStop();
|
||||
|
||||
mutable RecursiveMutex mutex_;
|
||||
FakeClock* clock_ = nullptr;
|
||||
TimerData timer_data_;
|
||||
absl::AnyInvocable<void()> callback_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
@@ -14,10 +14,11 @@
|
||||
|
||||
#include "internal/test/fake_timer.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/test/fake_task_runner.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace {
|
||||
@@ -105,10 +106,10 @@ TEST(FakeTimer, TestTimerDestructor) {
|
||||
FakeClock clock;
|
||||
{
|
||||
FakeTimer timer(&clock);
|
||||
EXPECT_EQ(clock.GetObserversCount(), 1);
|
||||
int count = 0;
|
||||
auto callback = [&count]() { ++count; };
|
||||
timer.Start(100, 0, callback);
|
||||
EXPECT_EQ(clock.GetObserversCount(), 1);
|
||||
EXPECT_TRUE(timer.IsRunning());
|
||||
EXPECT_EQ(count, 0);
|
||||
EXPECT_TRUE(timer.Stop());
|
||||
@@ -160,5 +161,25 @@ TEST(FakeTimer, StartTimerInTimerProc) {
|
||||
EXPECT_EQ(count, 2);
|
||||
}
|
||||
|
||||
TEST(FakeTimer, WaitForRunningTask) {
|
||||
bool finish = false;
|
||||
FakeClock clock;
|
||||
FakeTimer timer1(&clock);
|
||||
FakeTaskRunner task_runner{&clock, 1};
|
||||
|
||||
timer1.Start(50, 0, [&]() {
|
||||
absl::SleepFor(absl::Milliseconds(2000));
|
||||
finish = true;
|
||||
});
|
||||
|
||||
task_runner.PostTask([&]() {
|
||||
absl::SleepFor(absl::Milliseconds(10));
|
||||
timer1.Stop();
|
||||
EXPECT_TRUE(finish);
|
||||
});
|
||||
|
||||
clock.FastForward(absl::Milliseconds(50));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby
|
||||
|
||||
Reference in New Issue
Block a user