File indexing completed on 2024-11-10 04:57:03
0001 /* 0002 SPDX-FileCopyrightText: 2019 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "clockskewnotifierengine_linux.h" 0008 0009 #include <QSocketNotifier> 0010 0011 #include <cerrno> 0012 #include <fcntl.h> 0013 #include <sys/timerfd.h> 0014 #include <unistd.h> 0015 0016 #ifndef TFD_TIMER_CANCEL_ON_SET // only available in newer glib 0017 #define TFD_TIMER_CANCEL_ON_SET (1 << 1) 0018 #endif 0019 0020 namespace KWin 0021 { 0022 0023 LinuxClockSkewNotifierEngine *LinuxClockSkewNotifierEngine::create(QObject *parent) 0024 { 0025 FileDescriptor fd{timerfd_create(CLOCK_REALTIME, O_CLOEXEC | O_NONBLOCK)}; 0026 if (!fd.isValid()) { 0027 qWarning("Couldn't create clock skew notifier engine: %s", strerror(errno)); 0028 return nullptr; 0029 } 0030 0031 const itimerspec spec = {}; 0032 const int ret = timerfd_settime(fd.get(), TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &spec, nullptr); 0033 if (ret == -1) { 0034 qWarning("Couldn't create clock skew notifier engine: %s", strerror(errno)); 0035 return nullptr; 0036 } 0037 return new LinuxClockSkewNotifierEngine(std::move(fd), parent); 0038 } 0039 0040 LinuxClockSkewNotifierEngine::LinuxClockSkewNotifierEngine(FileDescriptor &&fd, QObject *parent) 0041 : ClockSkewNotifierEngine(parent) 0042 , m_fd(std::move(fd)) 0043 { 0044 const QSocketNotifier *notifier = new QSocketNotifier(m_fd.get(), QSocketNotifier::Read, this); 0045 connect(notifier, &QSocketNotifier::activated, this, &LinuxClockSkewNotifierEngine::handleTimerCancelled); 0046 } 0047 0048 void LinuxClockSkewNotifierEngine::handleTimerCancelled() 0049 { 0050 uint64_t expirationCount; 0051 read(m_fd.get(), &expirationCount, sizeof(expirationCount)); 0052 0053 Q_EMIT clockSkewed(); 0054 } 0055 0056 } // namespace KWin 0057 0058 #include "moc_clockskewnotifierengine_linux.cpp"