Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qabstracteventdispatcher.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
7
8#include "qthread.h"
9#include <private/qthread_p.h>
10#include <private/qcoreapplication_p.h>
11#include <private/qfreelist_p.h>
12#include <private/qnumeric_p.h>
13
15
16using namespace std::chrono_literals;
17
18// we allow for 2^24 = 8^8 = 16777216 simultaneously running timers
20{
21 enum
22 {
24 BlockCount = 6
25 };
26
27 static const int Sizes[BlockCount];
28};
29
30enum {
31 Offset0 = 0x00000000,
32 Offset1 = 0x00000040,
33 Offset2 = 0x00000100,
34 Offset3 = 0x00001000,
35 Offset4 = 0x00010000,
36 Offset5 = 0x00100000,
37
44};
45
54
55typedef QFreeList<void, QtTimerIdFreeListConstants> QtTimerIdFreeList;
56Q_GLOBAL_STATIC(QtTimerIdFreeList, timerIdFreeList)
57
58template <typename T> static T fromDuration(std::chrono::nanoseconds interval)
59{
60 using namespace std::chrono;
61 qint64 value = ceil<milliseconds>(interval).count();
62 return qt_saturate<T>(value);
63}
64
65#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
67{
69 return static_cast<QAbstractEventDispatcherV2 *>(self);
70 return nullptr;
71}
72
73static inline const QAbstractEventDispatcherV2 *v2(const QAbstractEventDispatcher *self)
74{
76 return static_cast<const QAbstractEventDispatcherV2 *>(self);
77 return nullptr;
78}
79#endif // Qt 7
80
82{
83 // Create the timer ID free list here to make sure that it is destroyed
84 // after any global static thread that may be using it.
85 // See also QTBUG-58732.
86 if (!timerIdFreeList.isDestroyed())
87 (void)timerIdFreeList();
88}
89
91 = default;
92
94{
95 // This function may be called after timerIdFreeList() has been destructed
96 // for example in case when application exits without waiting for
97 // running threads to exit and running thread finished() has been connected
98 // to a slot which triggers a sequence that registers new timer.
99 // See https://bugreports.qt-project.org/browse/QTBUG-38957.
100 if (QtTimerIdFreeList *fl = timerIdFreeList())
101 return fl->next();
102 return 0; // Note! returning 0 generates a warning
103}
104
106{
107 // this function may be called by a global destructor after
108 // timerIdFreeList() has been destructed
109 if (QtTimerIdFreeList *fl = timerIdFreeList())
110 fl->release(timerId);
111}
112
165
172
178
193
258{
259 return int(registerTimer(interval * 1ms, timerType, object));
260}
261
270 QObject *object)
271{
273#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
274 if (QAbstractEventDispatcherV2 *self = v2(this))
275 self->registerTimer(id, interval, timerType, object);
276 else
277 registerTimer(qToUnderlying(id), fromDuration<qint64>(interval), timerType, object);
278#else
279 registerTimer(id, interval, timerType, object);
280#endif
281 return id;
282}
283
284#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
319#else // Qt 7
359#endif
360
395// ### DOC: Are these called when the _application_ starts/stops or just
396// when the current _event loop_ starts/stops?
402
408
501{
503
504 // clean up unused items in the list
505 d->eventFilters.removeAll(nullptr);
506 d->eventFilters.removeAll(filterObj);
507 d->eventFilters.prepend(filterObj);
508}
509
524{
526 for (int i = 0; i < d->eventFilters.size(); ++i) {
527 if (d->eventFilters.at(i) == filter) {
528 d->eventFilters[i] = nullptr;
529 break;
530 }
531 }
532}
533
554{
556 if (!d->eventFilters.isEmpty()) {
557 // Raise the loopLevel so that deleteLater() calls in or triggered
558 // by event_filter() will be processed from the main event loop.
559 QScopedScopeLevelCounter scopeLevelCounter(d->threadData.loadAcquire());
560 for (int i = 0; i < d->eventFilters.size(); ++i) {
561 QAbstractNativeEventFilter *filter = d->eventFilters.at(i);
562 if (!filter)
563 continue;
564 if (filter->nativeEventFilter(eventType, message, result))
565 return true;
566 }
567 }
568 return false;
569}
570
587#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
588void QAbstractEventDispatcher::registerTimer(Qt::TimerId timerId, Duration interval,
589 Qt::TimerType timerType, QObject *object)
590{
591 if (QAbstractEventDispatcherV2 *self = v2(this))
592 self->registerTimer(timerId, interval, timerType, object);
593 else
594 registerTimer(int(timerId), fromDuration<qint64>(interval), timerType, object);
595}
596
598{
599 if (QAbstractEventDispatcherV2 *self = v2(this))
600 return self->unregisterTimer(timerId);
601 return unregisterTimer(int(timerId));
602}
603
604QList<QAbstractEventDispatcher::TimerInfoV2>
606{
607 if (const QAbstractEventDispatcherV2 *self = v2(this))
608 return self->timersForObject(object);
609 QList<TimerInfo> timers = registeredTimers(object);
610 QList<TimerInfoV2> result;
611 result.reserve(timers.size());
612 for (const TimerInfo &t : timers)
613 result.emplaceBack(TimerInfoV2{ t.interval * 1ms, Qt::TimerId(t.timerId), t.timerType });
614 return result;
615}
616
619{
620 if (const QAbstractEventDispatcherV2 *self = v2(this))
621 return self->remainingTime(timerId);
622 return const_cast<QAbstractEventDispatcher *>(this)->remainingTime(int(timerId)) * 1ms;
623}
624
641QAbstractEventDispatcherV2::QAbstractEventDispatcherV2(QObject *parent)
643{
644}
645
649QAbstractEventDispatcherV2::QAbstractEventDispatcherV2(QAbstractEventDispatcherPrivate &dd,
650 QObject *parent)
651 : QAbstractEventDispatcher((dd.isV2 = true, dd), parent)
652{
653}
654
658QAbstractEventDispatcherV2::~QAbstractEventDispatcherV2() = default;
659
664void QAbstractEventDispatcherV2::registerTimer(int timerId, qint64 interval,
665 Qt::TimerType timerType, QObject *object)
666{
667 auto self = static_cast<QAbstractEventDispatcherV2 *>(this);
668 self->registerTimer(Qt::TimerId(timerId), interval * 1ms, timerType, object);
669}
670
676{
677 auto self = static_cast<QAbstractEventDispatcherV2 *>(this);
678 return self->unregisterTimer(Qt::TimerId(timerId));
679}
680
685auto QAbstractEventDispatcherV2::registeredTimers(QObject *object) const -> QList<TimerInfo>
686{
687 auto self = static_cast<const QAbstractEventDispatcherV2 *>(this);
688 QList<TimerInfoV2> timers = self->timersForObject(object);
689 QList<TimerInfo> result;
690 result.reserve(timers.size());
691 for (const TimerInfoV2 &t : timers)
692 result.emplaceBack(qToUnderlying(t.timerId), fromDuration<int>(t.interval), t.timerType);
693 return result;
694}
695
701{
702 auto self = static_cast<QAbstractEventDispatcherV2 *>(this);
703 return fromDuration<int>(self->remainingTime(Qt::TimerId(timerId)));
704}
705#endif // ! Qt 7
706
708
709#include "moc_qabstracteventdispatcher.cpp"
static QAbstractEventDispatcherPrivate * get(QAbstractEventDispatcher *o)
~QAbstractEventDispatcher()
Destroys the event dispatcher.
virtual Duration remainingTime(Qt::TimerId timerId) const =0
Returns the remaining time of the timer with the given timerId.
static QAbstractEventDispatcher * instance(QThread *thread=nullptr)
Returns a pointer to the event dispatcher object for the specified thread.
bool filterNativeEvent(const QByteArray &eventType, void *message, qintptr *result)
Sends message through the event filters that were set by installNativeEventFilter().
std::chrono::nanoseconds Duration
A {std::chrono::duration} type that is used in various API in this class.
virtual QList< TimerInfoV2 > timersForObject(QObject *object) const =0
void installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
\variable QAbstractEventDispatcher::TimerInfoV2::timerId
void removeNativeEventFilter(QAbstractNativeEventFilter *filterObj)
Removes the event filter filter from this object.
QAbstractEventDispatcher(QObject *parent=nullptr)
Constructs a new event dispatcher with the given parent.
virtual bool unregisterTimer(Qt::TimerId timerId)=0
Qt::TimerId registerTimer(Duration interval, Qt::TimerType timerType, QObject *object)
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
Definition qobject.h:103
QThread * thread() const
Returns the thread in which the object lives.
Definition qobject.cpp:1598
static Q_AUTOTEST_EXPORT QThreadData * current(bool createIfNecessary=true)
Definition qthread.cpp:1087
static QThreadData * get2(QThread *thread)
Definition qthread_p.h:291
Combined button and popup list for selecting options.
Definition qcompare.h:63
TimerType
QString self
Definition language.cpp:58
QFreeList< void, QtTimerIdFreeListConstants > QtTimerIdFreeList
static T fromDuration(std::chrono::nanoseconds interval)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
GLint GLfloat GLfloat GLfloat v2
GLenum GLuint id
[7]
GLuint object
[3]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLuint GLsizei const GLchar * message
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint64EXT * result
[6]
QT_BEGIN_NAMESPACE constexpr std::underlying_type_t< Enum > qToUnderlying(Enum e) noexcept
long long qint64
Definition qtypes.h:60
ptrdiff_t qintptr
Definition qtypes.h:166
list emplaceBack(3, 'a')
static const int Sizes[BlockCount]