File indexing completed on 2024-11-17 05:15:20
0001 /* 0002 * Copyright 2020 Han Young <hanyoung@protonmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "alarmwaitworker.h" 0008 0009 #include <QDateTime> 0010 #include <QDebug> 0011 0012 #include <poll.h> 0013 #include <sys/timerfd.h> 0014 #include <unistd.h> 0015 0016 AlarmWaitWorker::AlarmWaitWorker(quint64 timestamp) 0017 : m_timerFd{timerfd_create(CLOCK_REALTIME, 0)} 0018 , m_waitEndTime{timestamp} 0019 { 0020 connect(this, &AlarmWaitWorker::startWait, this, &AlarmWaitWorker::wait); 0021 } 0022 0023 void AlarmWaitWorker::wait(int waitId) 0024 { 0025 if (m_waitEndTime == 0) { 0026 return; 0027 } 0028 0029 struct itimerspec timerSpec; 0030 timerSpec.it_value.tv_sec = static_cast<long>(m_waitEndTime); 0031 timerSpec.it_value.tv_nsec = 0; 0032 timerSpec.it_interval.tv_sec = 0; 0033 timerSpec.it_interval.tv_nsec = 0; 0034 0035 timerfd_settime(m_timerFd, TFD_TIMER_ABSTIME, &timerSpec, nullptr); // absolute time 0036 0037 struct pollfd fd; // only one fd 0038 fd.fd = m_timerFd; 0039 fd.events = POLLIN | POLLPRI; 0040 0041 poll(&fd, 1, -1); 0042 0043 if (fd.revents & POLLNVAL) { 0044 Q_EMIT error(); 0045 return; 0046 } 0047 // ensure that there is one wakeup and not multiple 0048 if (waitId != this->m_waitId) { 0049 qDebug() << "cancel old wakeup" << waitId; 0050 return; 0051 } 0052 0053 qDebug() << "waiting end" << waitId; 0054 0055 Q_EMIT finished(); 0056 } 0057 0058 void AlarmWaitWorker::setNewTime(quint64 timestamp) 0059 { 0060 m_waitId = std::rand(); 0061 0062 m_waitEndTime = timestamp; 0063 struct itimerspec timerSpec; 0064 timerSpec.it_value.tv_sec = static_cast<long>(m_waitEndTime); 0065 timerSpec.it_value.tv_nsec = 0; 0066 timerSpec.it_interval.tv_sec = 0; 0067 timerSpec.it_interval.tv_nsec = 0; 0068 timerfd_settime(m_timerFd, TFD_TIMER_ABSTIME, &timerSpec, nullptr); // absolute time 0069 0070 qDebug() << "start waiting, id:" << m_waitId << " Wait Time:" << timestamp; 0071 0072 Q_EMIT startWait(m_waitId); 0073 }