Add a timeout to Future

Future has a `Get(Duration)` method which allows us to wait synchronously until
a timeout.
Adding a timeout to the constructor allows the Future to time out
asynchronously.

PiperOrigin-RevId: 516982717
This commit is contained in:
Janusz Sobczak
2023-03-15 18:18:54 -07:00
committed by Copybara-Service
parent c2d8d44767
commit a70826dbf8
5 changed files with 95 additions and 11 deletions
@@ -42,6 +42,7 @@ cc_library(
"//internal/platform/implementation:types",
"//internal/platform/implementation/shared:count_down_latch",
"//internal/platform/implementation/shared:posix_mutex",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
+31 -10
View File
@@ -15,8 +15,13 @@
#ifndef PLATFORM_IMPL_G3_TIMER_H_
#define PLATFORM_IMPL_G3_TIMER_H_
#include <atomic>
#include <memory>
#include <utility>
#include "absl/base/thread_annotations.h"
#include "absl/time/time.h"
#include "internal/platform/implementation/g3/scheduled_executor.h"
#include "internal/platform/implementation/timer.h"
namespace nearby {
@@ -29,39 +34,55 @@ class Timer : public api::Timer {
bool Create(int delay, int interval,
absl::AnyInvocable<void()> callback) override {
if (delay < 0 || interval < 0) {
if (delay < 0 || interval < 0 || callback == nullptr) {
return false;
}
interval_ = absl::Milliseconds(interval);
callback_ = std::move(callback);
is_stopped_ = false;
return true;
return Schedule(absl::Milliseconds(delay));
}
bool Stop() override {
is_stopped_ = true;
return true;
absl::MutexLock lock(&mutex_);
if (task_) {
bool result = task_->Cancel();
task_.reset();
return result;
}
return false;
}
bool FireNow() override {
if (is_stopped_ || !callback_) {
if (is_stopped_) {
return false;
}
callback_();
return true;
}
// Mocked methods for test only
void TriggerCallback() {
if (is_stopped_ || callback_ == nullptr) {
return;
}
private:
bool Schedule(absl::Duration delay) {
if (delay == absl::ZeroDuration()) return false;
absl::MutexLock lock(&mutex_);
task_ = executor_.Schedule([this]() { TriggerCallback(); }, delay);
return true;
}
void TriggerCallback() {
if (is_stopped_) return;
Schedule(interval_);
callback_();
}
private:
absl::Mutex mutex_;
absl::AnyInvocable<void()> callback_;
bool is_stopped_ = false;
std::atomic_bool is_stopped_;
absl::Duration interval_;
std::shared_ptr<api::Cancelable> task_ ABSL_GUARDED_BY(mutex_);
ScheduledExecutor executor_;
};
} // namespace g3