1/*
2 SPDX-FileCopyrightText: 2019 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-or-later
5*/
6
7#include "ksystemclockskewnotifierengine_linux.h"
8
9#include <QSocketNotifier>
10
11#include <cerrno>
12#include <fcntl.h>
13#include <sys/timerfd.h>
14#include <unistd.h>
15
16#ifndef TFD_TIMER_CANCEL_ON_SET // only available in newer glib
17#define TFD_TIMER_CANCEL_ON_SET (1 << 1)
18#endif
19
20std::shared_ptr<KLinuxSystemClockSkewNotifierEngine> KLinuxSystemClockSkewNotifierEngine::create()
21{
22 int fd = timerfd_create(CLOCK_REALTIME, O_CLOEXEC | O_NONBLOCK);
23 if (fd == -1) {
24 qWarning(msg: "Couldn't create clock skew notifier engine: %s", strerror(errno));
25 return nullptr;
26 }
27
28 const itimerspec spec = {};
29 const int ret = timerfd_settime(ufd: fd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, utmr: &spec, otmr: nullptr);
30 if (ret == -1) {
31 qWarning(msg: "Couldn't create clock skew notifier engine: %s", strerror(errno));
32 close(fd: fd);
33 return nullptr;
34 }
35 return std::make_shared<KLinuxSystemClockSkewNotifierEngine>(args&: fd);
36}
37
38KLinuxSystemClockSkewNotifierEngine::KLinuxSystemClockSkewNotifierEngine(int fd)
39 : m_fd(fd)
40{
41 const QSocketNotifier *notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
42 connect(sender: notifier, signal: &QSocketNotifier::activated, context: this, slot: &KLinuxSystemClockSkewNotifierEngine::handleTimerCancelled);
43}
44
45KLinuxSystemClockSkewNotifierEngine::~KLinuxSystemClockSkewNotifierEngine()
46{
47 close(fd: m_fd);
48}
49
50void KLinuxSystemClockSkewNotifierEngine::handleTimerCancelled()
51{
52 uint64_t expirationCount;
53 read(fd: m_fd, buf: &expirationCount, nbytes: sizeof(expirationCount));
54
55 Q_EMIT skewed();
56}
57
58#include "moc_ksystemclockskewnotifierengine_linux.cpp"
59

source code of kcoreaddons/src/lib/util/ksystemclockskewnotifierengine_linux.cpp