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
4#include "qabstracteventdispatcher.h"
5#include "qabstracteventdispatcher_p.h"
6#include "qabstractnativeeventfilter.h"
7
8#include "qthread.h"
9#include <private/qthread_p.h>
10#include <private/qcoreapplication_p.h>
11#include <private/qfreelist_p.h>
12
13QT_BEGIN_NAMESPACE
14
15// we allow for 2^24 = 8^8 = 16777216 simultaneously running timers
16struct QtTimerIdFreeListConstants : public QFreeListDefaultConstants
17{
18 enum
19 {
20 InitialNextValue = 1,
21 BlockCount = 6
22 };
23
24 static const int Sizes[BlockCount];
25};
26
27enum {
28 Offset0 = 0x00000000,
29 Offset1 = 0x00000040,
30 Offset2 = 0x00000100,
31 Offset3 = 0x00001000,
32 Offset4 = 0x00010000,
33 Offset5 = 0x00100000,
34
35 Size0 = Offset1 - Offset0,
36 Size1 = Offset2 - Offset1,
37 Size2 = Offset3 - Offset2,
38 Size3 = Offset4 - Offset3,
39 Size4 = Offset5 - Offset4,
40 Size5 = QtTimerIdFreeListConstants::MaxIndex - Offset5
41};
42
43Q_CONSTINIT const int QtTimerIdFreeListConstants::Sizes[QtTimerIdFreeListConstants::BlockCount] = {
44 Size0,
45 Size1,
46 Size2,
47 Size3,
48 Size4,
49 Size5
50};
51
52typedef QFreeList<void, QtTimerIdFreeListConstants> QtTimerIdFreeList;
53Q_GLOBAL_STATIC(QtTimerIdFreeList, timerIdFreeList)
54
55QAbstractEventDispatcherPrivate::QAbstractEventDispatcherPrivate()
56{
57 // Create the timer ID free list here to make sure that it is destroyed
58 // after any global static thread that may be using it.
59 // See also QTBUG-58732.
60 if (!timerIdFreeList.isDestroyed())
61 (void)timerIdFreeList();
62}
63
64QAbstractEventDispatcherPrivate::~QAbstractEventDispatcherPrivate()
65 = default;
66
67int QAbstractEventDispatcherPrivate::allocateTimerId()
68{
69 // This function may be called after timerIdFreeList() has been destructed
70 // for example in case when application exits without waiting for
71 // running threads to exit and running thread finished() has been connected
72 // to a slot which triggers a sequence that registers new timer.
73 // See https://bugreports.qt-project.org/browse/QTBUG-38957.
74 if (QtTimerIdFreeList *fl = timerIdFreeList())
75 return fl->next();
76 return 0; // Note! returning 0 generates a warning
77}
78
79void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId)
80{
81 // this function may be called by a global destructor after
82 // timerIdFreeList() has been destructed
83 if (QtTimerIdFreeList *fl = timerIdFreeList())
84 fl->release(id: timerId);
85}
86
87/*!
88 \class QAbstractEventDispatcher
89 \inmodule QtCore
90 \brief The QAbstractEventDispatcher class provides an interface to manage Qt's event queue.
91
92 \ingroup events
93
94 An event dispatcher receives events from the window system and other
95 sources. It then sends them to the QCoreApplication or QApplication
96 instance for processing and delivery. QAbstractEventDispatcher provides
97 fine-grained control over event delivery.
98
99 For simple control of event processing use
100 QCoreApplication::processEvents().
101
102 For finer control of the application's event loop, call
103 instance() and call functions on the QAbstractEventDispatcher
104 object that is returned. If you want to use your own instance of
105 QAbstractEventDispatcher or of a QAbstractEventDispatcher
106 subclass, you must install it with QCoreApplication::setEventDispatcher()
107 or QThread::setEventDispatcher() \e before a default event dispatcher has
108 been installed.
109
110 The main event loop is started by calling
111 QCoreApplication::exec(), and stopped by calling
112 QCoreApplication::exit(). Local event loops can be created using
113 QEventLoop.
114
115 Programs that perform long operations can call processEvents()
116 with a bitwise OR combination of various QEventLoop::ProcessEventsFlag
117 values to control which events should be delivered.
118
119 QAbstractEventDispatcher also allows the integration of an
120 external event loop with the Qt event loop.
121
122 \sa QEventLoop, QCoreApplication, QThread
123*/
124
125/*!
126 Constructs a new event dispatcher with the given \a parent.
127*/
128QAbstractEventDispatcher::QAbstractEventDispatcher(QObject *parent)
129 : QObject(*new QAbstractEventDispatcherPrivate, parent) {}
130
131/*!
132 \internal
133*/
134QAbstractEventDispatcher::QAbstractEventDispatcher(QAbstractEventDispatcherPrivate &dd,
135 QObject *parent)
136 : QObject(dd, parent) {}
137
138/*!
139 Destroys the event dispatcher.
140*/
141QAbstractEventDispatcher::~QAbstractEventDispatcher()
142{ }
143
144/*!
145 Returns a pointer to the event dispatcher object for the specified
146 \a thread. If \a thread is \nullptr, the current thread is used. If no
147 event dispatcher exists for the specified thread, this function
148 returns \nullptr.
149
150 \b{Note:} If Qt is built without thread support, the \a thread
151 argument is ignored.
152 */
153QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
154{
155 QThreadData *data = thread ? QThreadData::get2(thread) : QThreadData::current();
156 return data->eventDispatcher.loadRelaxed();
157}
158
159/*!
160 \fn bool QAbstractEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
161
162 Processes pending events that match \a flags until there are no
163 more events to process. Returns \c true if an event was processed;
164 otherwise returns \c false.
165
166 This function is especially useful if you have a long running
167 operation, and want to show its progress without allowing user
168 input by using the QEventLoop::ExcludeUserInputEvents flag.
169
170 If the QEventLoop::WaitForMoreEvents flag is set in \a flags, the
171 behavior of this function is as follows:
172
173 \list
174
175 \li If events are available, this function returns after processing
176 them.
177
178 \li If no events are available, this function will wait until more
179 are available and return after processing newly available events.
180
181 \endlist
182
183 If the QEventLoop::WaitForMoreEvents flag is not set in \a flags,
184 and no events are available, this function will return
185 immediately.
186
187 \b{Note:} This function does not process events continuously; it
188 returns after all available events are processed.
189*/
190
191/*!
192 \internal
193
194 \note processEvents() only processes events queued before the function
195 is called. Events that are posted while the function runs will be queued
196 until a later round of event processing. This only applies to posted Qt
197 events. For timers and system level events, the situation is unknown.
198*/
199
200/*!
201 \fn void QAbstractEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier)
202
203 Registers \a notifier with the event loop. Subclasses must
204 implement this method to tie a socket notifier into another
205 event loop.
206*/
207
208/*! \fn void QAbstractEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier)
209
210 Unregisters \a notifier from the event dispatcher. Subclasses must
211 reimplement this method to tie a socket notifier into another
212 event loop. Reimplementations must call the base
213 implementation.
214*/
215
216/*!
217 Registers a timer with the specified \a interval and \a timerType for the
218 given \a object and returns the timer id.
219*/
220int QAbstractEventDispatcher::registerTimer(qint64 interval, Qt::TimerType timerType, QObject *object)
221{
222 int id = QAbstractEventDispatcherPrivate::allocateTimerId();
223 registerTimer(timerId: id, interval, timerType, object);
224 return id;
225}
226
227/*!
228 \fn void QAbstractEventDispatcher::registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object)
229
230 Register a timer with the specified \a timerId, \a interval, and \a
231 timerType for the given \a object.
232*/
233
234/*!
235 \fn bool QAbstractEventDispatcher::unregisterTimer(int timerId)
236
237 Unregisters the timer with the given \a timerId.
238 Returns \c true if successful; otherwise returns \c false.
239
240 \sa registerTimer(), unregisterTimers()
241*/
242
243/*!
244 \fn bool QAbstractEventDispatcher::unregisterTimers(QObject *object)
245
246 Unregisters all the timers associated with the given \a object.
247 Returns \c true if all timers were successful removed; otherwise returns \c false.
248
249 \sa unregisterTimer(), registeredTimers()
250*/
251
252/*!
253 \fn QList<TimerInfo> QAbstractEventDispatcher::registeredTimers(QObject *object) const
254
255 Returns a list of registered timers for \a object. The TimerInfo struct has
256 \c timerId, \c interval, and \c timerType members.
257
258 \sa Qt::TimerType
259*/
260
261/*!
262 \fn int QAbstractEventDispatcher::remainingTime(int timerId)
263
264 Returns the remaining time in milliseconds with the given \a timerId.
265 If the timer is inactive, the returned value will be -1. If the timer is
266 overdue, the returned value will be 0.
267
268 \sa Qt::TimerType
269*/
270
271/*! \fn void QAbstractEventDispatcher::wakeUp()
272 \threadsafe
273
274 Wakes up the event loop.
275
276 \omit
277 ### FIXME - QTBUG-70229
278 On Unix and Glib event dispatchers, if the dispatcher is already awake when
279 this function is called, it is ensured that the current iteration won't block
280 waiting for more events, but will instead do another event loop iteration.
281
282 ### TODO - does other event dispatchers behave the same?
283 \endomit
284
285 \sa awake()
286*/
287
288/*!
289 \fn void QAbstractEventDispatcher::interrupt()
290
291 Interrupts event dispatching. The event dispatcher will
292 return from processEvents() as soon as possible.
293*/
294
295// ### DOC: Are these called when the _application_ starts/stops or just
296// when the current _event loop_ starts/stops?
297/*!
298 \internal
299*/
300void QAbstractEventDispatcher::startingUp()
301{ }
302
303/*!
304 \internal
305*/
306void QAbstractEventDispatcher::closingDown()
307{ }
308
309/*!
310 \class QAbstractEventDispatcher::TimerInfo
311 \inmodule QtCore
312
313 This struct represents information about a timer:
314 \l{QAbstractEventDispatcher::TimerInfo::timerId}{timerId},
315 \l{QAbstractEventDispatcher::TimerInfo::interval}{interval}, and
316 \l{QAbstractEventDispatcher::TimerInfo::timerType}{timerType}.
317
318 \sa registeredTimers()
319*/
320/*! \fn QAbstractEventDispatcher::TimerInfo::TimerInfo(int timerId, int interval, Qt::TimerType timerType)
321
322 Constructs a TimerInfo struct with the given \a timerId, \a interval, and
323 \a timerType.
324*/
325/*!
326 \variable QAbstractEventDispatcher::TimerInfo::timerId
327
328 The timer's unique id.
329*/
330/*!
331 \variable QAbstractEventDispatcher::TimerInfo::interval
332
333 The timer's interval.
334*/
335/*!
336 \variable QAbstractEventDispatcher::TimerInfo::timerType
337
338 The timer's type
339
340 \sa Qt::TimerType
341*/
342
343/*!
344 Installs an event filter \a filterObj for all native events received by the application.
345
346 The event filter \a filterObj receives events via its \l {QAbstractNativeEventFilter::}{nativeEventFilter()}
347 function, which is called for all events received by all threads.
348
349 The \l {QAbstractNativeEventFilter::}{nativeEventFilter()} function should return true
350 if the event should be filtered, (in this case, stopped). It should return false to allow
351 normal Qt processing to continue: the native event can then be translated
352 into a QEvent and handled by the standard Qt \l{QEvent} {event} filtering,
353 e.g. QObject::installEventFilter().
354
355 If multiple event filters are installed, the filter that was installed last
356 is activated first.
357
358 \note The filter function set here receives native messages,
359 that is, MSG or XEvent structs.
360
361 For maximum portability, you should always try to use QEvent objects
362 and QObject::installEventFilter() whenever possible.
363
364 \sa QObject::installEventFilter()
365
366 \since 5.0
367*/
368void QAbstractEventDispatcher::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
369{
370 Q_D(QAbstractEventDispatcher);
371
372 // clean up unused items in the list
373 d->eventFilters.removeAll(t: nullptr);
374 d->eventFilters.removeAll(t: filterObj);
375 d->eventFilters.prepend(t: filterObj);
376}
377
378/*!
379 Removes the event filter \a filter from this object. The
380 request is ignored if such an event filter has not been installed.
381
382 All event filters for this object are automatically removed when
383 this object is destroyed.
384
385 It is always safe to remove an event filter, even during event filter
386 filter activation (that is, even from within the \l {QAbstractNativeEventFilter::}{nativeEventFilter()} function).
387
388 \sa installNativeEventFilter(), QAbstractNativeEventFilter
389 \since 5.0
390*/
391void QAbstractEventDispatcher::removeNativeEventFilter(QAbstractNativeEventFilter *filter)
392{
393 Q_D(QAbstractEventDispatcher);
394 for (int i = 0; i < d->eventFilters.size(); ++i) {
395 if (d->eventFilters.at(i) == filter) {
396 d->eventFilters[i] = nullptr;
397 break;
398 }
399 }
400}
401
402/*!
403 Sends \a message through the event filters that were set by
404 installNativeEventFilter(). This function returns \c true as soon as an
405 event filter returns \c true, and false otherwise to indicate that
406 the processing of the event should continue.
407
408 Subclasses of QAbstractEventDispatcher \e must call this function
409 for \e all messages received from the system to ensure
410 compatibility with any extensions that may be used in the
411 application. The type of event \a eventType is specific to the platform
412 plugin chosen at run-time, and can be used to cast message to the right type.
413 The \a result pointer is only used on Windows, and corresponds to the LRESULT pointer.
414
415 Note that the type of \a message is platform dependent. See
416 QAbstractNativeEventFilter for details.
417
418 \sa installNativeEventFilter(), QAbstractNativeEventFilter::nativeEventFilter()
419 \since 5.0
420*/
421bool QAbstractEventDispatcher::filterNativeEvent(const QByteArray &eventType, void *message, qintptr *result)
422{
423 Q_D(QAbstractEventDispatcher);
424 if (!d->eventFilters.isEmpty()) {
425 // Raise the loopLevel so that deleteLater() calls in or triggered
426 // by event_filter() will be processed from the main event loop.
427 QScopedScopeLevelCounter scopeLevelCounter(d->threadData.loadAcquire());
428 for (int i = 0; i < d->eventFilters.size(); ++i) {
429 QAbstractNativeEventFilter *filter = d->eventFilters.at(i);
430 if (!filter)
431 continue;
432 if (filter->nativeEventFilter(eventType, message, result))
433 return true;
434 }
435 }
436 return false;
437}
438
439/*! \fn void QAbstractEventDispatcher::awake()
440
441 This signal is emitted after the event loop returns from a
442 function that could block.
443
444 \sa wakeUp(), aboutToBlock()
445*/
446
447/*! \fn void QAbstractEventDispatcher::aboutToBlock()
448
449 This signal is emitted before the event loop calls a function that
450 could block.
451
452 \sa awake()
453*/
454
455QT_END_NAMESPACE
456
457#include "moc_qabstracteventdispatcher.cpp"
458

source code of qtbase/src/corelib/kernel/qabstracteventdispatcher.cpp