init
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
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
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
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
95
Telegram/lib_crl/crl/crl_time.cpp
Normal file
95
Telegram/lib_crl/crl/crl_time.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
// 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
|
||||
Reference in New Issue
Block a user