Allow QWinEventNotifier to coexist with waiting functions
Many subclasses of QIODevice have a functionality to block execution until some asynchronous I/O operation completes. In case we are using QWinEventNotifier, a typical reimplemented waitFor{ReadyRead |BytesWritten}() function could look like: if (WaitForSingleObject(notifier.handle(),...) == WAIT_OBJECT_0) { notifier.setEnabled(false); ResetEvent(notifier.handle()); bool res = GetOverlappedResult(...); ... return true; } Despite the fact that the operation ends synchronously, it leaves the notifier in a state that indicates it has received the event, so its next call to setEnabled(true) will produce a fake notification. So, we should reset a notifier's history before enabling it again. Change-Id: I62a9dd809ce6a7a40e9d8038f2a49299b36f8142 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
parent
09f3b19f98
commit
cdbd68fc2f
@ -157,7 +157,6 @@ void QWinEventNotifier::setHandle(HANDLE hEvent)
|
||||
Q_D(QWinEventNotifier);
|
||||
setEnabled(false);
|
||||
d->handleToEvent = hEvent;
|
||||
d->signaledCount = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -209,10 +208,12 @@ void QWinEventNotifier::setEnabled(bool enable)
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable)
|
||||
if (enable) {
|
||||
d->signaledCount = 0;
|
||||
eventDispatcher->registerEventNotifier(this);
|
||||
else
|
||||
} else {
|
||||
eventDispatcher->unregisterEventNotifier(this);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -46,6 +46,7 @@ protected slots:
|
||||
private slots:
|
||||
void simple_data();
|
||||
void simple();
|
||||
void blockedWaiting();
|
||||
void manyNotifiers();
|
||||
void disableNotifiersInActivatedSlot_data();
|
||||
void disableNotifiersInActivatedSlot();
|
||||
@ -104,6 +105,26 @@ void tst_QWinEventNotifier::simple()
|
||||
QVERIFY(simpleActivated);
|
||||
}
|
||||
|
||||
void tst_QWinEventNotifier::blockedWaiting()
|
||||
{
|
||||
simpleHEvent = CreateEvent(0, true, false, 0);
|
||||
QWinEventNotifier n(simpleHEvent);
|
||||
QObject::connect(&n, &QWinEventNotifier::activated,
|
||||
this, &tst_QWinEventNotifier::simple_activated);
|
||||
simpleActivated = false;
|
||||
|
||||
SetEvent(simpleHEvent);
|
||||
QCOMPARE(WaitForSingleObject(simpleHEvent, 1000), WAIT_OBJECT_0);
|
||||
|
||||
n.setEnabled(false);
|
||||
ResetEvent(simpleHEvent);
|
||||
n.setEnabled(true);
|
||||
|
||||
QTestEventLoop::instance().enterLoop(1);
|
||||
QVERIFY(QTestEventLoop::instance().timeout());
|
||||
QVERIFY(!simpleActivated);
|
||||
}
|
||||
|
||||
class EventWithNotifier : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
Loading…
Reference in New Issue
Block a user