1
/****************************************************************************
2
**
3
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
7
** This file is part of the QtCore module of the Qt Toolkit.
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17
**
18
** In addition, as a special exception, Nokia gives you certain additional
19
** rights. These rights are described in the Nokia Qt LGPL Exception
20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21
**
22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
29
**
30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
33
**
34
**
35
**
36
**
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
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
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
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
135
static inline int bucketIndex(int bucket, int timerId)
136
{
137
    return timerId - BucketOffset[bucket];
138
}
139
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
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).
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.
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
*/
278
QAbstractEventDispatcher::QAbstractEventDispatcher(QObject *parent)
279
    : QObject(*new QAbstractEventDispatcherPrivate, parent)
280
{
281
    Q_D(QAbstractEventDispatcher);
282
    d->init();
283
}
284
285
/*!
286
    \internal
287
*/
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
*/
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
 */
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
*/
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 */
441
void QAbstractEventDispatcher::startingUp()
442
{ }
443
444
/*! \internal */
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, and
467
    X11. 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
    \endtable
483
484
    
485
486
    \sa setEventFilter(), filterEvent()
487
*/
488
489
/*!
490
    Replaces the event filter function for this
491
    QAbstractEventDispatcher with \a filter and returns the replaced
492
    event filter function. Only the current event filter function is
493
    called. If you want to use both filter functions, save the
494
    replaced EventFilter in a place where yours can call it.
495
496
    The event filter function set here is called for all messages
497
    taken from the system event loop before the event is dispatched to
498
    the respective target, including the messages not meant for Qt
499
    objects.
500
501
    The event filter function should return true if the message should
502
    be filtered, (i.e. stopped). It should return false to allow
503
    processing the message to continue.
504
505
    By default, no event filter function is set (i.e., this function
506
    returns a null EventFilter the first time it is called).
507
*/
508
QAbstractEventDispatcher::EventFilter QAbstractEventDispatcher::setEventFilter(EventFilter filter)
509
{
510
    Q_D(QAbstractEventDispatcher);
511
    EventFilter oldFilter = d->event_filter;
512
    d->event_filter = filter;
513
    return oldFilter;
514
}
515
516
/*!
517
    Sends \a message through the event filter that was set by
518
    setEventFilter().  If no event filter has been set, this function
519
    returns false; otherwise, this function returns the result of the
520
    event filter function.
521
522
    Subclasses of QAbstractEventDispatcher \e must call this function
523
    for \e all messages received from the system to ensure
524
    compatibility with any extensions that may be used in the
525
    application.
526
527
    Note that the type of \a message is platform dependent. See 
528
    QAbstractEventDispatcher::EventFilter for details.
529
530
    \sa setEventFilter()
531
*/
532
bool QAbstractEventDispatcher::filterEvent(void *message)
533
{
534
    Q_D(QAbstractEventDispatcher);
535
    if (d->event_filter) {
536
        // Raise the loopLevel so that deleteLater() calls in or triggered
537
        // by event_filter() will be processed from the main event loop.
538
        QScopedLoopLevelCounter loopLevelCounter(d->threadData);
539
        return d->event_filter(message);
540
    }
541
    return false;
542
}
543
544
/*! \fn void QAbstractEventDispatcher::awake()
545
546
    This signal is emitted after the event loop returns from a
547
    function that could block.
548
549
    \sa wakeUp() aboutToBlock()
550
*/
551
552
/*! \fn void QAbstractEventDispatcher::aboutToBlock()
553
554
    This signal is emitted before the event loop calls a function that
555
    could block.
556
557
    \sa awake()
558
*/
559
560
QT_END_NAMESPACE