e5fcad3 by Lars Knoll at 2009-03-23 1
/****************************************************************************
2
**
89c08c0 by Jason McDonald at 2012-01-11 3
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
04e3b30 by Jason McDonald at 2009-09-09 4
** All rights reserved.
858c70f by Jason McDonald at 2009-06-16 5
** Contact: Nokia Corporation (qt-info@nokia.com)
e5fcad3 by Lars Knoll at 2009-03-23 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
1eea52e by Jyri Tahtela at 2011-05-13 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.
e5fcad3 by Lars Knoll at 2009-03-23 17
**
04e3b30 by Jason McDonald at 2009-09-09 18
** In addition, as a special exception, Nokia gives you certain additional
1eea52e by Jyri Tahtela at 2011-05-13 19
** rights. These rights are described in the Nokia Qt LGPL Exception
04e3b30 by Jason McDonald at 2009-09-09 20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
e5fcad3 by Lars Knoll at 2009-03-23 21
**
1eea52e by Jyri Tahtela at 2011-05-13 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.
309db73 by Jason McDonald at 2009-08-31 29
**
1eea52e by Jyri Tahtela at 2011-05-13 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.
309db73 by Jason McDonald at 2009-08-31 33
**
34
**
35
**
36
**
e5fcad3 by Lars Knoll at 2009-03-23 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
290bc1e by Thiago Macieira at 2011-04-14 52
static const int TimerIdMask = 0x00ffffff;
53
static const int TimerSerialMask = ~TimerIdMask & ~0x80000000;
54
static const int TimerSerialCounter = TimerIdMask + 1;
050928a by Thiago Macieira at 2011-04-14 55
static const int MaxTimerId = TimerIdMask;
8f08be2 by Thiago Macieira at 2011-04-13 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
};
e5fcad3 by Lars Knoll at 2009-03-23 61
050928a by Thiago Macieira at 2011-04-14 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[] =
e5fcad3 by Lars Knoll at 2009-03-23 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
{
a02a747 by Thiago Macieira at 2010-12-13 112
    return (newId & TimerIdMask) | ((oldId + TimerSerialCounter) & TimerSerialMask);
e5fcad3 by Lars Knoll at 2009-03-23 113
}
114
050928a by Thiago Macieira at 2011-04-14 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
e5fcad3 by Lars Knoll at 2009-03-23 121
static inline int bucketOffset(int timerId)
122
{
050928a by Thiago Macieira at 2011-04-14 123
    q_static_assert(sizeof BucketSize == sizeof BucketOffset);
124
    q_static_assert(sizeof(timerIds) / sizeof(timerIds[0]) == NumberOfBuckets);
125
e5fcad3 by Lars Knoll at 2009-03-23 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
b8f639f by Thiago Macieira at 2010-12-13 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
bd9d5c8 by Thiago Macieira at 2010-12-13 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
//
b8f639f by Thiago Macieira at 2010-12-13 174
// (continues below).
e5fcad3 by Lars Knoll at 2009-03-23 175
int QAbstractEventDispatcherPrivate::allocateTimerId()
176
{
177
    int timerId, newTimerId;
bd9d5c8 by Thiago Macieira at 2010-12-13 178
    int at, *b;
e5fcad3 by Lars Knoll at 2009-03-23 179
    do {
b8f639f by Thiago Macieira at 2010-12-13 180
        timerId = nextFreeTimerId; //.loadAcquire(); // ### FIXME Proper memory ordering semantics
e5fcad3 by Lars Knoll at 2009-03-23 181
182
        // which bucket are we looking in?
a02a747 by Thiago Macieira at 2010-12-13 183
        int which = timerId & TimerIdMask;
e5fcad3 by Lars Knoll at 2009-03-23 184
        int bucket = bucketOffset(which);
bd9d5c8 by Thiago Macieira at 2010-12-13 185
        at = bucketIndex(bucket, which);
186
        b = timerIds[bucket];
e5fcad3 by Lars Knoll at 2009-03-23 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
f0a892a by Thiago Macieira at 2010-12-13 198
        newTimerId = prepareNewValueWithSerialNumber(timerId, b[at]);
e5fcad3 by Lars Knoll at 2009-03-23 199
    } while (!nextFreeTimerId.testAndSetRelaxed(timerId, newTimerId));
200
bd9d5c8 by Thiago Macieira at 2010-12-13 201
    b[at] = -timerId;
202
e5fcad3 by Lars Knoll at 2009-03-23 203
    return timerId;
204
}
205
b8f639f by Thiago Macieira at 2010-12-13 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.
e5fcad3 by Lars Knoll at 2009-03-23 217
void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId)
218
{
a02a747 by Thiago Macieira at 2010-12-13 219
    int which = timerId & TimerIdMask;
e5fcad3 by Lars Knoll at 2009-03-23 220
    int bucket = bucketOffset(which);
221
    int at = bucketIndex(bucket, which);
222
    int *b = timerIds[bucket];
223
162ee8d by Thiago Macieira at 2011-04-13 224
    Q_ASSERT_X(timerId == -b[at], "QAbstractEventDispatcher::releaseTimerId",
225
               "Internal error: timer ID not found");
bd9d5c8 by Thiago Macieira at 2010-12-13 226
e5fcad3 by Lars Knoll at 2009-03-23 227
    int freeId, newTimerId;
228
    do {
b8f639f by Thiago Macieira at 2010-12-13 229
        freeId = nextFreeTimerId;//.loadAcquire(); // ### FIXME Proper memory ordering semantics
a02a747 by Thiago Macieira at 2010-12-13 230
        b[at] = freeId & TimerIdMask;
e5fcad3 by Lars Knoll at 2009-03-23 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
40fb475 by artoka at 2012-01-31 268
    \l{Motif Extension}
269
    includes a reimplementation of QAbstractEventDispatcher that merges Qt and
e5fcad3 by Lars Knoll at 2009-03-23 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
594900e by Geir Vattekar at 2010-06-17 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
e5fcad3 by Lars Knoll at 2009-03-23 486
    \sa setEventFilter(), filterEvent()
487
*/
488
489
/*!
b420385 by Martin Smith at 2009-07-10 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
e5fcad3 by Lars Knoll at 2009-03-23 499
    objects.
500
b420385 by Martin Smith at 2009-07-10 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.
e5fcad3 by Lars Knoll at 2009-03-23 504
b420385 by Martin Smith at 2009-07-10 505
    By default, no event filter function is set (i.e., this function
506
    returns a null EventFilter the first time it is called).
e5fcad3 by Lars Knoll at 2009-03-23 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
594900e by Geir Vattekar at 2010-06-17 527
    Note that the type of \a message is platform dependent. See 
528
    QAbstractEventDispatcher::EventFilter for details.
529
e5fcad3 by Lars Knoll at 2009-03-23 530
    \sa setEventFilter()
531
*/
532
bool QAbstractEventDispatcher::filterEvent(void *message)
533
{
534
    Q_D(QAbstractEventDispatcher);
6bab6fc by John Stanley at 2012-02-10 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);
e5fcad3 by Lars Knoll at 2009-03-23 539
        return d->event_filter(message);
6bab6fc by John Stanley at 2012-02-10 540
    }
e5fcad3 by Lars Knoll at 2009-03-23 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