Files
tdesktop/Telegram/lib_crl/crl/crl_time.cpp
allhaileris afb81b8278
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Close stale issues and PRs / stale (push) Successful in 13s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
init
2026-02-16 15:50:16 +03:00

96 lines
2.1 KiB
C++

// This file is part of Desktop App Toolkit,
// a set of libraries for developing nice desktop applications.
//
// For license and copyright information please follow this link:
// https://github.com/desktop-app/legal/blob/master/LEGAL
//
#include <crl/crl_time.h>
#include <atomic>
#include <ctime>
#include <limits>
namespace crl {
namespace details {
namespace {
time LastAdjustmentTime/* = 0*/;
std::time_t LastAdjustmentUnixtime/* = 0*/;
using seconds_type = std::uint32_t;
std::atomic<seconds_type> AdjustSeconds/* = 0*/;
inner_time_type StartValue/* = 0*/;
inner_profile_type StartProfileValue/* = 0*/;
struct StaticInit {
StaticInit();
};
StaticInit::StaticInit() {
StartValue = current_value();
StartProfileValue = current_profile_value();
init();
LastAdjustmentUnixtime = ::time(nullptr);
}
StaticInit StaticInitObject;
bool adjust_time() {
const auto now = crl::now();
const auto delta = (now - LastAdjustmentTime);
const auto unixtime = ::time(nullptr);
const auto real = (unixtime - LastAdjustmentUnixtime);
const auto seconds = (time(real) * 1000 - delta) / 1000;
LastAdjustmentUnixtime = unixtime;
LastAdjustmentTime = now;
if (seconds <= 0) {
return false;
}
auto current = seconds_type(0);
static constexpr auto max = std::numeric_limits<seconds_type>::max();
while (true) {
if (time(current) + seconds > time(max)) {
return false;
}
const auto next = current + seconds_type(seconds);
if (AdjustSeconds.compare_exchange_weak(current, next)) {
return true;
}
}
return false;
}
time compute_adjustment() {
return time(AdjustSeconds.load()) * 1000;
}
profile_time compute_profile_adjustment() {
return compute_adjustment() * 1000;
}
} // namespace
} // namespace details
time now() {
const auto elapsed = details::current_value() - details::StartValue;
return details::convert(elapsed) + details::compute_adjustment();
}
profile_time profile() {
const auto elapsed = details::current_profile_value()
- details::StartProfileValue;
return details::convert_profile(elapsed)
+ details::compute_profile_adjustment();
}
bool adjust_time() {
return details::adjust_time();
}
} // namespace crl