Deprecate {QCoreApp,QAbstractEventDispatcher}::hasPendingEvents()

This function has a flawed design. It was flawed when it was added in
Qt 3.0.

A "false" return value is racy: any other thread running may post events
to the current thread, thus making the result stale. That includes Qt
starts for its own purposes when it comes to the main thread, like the
Scene Graph thread, the QProcessManager thread, the Windows
QAdoptedThread watcher thread, the Windows pipe writer thread, etc.

A "true" return is stable only if the selected thread is stopped, which
includes selecting the current thread (the case of QCoreApplication).
For that reason, this method should not be public, but a protected one
so that a public static could call it. But even that would not solve the
race condition from the previous paragraph (hence why
QCoreApplication::hasPendingEvents being deprecated too).

And, to top all of that off, all but one of the implementations access
the GUI thread's event loop counter in a non-thread-safe manner. I've
changed the documentation to restrict to the only currently-working use-
application.

[ChangeLog][QtCore][Event loop] QCoreApplication::hasPendingEvents and
QAbstractEventDispatcher::hasPendingEvents are now deprecated. Please
refer to the documentation for more information.

Task-number: QTBUG-36611
Change-Id: Iac61f307e9672839944ae2f75abb1aea30c419f6
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
bb10
Thiago Macieira 2014-02-03 15:37:42 -08:00 committed by The Qt Project
parent 1bf9f725d1
commit af8c35bda4
4 changed files with 14 additions and 4 deletions

View File

@ -210,9 +210,11 @@ QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
*/
/*! \fn bool QAbstractEventDispatcher::hasPendingEvents()
\deprecated
Returns \c true if there is an event waiting; otherwise returns
false.
Returns \c true if there is an event waiting; otherwise returns false. This
function is an implementation detail for
QCoreApplication::hasPendingEvents() and must not be called directly.
*/
/*!

View File

@ -78,7 +78,7 @@ public:
static QAbstractEventDispatcher *instance(QThread *thread = 0);
virtual bool processEvents(QEventLoop::ProcessEventsFlags flags) = 0;
virtual bool hasPendingEvents() = 0;
virtual bool hasPendingEvents() = 0; // ### Qt6: remove, mark final or make protected
virtual void registerSocketNotifier(QSocketNotifier *notifier) = 0;
virtual void unregisterSocketNotifier(QSocketNotifier *notifier) = 0;

View File

@ -2558,10 +2558,16 @@ void QCoreApplication::removeNativeEventFilter(QAbstractNativeEventFilter *filte
}
/*!
\deprecated
This function returns \c true if there are pending events; otherwise
returns \c false. Pending events can be either from the window
system or posted events using postEvent().
\note this function is not thread-safe. It may only be called in the main
thread and only if there are no other threads running in the application
(including threads Qt starts for its own purposes).
\sa QAbstractEventDispatcher::hasPendingEvents()
*/
bool QCoreApplication::hasPendingEvents()

View File

@ -127,7 +127,9 @@ public:
static void postEvent(QObject *receiver, QEvent *event, int priority = Qt::NormalEventPriority);
static void sendPostedEvents(QObject *receiver = 0, int event_type = 0);
static void removePostedEvents(QObject *receiver, int eventType = 0);
static bool hasPendingEvents();
#if QT_DEPRECATED_SINCE(5, 3)
QT_DEPRECATED static bool hasPendingEvents();
#endif
static QAbstractEventDispatcher *eventDispatcher();
static void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher);