1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qabstracteventdispatcher.h"
43 #include "qabstracteventdispatcher_p.h"
44
45 #include "qthread.h"
46 #include <private/qthread_p.h>
47 #include <private/qcoreapplication_p.h>
48
49 QT_BEGIN_NAMESPACE
50
51 // we allow for 2^24 = 8^8 = 16777216 simultaneously running timers
52 static const int TimerIdMask = 0x00ffffff;
53 static const int TimerSerialMask = ~TimerIdMask & ~0x80000000;
54 static const int TimerSerialCounter = TimerIdMask + 1;
55 static const int MaxTimerId = TimerIdMask;
56
57 static int FirstBucket[] = {
58 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
59 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
60 };
61
62 enum {
63 FirstBucketOffset = 0,
64 SecondBucketOffset = sizeof(FirstBucket) / sizeof(FirstBucket[0]),
65 ThirdBucketOffset = 0x100,
66 FourthBucketOffset = 0x1000,
67 FifthBucketOffset = 0x10000,
68 SixthBucketOffset = 0x100000
69 };
70
71 enum {
72 FirstBucketSize = SecondBucketOffset,
73 SecondBucketSize = ThirdBucketOffset - SecondBucketOffset,
74 ThirdBucketSize = FourthBucketOffset - ThirdBucketOffset,
75 FourthBucketSize = FifthBucketOffset - FourthBucketOffset,
76 FifthBucketSize = SixthBucketOffset - FifthBucketOffset,
77 SixthBucketSize = MaxTimerId - SixthBucketOffset
78 };
79
80 static const int BucketSize[] = {
81 FirstBucketSize, SecondBucketSize, ThirdBucketSize,
82 FourthBucketSize, FifthBucketSize, SixthBucketSize
83 };
84 enum { NumberOfBuckets = sizeof(BucketSize) / sizeof(BucketSize[0]) };
85
86 static const int BucketOffset[] = {
87 FirstBucketOffset, SecondBucketOffset, ThirdBucketOffset,
88 FourthBucketOffset, FifthBucketOffset, SixthBucketOffset
89 };
90
91 static QBasicAtomicPointer<int> timerIds[] =
92 { Q_BASIC_ATOMIC_INITIALIZER(FirstBucket),
93 Q_BASIC_ATOMIC_INITIALIZER(0),
94 Q_BASIC_ATOMIC_INITIALIZER(0),
95 Q_BASIC_ATOMIC_INITIALIZER(0),
96 Q_BASIC_ATOMIC_INITIALIZER(0),
97 Q_BASIC_ATOMIC_INITIALIZER(0) };
98
timerIdsDestructorFunction()99 static void timerIdsDestructorFunction()
100 {
101 // start at one, the first bucket is pre-allocated
102 for (int i = 1; i < NumberOfBuckets; ++i)
103 delete [] static_cast<int *>(timerIds[i]);
104 }
105 Q_DESTRUCTOR_FUNCTION(timerIdsDestructorFunction)
106
107 static QBasicAtomicInt nextFreeTimerId = Q_BASIC_ATOMIC_INITIALIZER(1);
108
109 // avoid the ABA-problem by using 7 of the top 8 bits of the timerId as a serial number
prepareNewValueWithSerialNumber(int oldId,int newId)110 static inline int prepareNewValueWithSerialNumber(int oldId, int newId)
111 {
112 return (newId & TimerIdMask) | ((oldId + TimerSerialCounter) & TimerSerialMask);
113 }
114
115 namespace {
116 template<bool> struct QStaticAssertType;
117 template<> struct QStaticAssertType<true> { enum { Value = 1 }; };
118 }
119 #define q_static_assert(expr) (void)QStaticAssertType<expr>::Value
120
bucketOffset(int timerId)121 static inline int bucketOffset(int timerId)
122 {
123 q_static_assert(sizeof BucketSize == sizeof BucketOffset);
124 q_static_assert(sizeof(timerIds) / sizeof(timerIds[0]) == NumberOfBuckets);
125
126 for (int i = 0; i < NumberOfBuckets; ++i) {
127 if (timerId < BucketSize[i])
128 return i;
129 timerId -= BucketSize[i];
130 }
131 qFatal("QAbstractEventDispatcher: INTERNAL ERROR, timer ID %d is too large", timerId);
132 return -1;
133 }
134
bucketIndex(int bucket,int timerId)135 static inline int bucketIndex(int bucket, int timerId)
136 {
137 return timerId - BucketOffset[bucket];
138 }
139
allocateBucket(int bucket)140 static inline int *allocateBucket(int bucket)
141 {
142 // allocate a new bucket
143 const int size = BucketSize[bucket];
144 const int offset = BucketOffset[bucket];
145 int *b = new int[size];
146 for (int i = 0; i != size; ++i)
147 b[i] = offset + i + 1;
148 return b;
149 }
150
init()151 void QAbstractEventDispatcherPrivate::init()
152 {
153 Q_Q(QAbstractEventDispatcher);
154 if (threadData->eventDispatcher != 0) {
155 qWarning("QAbstractEventDispatcher: An event dispatcher has already been created for this thread");
156 } else {
157 threadData->eventDispatcher = q;
158 }
159 }
160
161 // Timer IDs are implemented using a free-list;
162 // there's a vector initialized with:
163 // X[i] = i + 1
164 // and nextFreeTimerId starts with 1.
165 //
166 // Allocating a timer ID involves taking the ID from
167 // X[nextFreeTimerId]
168 // updating nextFreeTimerId to this value and returning the old value
169 //
170 // When the timer ID is allocated, its cell in the vector is unused (it's a
171 // free list). As an added protection, we use the cell to store an invalid
172 // (negative) value that we can later check for integrity.
173 //
174 // (continues below).
allocateTimerId()175 int QAbstractEventDispatcherPrivate::allocateTimerId()
176 {
177 int timerId, newTimerId;
178 int at, *b;
179 do {
180 timerId = nextFreeTimerId; //.loadAcquire(); // ### FIXME Proper memory ordering semantics
181
182 // which bucket are we looking in?
183 int which = timerId & TimerIdMask;
184 int bucket = bucketOffset(which);
185 at = bucketIndex(bucket, which);
186 b = timerIds[bucket];
187
188 if (!b) {
189 // allocate a new bucket
190 b = allocateBucket(bucket);
191 if (!timerIds[bucket].testAndSetRelease(0, b)) {
192 // another thread won the race to allocate the bucket
193 delete [] b;
194 b = timerIds[bucket];
195 }
196 }
197
198 newTimerId = prepareNewValueWithSerialNumber(timerId, b[at]);
199 } while (!nextFreeTimerId.testAndSetRelaxed(timerId, newTimerId));
200
201 b[at] = -timerId;
202
203 return timerId;
204 }
205
206 // Releasing a timer ID requires putting the current ID back in the vector;
207 // we do it by setting:
208 // X[timerId] = nextFreeTimerId;
209 // then we update nextFreeTimerId to the timer we've just released
210 //
211 // The extra code in allocateTimerId and releaseTimerId are ABA prevention
212 // and bucket memory. The buckets are simply to make sure we allocate only
213 // the necessary number of timers. See above.
214 //
215 // ABA prevention simply adds a value to 7 of the top 8 bits when resetting
216 // nextFreeTimerId.
releaseTimerId(int timerId)217 void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId)
218 {
219 int which = timerId & TimerIdMask;
220 int bucket = bucketOffset(which);
221 int at = bucketIndex(bucket, which);
222 int *b = timerIds[bucket];
223
224 Q_ASSERT_X(timerId == -b[at], "QAbstractEventDispatcher::releaseTimerId",
225 "Internal error: timer ID not found");
226
227 int freeId, newTimerId;
228 do {
229 freeId = nextFreeTimerId;//.loadAcquire(); // ### FIXME Proper memory ordering semantics
230 b[at] = freeId & TimerIdMask;
231
232 newTimerId = prepareNewValueWithSerialNumber(freeId, timerId);
233 } while (!nextFreeTimerId.testAndSetRelease(freeId, newTimerId));
234 }
235
236 /*!
237 \class QAbstractEventDispatcher
238 \brief The QAbstractEventDispatcher class provides an interface to manage Qt's event queue.
239
240 \ingroup events
241
242 An event dispatcher receives events from the window system and other
243 sources. It then sends them to the QCoreApplication or QApplication
244 instance for processing and delivery. QAbstractEventDispatcher provides
245 fine-grained control over event delivery.
246
247 For simple control of event processing use
248 QCoreApplication::processEvents().
249
250 For finer control of the application's event loop, call
251 instance() and call functions on the QAbstractEventDispatcher
252 object that is returned. If you want to use your own instance of
253 QAbstractEventDispatcher or of a QAbstractEventDispatcher
254 subclass, you must create your instance \e before you create the
255 QApplication object.
256
257 The main event loop is started by calling
258 QCoreApplication::exec(), and stopped by calling
259 QCoreApplication::exit(). Local event loops can be created using
260 QEventLoop.
261
262 Programs that perform long operations can call processEvents()
263 with a bitwise OR combination of various QEventLoop::ProcessEventsFlag
264 values to control which events should be delivered.
265
266 QAbstractEventDispatcher also allows the integration of an
267 external event loop with the Qt event loop. For example, the
268 \l{Motif Extension}
269 includes a reimplementation of QAbstractEventDispatcher that merges Qt and
270 Motif events together.
271
272 \sa QEventLoop, QCoreApplication
273 */
274
275 /*!
276 Constructs a new event dispatcher with the given \a parent.
277 */
QAbstractEventDispatcher(QObject * parent)278 QAbstractEventDispatcher::QAbstractEventDispatcher(QObject *parent)
279 : QObject(*new QAbstractEventDispatcherPrivate, parent)
280 {
281 Q_D(QAbstractEventDispatcher);
282 d->init();
283 }
284
285 /*!
286 \internal
287 */
QAbstractEventDispatcher(QAbstractEventDispatcherPrivate & dd,QObject * parent)288 QAbstractEventDispatcher::QAbstractEventDispatcher(QAbstractEventDispatcherPrivate &dd,
289 QObject *parent)
290 : QObject(dd, parent)
291 {
292 Q_D(QAbstractEventDispatcher);
293 d->init();
294 }
295
296 /*!
297 Destroys the event dispatcher.
298 */
~QAbstractEventDispatcher()299 QAbstractEventDispatcher::~QAbstractEventDispatcher()
300 { }
301
302 /*!
303 Returns a pointer to the event dispatcher object for the specified
304 \a thread. If \a thread is zero, the current thread is used. If no
305 event dispatcher exists for the specified thread, this function
306 returns 0.
307
308 \bold{Note:} If Qt is built without thread support, the \a thread
309 argument is ignored.
310 */
instance(QThread * thread)311 QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
312 {
313 QThreadData *data = thread ? QThreadData::get2(thread) : QThreadData::current();
314 return data->eventDispatcher;
315 }
316
317 /*!
318 \fn bool QAbstractEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
319
320 Processes pending events that match \a flags until there are no
321 more events to process. Returns true if an event was processed;
322 otherwise returns false.
323
324 This function is especially useful if you have a long running
325 operation and want to show its progress without allowing user
326 input; i.e. by using the QEventLoop::ExcludeUserInputEvents flag.
327
328 If the QEventLoop::WaitForMoreEvents flag is set in \a flags, the
329 behavior of this function is as follows:
330
331 \list
332
333 \i If events are available, this function returns after processing
334 them.
335
336 \i If no events are available, this function will wait until more
337 are available and return after processing newly available events.
338
339 \endlist
340
341 If the QEventLoop::WaitForMoreEvents flag is not set in \a flags,
342 and no events are available, this function will return
343 immediately.
344
345 \bold{Note:} This function does not process events continuously; it
346 returns after all available events are processed.
347
348 \sa hasPendingEvents()
349 */
350
351 /*! \fn bool QAbstractEventDispatcher::hasPendingEvents()
352
353 Returns true if there is an event waiting; otherwise returns
354 false.
355 */
356
357 /*!
358 \fn void QAbstractEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier)
359
360 Registers \a notifier with the event loop. Subclasses must
361 implement this method to tie a socket notifier into another
362 event loop.
363 */
364
365 /*! \fn void QAbstractEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier)
366
367 Unregisters \a notifier from the event dispatcher. Subclasses must
368 reimplement this method to tie a socket notifier into another
369 event loop. Reimplementations must call the base
370 implementation.
371 */
372
373 /*!
374 \fn int QAbstractEventDispatcher::registerTimer(int interval, QObject *object)
375
376 Registers a timer with the specified \a interval for the given \a object.
377 */
registerTimer(int interval,QObject * object)378 int QAbstractEventDispatcher::registerTimer(int interval, QObject *object)
379 {
380 int id = QAbstractEventDispatcherPrivate::allocateTimerId();
381 registerTimer(id, interval, object);
382 return id;
383 }
384
385 /*!
386 \fn void QAbstractEventDispatcher::registerTimer(int timerId, int interval, QObject *object)
387
388 Register a timer with the specified \a timerId and \a interval for
389 the given \a object.
390 */
391
392 /*!
393 \fn bool QAbstractEventDispatcher::unregisterTimer(int timerId)
394
395 Unregisters the timer with the given \a timerId.
396 Returns true if successful; otherwise returns false.
397
398 \sa registerTimer(), unregisterTimers()
399 */
400
401 /*!
402 \fn bool QAbstractEventDispatcher::unregisterTimers(QObject *object)
403
404 Unregisters all the timers associated with the given \a object.
405 Returns true if all timers were successful removed; otherwise returns false.
406
407 \sa unregisterTimer(), registeredTimers()
408 */
409
410 /*!
411 \fn QList<TimerInfo> QAbstractEventDispatcher::registeredTimers(QObject *object) const
412
413 Returns a list of registered timers for \a object. The timer ID
414 is the first member in each pair; the interval is the second.
415 */
416
417 /*! \fn void QAbstractEventDispatcher::wakeUp()
418 \threadsafe
419
420 Wakes up the event loop.
421
422 \sa awake()
423 */
424
425 /*!
426 \fn void QAbstractEventDispatcher::interrupt()
427
428 Interrupts event dispatching; i.e. the event dispatcher will
429 return from processEvents() as soon as possible.
430 */
431
432 /*! \fn void QAbstractEventDispatcher::flush()
433
434 Flushes the event queue. This normally returns almost
435 immediately. Does nothing on platforms other than X11.
436 */
437
438 // ### DOC: Are these called when the _application_ starts/stops or just
439 // when the current _event loop_ starts/stops?
440 /*! \internal */
startingUp()441 void QAbstractEventDispatcher::startingUp()
442 { }
443
444 /*! \internal */
closingDown()445 void QAbstractEventDispatcher::closingDown()
446 { }
447
448 /*!
449 \typedef QAbstractEventDispatcher::TimerInfo
450
451 Typedef for QPair<int, int>. The first component of
452 the pair is the timer ID; the second component is
453 the interval.
454
455 \sa registeredTimers()
456 */
457
458 /*!
459 \typedef QAbstractEventDispatcher::EventFilter
460
461 Typedef for a function with the signature
462
463 \snippet doc/src/snippets/code/src_corelib_kernel_qabstracteventdispatcher.cpp 0
464
465 Note that the type of the \a message is platform dependent. The
466 following table shows the \a {message}'s type on Windows, Mac, X11
467 and BlackBerry. You can do a static cast to these types.
468
469 \table
470 \header
471 \o Platform
472 \o type
473 \row
474 \o Windows
475 \o MSG
476 \row
477 \o X11
478 \o XEvent
479 \row
480 \o Mac
481 \o NSEvent
482 \row
483 \o BlackBerry
484 \o bps_event_t
485 \endtable
486
487
488
489 \sa setEventFilter(), filterEvent()
490 */
491
492 /*!
493 Replaces the event filter function for this
494 QAbstractEventDispatcher with \a filter and returns the replaced
495 event filter function. Only the current event filter function is
496 called. If you want to use both filter functions, save the
497 replaced EventFilter in a place where yours can call it.
498
499 The event filter function set here is called for all messages
500 taken from the system event loop before the event is dispatched to
501 the respective target, including the messages not meant for Qt
502 objects.
503
504 The event filter function should return true if the message should
505 be filtered, (i.e. stopped). It should return false to allow
506 processing the message to continue.
507
508 By default, no event filter function is set (i.e., this function
509 returns a null EventFilter the first time it is called).
510 */
setEventFilter(EventFilter filter)511 QAbstractEventDispatcher::EventFilter QAbstractEventDispatcher::setEventFilter(EventFilter filter)
512 {
513 Q_D(QAbstractEventDispatcher);
514 EventFilter oldFilter = d->event_filter;
515 d->event_filter = filter;
516 return oldFilter;
517 }
518
519 /*!
520 Sends \a message through the event filter that was set by
521 setEventFilter(). If no event filter has been set, this function
522 returns false; otherwise, this function returns the result of the
523 event filter function.
524
525 Subclasses of QAbstractEventDispatcher \e must call this function
526 for \e all messages received from the system to ensure
527 compatibility with any extensions that may be used in the
528 application.
529
530 Note that the type of \a message is platform dependent. See
531 QAbstractEventDispatcher::EventFilter for details.
532
533 \sa setEventFilter()
534 */
filterEvent(void * message)535 bool QAbstractEventDispatcher::filterEvent(void *message)
536 {
537 Q_D(QAbstractEventDispatcher);
538 if (d->event_filter) {
539 // Raise the loopLevel so that deleteLater() calls in or triggered
540 // by event_filter() will be processed from the main event loop.
541 QScopedLoopLevelCounter loopLevelCounter(d->threadData);
542 return d->event_filter(message);
543 }
544 return false;
545 }
546
547 /*! \fn void QAbstractEventDispatcher::awake()
548
549 This signal is emitted after the event loop returns from a
550 function that could block.
551
552 \sa wakeUp() aboutToBlock()
553 */
554
555 /*! \fn void QAbstractEventDispatcher::aboutToBlock()
556
557 This signal is emitted before the event loop calls a function that
558 could block.
559
560 \sa awake()
561 */
562
563 QT_END_NAMESPACE
564