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