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 }