refractored timer to match windows impl

This commit is contained in:
Lasan Mahaliyana
2026-03-16 00:14:07 +05:30
parent c8c9d80abd
commit f62348a4e5
2 changed files with 39 additions and 31 deletions
+38 -27
View File
@@ -20,27 +20,34 @@
#include <ctime>
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/linux/submittable_executor.h"
#include "internal/platform/implementation/linux/timer.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace linux {
namespace {
timespec MillisToTimespec(int milliseconds) {
if (milliseconds < 0) {
milliseconds = 0;
}
timespec ts{};
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = static_cast<long>(milliseconds % 1000) * 1000000L;
return ts;
}
} // namespace
static void timer_callback(union sigval val) {
absl::AnyInvocable<void()> *callback =
reinterpret_cast<absl::AnyInvocable<void()> *>(val.sival_ptr);
if (*callback != nullptr) (*callback)();
}
Timer::~Timer() {
absl::MutexLock l(&mutex_);
if (timerid_.has_value())
if (timer_delete(*timerid_) < 0) {
LOG(ERROR) << __func__ << ": Error deleting POSIX timer: "
<< std::strerror(errno);
}
}
Timer::~Timer() { Stop(); }
bool Timer::Create(int delay, int interval,
absl::AnyInvocable<void()> callback) {
@@ -52,26 +59,29 @@ bool Timer::Create(int delay, int interval,
absl::MutexLock l(&mutex_);
if (timerid_.has_value()) {
LOG(ERROR) << __func__
<< "Timer has already been created and armed.";
return false;
if (timer_delete(*timerid_) < 0) {
if (errno != EINVAL) {
LOG(ERROR) << __func__ << ": Error deleting stale POSIX timer: "
<< std::strerror(errno);
return false;
}
}
timerid_.reset();
}
callback_ = std::move(callback);
struct sigevent ev;
struct sigevent ev{};
ev.sigev_notify = SIGEV_THREAD;
ev.sigev_value.sival_ptr = &callback_;
ev.sigev_notify_function = timer_callback;
ev.sigev_notify_attributes = nullptr;
timer_t timerid;
struct itimerspec spec;
spec.it_value.tv_nsec = delay * 1000000;
spec.it_value.tv_sec = 0;
spec.it_interval.tv_nsec = interval * 1000000;
spec.it_interval.tv_sec = 0;
struct itimerspec spec{};
spec.it_value = MillisToTimespec(delay);
spec.it_interval = MillisToTimespec(interval);
if (timer_create(CLOCK_MONOTONIC, &ev, &timerid) < 0) {
LOG(ERROR) << __func__ << ": Error creating POSIX timer: "
@@ -79,10 +89,10 @@ bool Timer::Create(int delay, int interval,
return false;
}
if (timer_settime(&timerid, 0, &spec, nullptr) < 0) {
if (timer_settime(timerid, 0, &spec, nullptr) < 0) {
LOG(ERROR) << __func__ << ": Error arming POSIX timer: "
<< std::strerror(errno);
if (!timer_delete(&timerid)) {
if (timer_delete(timerid) < 0) {
LOG(ERROR) << __func__ << ": error deleting POSIX timer: "
<< std::strerror(errno);
}
@@ -96,14 +106,15 @@ bool Timer::Create(int delay, int interval,
bool Timer::Stop() {
absl::MutexLock l(&mutex_);
if (!timerid_.has_value()) {
LOG(WARNING) << __func__ << ": no timer created";
return true;
}
if (!timer_delete(&*timerid_)) {
LOG(ERROR) << __func__ << ": error deleting POSIX timer: "
<< std::strerror(errno);
return false;
if (timer_delete(*timerid_) < 0) {
if (errno != EINVAL) {
LOG(ERROR) << __func__ << ": error deleting POSIX timer: "
<< std::strerror(errno);
return false;
}
}
timerid_.reset();
@@ -17,12 +17,10 @@
#include <signal.h>
#include <time.h>
#include <memory>
#include <optional>
#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/linux/submittable_executor.h"
#include "internal/platform/implementation/timer.h"
namespace nearby {
@@ -30,7 +28,7 @@ namespace linux {
class Timer : public api::Timer {
public:
Timer() : timerid_(nullptr){};
Timer() : timerid_(nullptr) {}
~Timer() override;
bool Create(int delay, int interval,
@@ -42,7 +40,6 @@ class Timer : public api::Timer {
absl::Mutex mutex_;
std::optional<timer_t> timerid_ ABSL_GUARDED_BY(mutex_);
absl::AnyInvocable<void()> callback_;
std::unique_ptr<SubmittableExecutor> task_executor_;
};
} // namespace linux