Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
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// Qt-Security score:significant reason:default
4
8
9#include "qthread.h"
10#include <private/qthread_p.h>
11#include <private/qcoreapplication_p.h>
12#include <private/qfreelist_p.h>
13
14#include <QtCore/q26numeric.h>
15
17
18using namespace std::chrono_literals;
19
20// we allow for 2^24 = 8^8 = 16777216 simultaneously running timers
22{
23 enum
24 {
27 };
28
29 static const int Sizes[BlockCount];
30};
31
32enum {
33 Offset0 = 0x00000000,
34 Offset1 = 0x00000040,
35 Offset2 = 0x00000100,
36 Offset3 = 0x00001000,
37 Offset4 = 0x00010000,
38 Offset5 = 0x00100000,
39
45 Size5 = QtTimerIdFreeListConstants::MaxIndex - Offset5
46};
47
56
58Q_GLOBAL_STATIC(QtTimerIdFreeList, timerIdFreeList)
59
60template <typename T> static T fromDuration(std::chrono::nanoseconds interval)
61{
62 using namespace std::chrono;
63 qint64 value = ceil<milliseconds>(interval).count();
64 return q26::saturate_cast<T>(value);
65}
66
67#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
68static inline QAbstractEventDispatcherV2 *v2(QAbstractEventDispatcher *self)
69{
70 if (QAbstractEventDispatcherPrivate::get(self)->isV2)
71 return static_cast<QAbstractEventDispatcherV2 *>(self);
72 return nullptr;
73}
74
75static inline const QAbstractEventDispatcherV2 *v2(const QAbstractEventDispatcher *self)
76{
77 if (QAbstractEventDispatcherPrivate::get(self)->isV2)
78 return static_cast<const QAbstractEventDispatcherV2 *>(self);
79 return nullptr;
80}
81#endif // Qt 7
82
83QAbstractEventDispatcherPrivate::QAbstractEventDispatcherPrivate()
84{
85 // Create the timer ID free list here to make sure that it is destroyed
86 // after any global static thread that may be using it.
87 // See also QTBUG-58732.
88 if (!timerIdFreeList.isDestroyed())
89 (void)timerIdFreeList();
90}
91
92QAbstractEventDispatcherPrivate::~QAbstractEventDispatcherPrivate()
93 = default;
94
95Qt::TimerId QAbstractEventDispatcherPrivate::allocateTimerId()
96{
97 // This function may be called after timerIdFreeList() has been destructed
98 // for example in case when application exits without waiting for
99 // running threads to exit and running thread finished() has been connected
100 // to a slot which triggers a sequence that registers new timer.
101 // See https://bugreports.qt-project.org/browse/QTBUG-38957.
102 if (QtTimerIdFreeList *fl = timerIdFreeList())
103 return Qt::TimerId{fl->next()};
104 return Qt::TimerId{0}; // Note! returning 0 generates a warning
105}
106
107void QAbstractEventDispatcherPrivate::releaseTimerId(Qt::TimerId timerId)
108{
109 // this function may be called by a global destructor after
110 // timerIdFreeList() has been destructed
111 if (QtTimerIdFreeList *fl = timerIdFreeList())
112 fl->release(qToUnderlying(timerId));
113}
114
115/*!
116 \class QAbstractEventDispatcher
117 \inmodule QtCore
118 \brief The QAbstractEventDispatcher class provides an interface to manage Qt's event queue.
119
120 \ingroup events
121
122 An event dispatcher receives events from the window system and other
123 sources. It then sends them to the QCoreApplication or QApplication
124 instance for processing and delivery. QAbstractEventDispatcher provides
125 fine-grained control over event delivery.
126
127 For simple control of event processing use
128 QCoreApplication::processEvents().
129
130 For finer control of the application's event loop, call
131 instance() and call functions on the QAbstractEventDispatcher
132 object that is returned. If you want to use your own instance of
133 QAbstractEventDispatcher or of a QAbstractEventDispatcher
134 subclass, you must install it with QCoreApplication::setEventDispatcher()
135 or QThread::setEventDispatcher() \e before a default event dispatcher has
136 been installed.
137
138 The main event loop is started by calling
139 QCoreApplication::exec(), and stopped by calling
140 QCoreApplication::exit(). Local event loops can be created using
141 QEventLoop.
142
143 Programs that perform long operations can call processEvents()
144 with a bitwise OR combination of various QEventLoop::ProcessEventsFlag
145 values to control which events should be delivered.
146
147 QAbstractEventDispatcher also allows the integration of an
148 external event loop with the Qt event loop.
149
150 \sa QEventLoop, QCoreApplication, QThread
151*/
152/*!
153 \typedef QAbstractEventDispatcher::Duration
154
155 A \c{std::chrono::duration} type that is used in various API in this class.
156 This type exists to facilitate a possible transition to a higher or lower
157 granularity.
158
159 In all current platforms, it is \c nanoseconds.
160*/
161
162/*!
163 Constructs a new event dispatcher with the given \a parent.
164*/
165QAbstractEventDispatcher::QAbstractEventDispatcher(QObject *parent)
166 : QObject(*new QAbstractEventDispatcherPrivate, parent) {}
167
168/*!
169 \internal
170*/
171QAbstractEventDispatcher::QAbstractEventDispatcher(QAbstractEventDispatcherPrivate &dd,
172 QObject *parent)
173 : QObject(dd, parent) {}
174
175/*!
176 Destroys the event dispatcher.
177*/
178QAbstractEventDispatcher::~QAbstractEventDispatcher()
179{
180 // don't recreate the QThreadData if it has already been destroyed
181 QThreadData *data = QThreadData::currentThreadData();
182 if (data && data->eventDispatcher.loadRelaxed() == this)
183 data->eventDispatcher.storeRelaxed(nullptr);
184}
185
186/*!
187 Returns a pointer to the event dispatcher object for the specified
188 \a thread. If \a thread is \nullptr, the current thread is used. If no
189 event dispatcher exists for the specified thread, this function
190 returns \nullptr.
191
192 \b{Note:} If Qt is built without thread support, the \a thread
193 argument is ignored.
194 */
195QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
196{
197 // do create a QThreadData, in case this is very early in an adopted thread
198 QThreadData *data = thread ? QThreadData::get2(thread) : QThreadData::current();
199 return data->eventDispatcher.loadRelaxed();
200}
201
202/*!
203 \fn bool QAbstractEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
204
205 Processes pending events that match \a flags until there are no
206 more events to process. Returns \c true if an event was processed;
207 otherwise returns \c false.
208
209 This function is especially useful if you have a long running
210 operation, and want to show its progress without allowing user
211 input by using the QEventLoop::ExcludeUserInputEvents flag.
212
213 If the QEventLoop::WaitForMoreEvents flag is set in \a flags, the
214 behavior of this function is as follows:
215
216 \list
217
218 \li If events are available, this function returns after processing
219 them.
220
221 \li If no events are available, this function will wait until more
222 are available and return after processing newly available events.
223
224 \endlist
225
226 If the QEventLoop::WaitForMoreEvents flag is not set in \a flags,
227 and no events are available, this function will return
228 immediately.
229
230 \b{Note:} This function does not process events continuously; it
231 returns after all available events are processed.
232*/
233
234/*!
235 \internal
236
237 \note processEvents() only processes events queued before the function
238 is called. Events that are posted while the function runs will be queued
239 until a later round of event processing. This only applies to posted Qt
240 events. For timers and system level events, the situation is unknown.
241*/
242
243/*!
244 \fn void QAbstractEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier)
245
246 Registers \a notifier with the event loop. Subclasses must
247 implement this method to tie a socket notifier into another
248 event loop.
249*/
250
251/*! \fn void QAbstractEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier)
252
253 Unregisters \a notifier from the event dispatcher. Subclasses must
254 reimplement this method to tie a socket notifier into another
255 event loop. Reimplementations must call the base
256 implementation.
257*/
258
259/*!
260 \obsolete [6.8] This function will be removed in Qt 7. Use the overload taking \l Duration.
261
262 Registers a timer with the specified \a interval and \a timerType for the
263 given \a object and returns the timer id.
264*/
265int QAbstractEventDispatcher::registerTimer(qint64 interval, Qt::TimerType timerType, QObject *object)
266{
267 return int(registerTimer(interval * 1ms, timerType, object));
268}
269
270/*!
271 \since 6.8
272 \overload
273
274 Registers a timer with the specified \a interval and \a timerType for the
275 given \a object and returns the timer id.
276*/
277Qt::TimerId QAbstractEventDispatcher::registerTimer(Duration interval, Qt::TimerType timerType,
278 QObject *object)
279{
280 auto id = QAbstractEventDispatcherPrivate::allocateTimerId();
281#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
282 if (QAbstractEventDispatcherV2 *self = v2(this))
283 self->registerTimer(id, interval, timerType, object);
284 else
285 registerTimer(qToUnderlying(id), fromDuration<qint64>(interval), timerType, object);
286#else
287 registerTimer(id, interval, timerType, object);
288#endif
289 return id;
290}
291
292#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
293/*!
294 \fn void QAbstractEventDispatcher::registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object)
295
296 Register a timer with the specified \a timerId, \a interval, and \a
297 timerType for the given \a object.
298*/
299
300/*!
301 \fn bool QAbstractEventDispatcher::unregisterTimer(int timerId)
302
303 Unregisters the timer with the given \a timerId.
304 Returns \c true if successful; otherwise returns \c false.
305
306 \sa registerTimer(), unregisterTimers()
307*/
308
309/*!
310 \fn QList<TimerInfo> QAbstractEventDispatcher::registeredTimers(QObject *object) const
311
312 Returns a list of registered timers for \a object. The TimerInfo struct has
313 \c timerId, \c interval, and \c timerType members.
314
315 \sa Qt::TimerType
316*/
317
318/*!
319 \fn int QAbstractEventDispatcher::remainingTime(int timerId)
320
321 Returns the remaining time in milliseconds with the given \a timerId.
322 If the timer is inactive, the returned value will be -1. If the timer is
323 overdue, the returned value will be 0.
324
325 \sa Qt::TimerType
326*/
327#else // Qt 7
328/*!
329 \fn void QAbstractEventDispatcher::registerTimer(Qt::TimerId timerId, Duration interval, Qt::TimerType timerType, QObject *object)
330 \since 6.8
331
332 Register a timer with the specified \a timerId, \a interval, and \a
333 timerType for the given \a object.
334
335 \sa unregisterTimer(), timersForObject()
336*/
337
338/*!
339 \fn bool QAbstractEventDispatcher::unregisterTimer(Qt::TimerId timerId)
340 \since 6.8
341
342 Unregisters the timer with the given \a timerId.
343 Returns \c true if successful; otherwise returns \c false.
344
345 \sa registerTimer(), unregisterTimers()
346*/
347
348/*!
349 \fn QList<TimerInfoV2> QAbstractEventDispatcher::timersForObject(QObject *object) const
350 \since 6.8
351
352 Returns a list of registered timers for \a object. The TimerInfoV2 struct has
353 \c timerId, \c interval, and \c timerType members.
354
355 \sa Qt::TimerType, registerTimer(), unregisterTimer()
356*/
357
358/*!
359 \fn QAbstractEventDispatcher::remainingTime(Qt::TimerId timerId) const
360
361 Returns the remaining time of the timer with the given \a timerId.
362 If the timer is inactive, the returned value will be negative. If the timer
363 is overdue, the returned value will be 0.
364
365 \sa Qt::TimerType, registerTimer(), unregisterTimer()
366*/
367#endif
368
369/*!
370 \fn bool QAbstractEventDispatcher::unregisterTimers(QObject *object)
371
372 Unregisters all the timers associated with the given \a object. Returns \c
373 true if all timers were successfully removed; otherwise returns \c false.
374
375 \sa unregisterTimer(), registeredTimers()
376*/
377
378
379/*! \fn void QAbstractEventDispatcher::wakeUp()
380 \threadsafe
381
382 Wakes up the event loop.
383
384 \omit
385 ### FIXME - QTBUG-70229
386 On Unix and Glib event dispatchers, if the dispatcher is already awake when
387 this function is called, it is ensured that the current iteration won't block
388 waiting for more events, but will instead do another event loop iteration.
389
390 ### TODO - does other event dispatchers behave the same?
391 \endomit
392
393 \sa awake()
394*/
395
396/*!
397 \fn void QAbstractEventDispatcher::interrupt()
398
399 Interrupts event dispatching. The event dispatcher will
400 return from processEvents() as soon as possible.
401*/
402
403// ### DOC: Are these called when the _application_ starts/stops or just
404// when the current _event loop_ starts/stops?
405/*!
406 \internal
407*/
408void QAbstractEventDispatcher::startingUp()
409{ }
410
411/*!
412 \internal
413*/
414void QAbstractEventDispatcher::closingDown()
415{ }
416
417/*!
418 \class QAbstractEventDispatcher::TimerInfo
419 \deprecated [6.8] Use TimerInfoV2
420 \inmodule QtCore
421
422 This struct represents information about a timer:
423 \l{QAbstractEventDispatcher::TimerInfo::timerId}{timerId},
424 \l{QAbstractEventDispatcher::TimerInfo::interval}{interval}, and
425 \l{QAbstractEventDispatcher::TimerInfo::timerType}{timerType}.
426
427 \sa registeredTimers(), QAbstractEventDispatcher::TimerInfoV2, timersForObject()
428*/
429/*! \fn QAbstractEventDispatcher::TimerInfo::TimerInfo(int timerId, int interval, Qt::TimerType timerType)
430
431 Constructs a TimerInfo struct with the given \a timerId, \a interval, and
432 \a timerType.
433*/
434/*!
435 \variable QAbstractEventDispatcher::TimerInfo::timerId
436
437 The timer's unique id.
438*/
439/*!
440 \variable QAbstractEventDispatcher::TimerInfo::interval
441
442 The timer's interval.
443*/
444/*!
445 \variable QAbstractEventDispatcher::TimerInfo::timerType
446
447 The timer's type
448
449 \sa Qt::TimerType
450*/
451
452/*!
453 \class QAbstractEventDispatcher::TimerInfoV2
454 \inmodule QtCore
455
456 This struct represents information about a timer:
457 \l{QAbstractEventDispatcher::TimerInfoV2::timerId}{timerId},
458 \l{QAbstractEventDispatcher::TimerInfoV2::interval}{interval}, and
459 \l{QAbstractEventDispatcher::TimerInfoV2::timerType}{timerType}.
460
461 \sa timersForObject()
462*/
463/*!
464 \variable QAbstractEventDispatcher::TimerInfoV2::timerId
465
466 The timer's unique id. This is created by registerTimer() upon creation and
467 uniquely identifies a timer while it is active. It is also used by
468 QTimer::id() and returned by QObject::startTimer().
469*/
470/*!
471 \variable QAbstractEventDispatcher::TimerInfoV2::interval
472
473 The timer's interval.
474*/
475/*!
476 \variable QAbstractEventDispatcher::TimerInfoV2::timerType
477
478 The timer's type
479
480 \sa Qt::TimerType
481*/
482
483/*!
484 Installs an event filter \a filterObj for all native events received by the application.
485
486 The event filter \a filterObj receives events via its \l {QAbstractNativeEventFilter::}{nativeEventFilter()}
487 function, which is called for all events received by all threads.
488
489 The \l {QAbstractNativeEventFilter::}{nativeEventFilter()} function should return true
490 if the event should be filtered, (in this case, stopped). It should return false to allow
491 normal Qt processing to continue: the native event can then be translated
492 into a QEvent and handled by the standard Qt \l{QEvent} {event} filtering,
493 e.g. QObject::installEventFilter().
494
495 If multiple event filters are installed, the filter that was installed last
496 is activated first.
497
498 \note The filter function set here receives native messages,
499 that is, MSG or XEvent structs.
500
501 For maximum portability, you should always try to use QEvent objects
502 and QObject::installEventFilter() whenever possible.
503
504 \sa QObject::installEventFilter()
505
506 \since 5.0
507*/
508void QAbstractEventDispatcher::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
509{
510 Q_D(QAbstractEventDispatcher);
511
512 // clean up unused items in the list
513 d->eventFilters.removeAll(nullptr);
514 d->eventFilters.removeAll(filterObj);
515 d->eventFilters.prepend(filterObj);
516}
517
518/*!
519 Removes the event filter \a filter from this object. The
520 request is ignored if such an event filter has not been installed.
521
522 All event filters for this object are automatically removed when
523 this object is destroyed.
524
525 It is always safe to remove an event filter, even during event filter
526 filter activation (that is, even from within the \l {QAbstractNativeEventFilter::}{nativeEventFilter()} function).
527
528 \sa installNativeEventFilter(), QAbstractNativeEventFilter
529 \since 5.0
530*/
531void QAbstractEventDispatcher::removeNativeEventFilter(QAbstractNativeEventFilter *filter)
532{
533 Q_D(QAbstractEventDispatcher);
534 if (const auto idx = d->eventFilters.indexOf(filter); idx >= 0)
535 d->eventFilters[idx] = nullptr;
536}
537
538/*!
539 Sends \a message through the event filters that were set by
540 installNativeEventFilter(). This function returns \c true as soon as an
541 event filter returns \c true, and false otherwise to indicate that
542 the processing of the event should continue.
543
544 Subclasses of QAbstractEventDispatcher \e must call this function
545 for \e all messages received from the system to ensure
546 compatibility with any extensions that may be used in the
547 application. The type of event \a eventType is specific to the platform
548 plugin chosen at run-time, and can be used to cast message to the right type.
549 The \a result pointer is only used on Windows, and corresponds to the LRESULT pointer.
550
551 Note that the type of \a message is platform dependent. See
552 QAbstractNativeEventFilter for details.
553
554 \sa installNativeEventFilter(), QAbstractNativeEventFilter::nativeEventFilter()
555 \since 5.0
556*/
557bool QAbstractEventDispatcher::filterNativeEvent(const QByteArray &eventType, void *message, qintptr *result)
558{
559 Q_D(QAbstractEventDispatcher);
560 if (!d->eventFilters.isEmpty()) {
561 // Raise the loopLevel so that deleteLater() calls in or triggered
562 // by event_filter() will be processed from the main event loop.
563 QScopedScopeLevelCounter scopeLevelCounter(d->threadData.loadAcquire());
564 for (qsizetype i = 0; i < d->eventFilters.size(); ++i) {
565 QAbstractNativeEventFilter *filter = d->eventFilters.at(i);
566 if (!filter)
567 continue;
568 if (filter->nativeEventFilter(eventType, message, result))
569 return true;
570 }
571 }
572 return false;
573}
574
575/*! \fn void QAbstractEventDispatcher::awake()
576
577 This signal is emitted after the event loop returns from a
578 function that could block.
579
580 \sa wakeUp(), aboutToBlock()
581*/
582
583/*! \fn void QAbstractEventDispatcher::aboutToBlock()
584
585 This signal is emitted before the event loop calls a function that
586 could block.
587
588 \sa awake()
589*/
590
591#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
592void QAbstractEventDispatcher::registerTimer(Qt::TimerId timerId, Duration interval,
593 Qt::TimerType timerType, QObject *object)
594{
595 if (QAbstractEventDispatcherV2 *self = v2(this))
596 self->registerTimer(timerId, interval, timerType, object);
597 else
598 registerTimer(int(timerId), fromDuration<qint64>(interval), timerType, object);
599}
600
601bool QAbstractEventDispatcher::unregisterTimer(Qt::TimerId timerId)
602{
603 if (QAbstractEventDispatcherV2 *self = v2(this))
604 return self->unregisterTimer(timerId);
605 return unregisterTimer(int(timerId));
606}
607
608QList<QAbstractEventDispatcher::TimerInfoV2>
609QAbstractEventDispatcher::timersForObject(QObject *object) const
610{
611 if (const QAbstractEventDispatcherV2 *self = v2(this))
612 return self->timersForObject(object);
613 QList<TimerInfo> timers = registeredTimers(object);
614 QList<TimerInfoV2> result;
615 result.reserve(timers.size());
616 for (const TimerInfo &t : timers)
617 result.emplaceBack(TimerInfoV2{ t.interval * 1ms, Qt::TimerId(t.timerId), t.timerType });
618 return result;
619}
620
621QAbstractEventDispatcher::Duration
622QAbstractEventDispatcher::remainingTime(Qt::TimerId timerId) const
623{
624 if (const QAbstractEventDispatcherV2 *self = v2(this))
625 return self->remainingTime(timerId);
626 return const_cast<QAbstractEventDispatcher *>(this)->remainingTime(int(timerId)) * 1ms;
627}
628
629/*!
630 \class QAbstractEventDispatcherV2
631 \inmodule QtCore
632
633 This class is a temporary hack to enable transition to an API based on
634 \c{std::chrono} for the Qt event dispatcher. In Qt 7, it will be merged
635 with QAbstractEventDispatcher, replacing the pure virtuals there with the
636 ones defined here.
637
638 It is recommended applications and libraries port to the new API before
639 that future release to simplify work when the time comes.
640*/
641
642/*!
643 Constructs a new event dispatcher with the given \a parent.
644*/
645QAbstractEventDispatcherV2::QAbstractEventDispatcherV2(QObject *parent)
646 : QAbstractEventDispatcherV2(*new QAbstractEventDispatcherPrivate, parent)
647{
648}
649
650/*!
651 \internal
652*/
653QAbstractEventDispatcherV2::QAbstractEventDispatcherV2(QAbstractEventDispatcherPrivate &dd,
654 QObject *parent)
655 : QAbstractEventDispatcher((dd.isV2 = true, dd), parent)
656{
657}
658
659/*!
660 Destroys the event dispatcher.
661*/
662QAbstractEventDispatcherV2::~QAbstractEventDispatcherV2() = default;
663
664/*!
665 \internal
666 Temporary compatibility override.
667*/
668void QAbstractEventDispatcherV2::registerTimer(int timerId, qint64 interval,
669 Qt::TimerType timerType, QObject *object)
670{
671 auto self = static_cast<QAbstractEventDispatcherV2 *>(this);
672 self->registerTimer(Qt::TimerId(timerId), interval * 1ms, timerType, object);
673}
674
675/*!
676 \internal
677 Temporary compatibility override.
678*/
679bool QAbstractEventDispatcherV2::unregisterTimer(int timerId)
680{
681 auto self = static_cast<QAbstractEventDispatcherV2 *>(this);
682 return self->unregisterTimer(Qt::TimerId(timerId));
683}
684
685/*!
686 \internal
687 Temporary compatibility override.
688*/
689auto QAbstractEventDispatcherV2::registeredTimers(QObject *object) const -> QList<TimerInfo>
690{
691 auto self = static_cast<const QAbstractEventDispatcherV2 *>(this);
692 QList<TimerInfoV2> timers = self->timersForObject(object);
693 QList<TimerInfo> result;
694 result.reserve(timers.size());
695 for (const TimerInfoV2 &t : timers)
696 result.emplaceBack(qToUnderlying(t.timerId), fromDuration<int>(t.interval), t.timerType);
697 return result;
698}
699
700/*!
701 \internal
702 Temporary compatibility override.
703*/
704int QAbstractEventDispatcherV2::remainingTime(int timerId)
705{
706 auto self = static_cast<QAbstractEventDispatcherV2 *>(this);
707 return fromDuration<int>(self->remainingTime(Qt::TimerId(timerId)));
708}
709
710/*!
711 \internal
712 Temporary compatibility override.
713*/
714bool QAbstractEventDispatcherV2::processEventsWithDeadline(QEventLoop::ProcessEventsFlags flags, QDeadlineTimer deadline)
715{
716 Q_UNUSED(deadline);
717 return processEvents(flags);
718}
719#endif // ! Qt 7
720
721QT_END_NAMESPACE
722
723#include "moc_qabstracteventdispatcher.cpp"
Combined button and popup list for selecting options.
QFreeList< void, QtTimerIdFreeListConstants > QtTimerIdFreeList
static const int Sizes[BlockCount]