summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp44
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h2
-rw-r--r--tests/auto/gui/kernel/kernel.pro2
-rw-r--r--tests/auto/gui/kernel/noqteventloop/noqteventloop.pro2
-rw-r--r--tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp34
5 files changed, 69 insertions, 15 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 695eb3d5d0..812494372d 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -79,6 +79,7 @@ extern uint qGlobalPostedEventsCount();
enum {
WM_QT_SOCKETNOTIFIER = WM_USER,
WM_QT_SENDPOSTEDEVENTS = WM_USER + 1,
+ WM_QT_ACTIVATENOTIFIERS = WM_USER + 2,
SendPostedEventsWindowsTimerId = ~1u
};
@@ -309,7 +310,7 @@ static void resolveTimerAPI()
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
: threadId(GetCurrentThreadId()), interrupt(false), closingDown(false), internalHwnd(0),
getMessageHook(0), serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0),
- wakeUps(0)
+ wakeUps(0), activateNotifiersPosted(false)
{
resolveTimerAPI();
}
@@ -393,6 +394,7 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
if (sn) {
d->doWsaAsyncSelect(sn->fd, 0);
d->active_fd[sn->fd].selected = false;
+ d->postActivateSocketNotifiers();
if (type < 3) {
QEvent event(QEvent::SockAct);
QCoreApplication::sendEvent(sn->obj, &event);
@@ -403,6 +405,20 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
}
}
return 0;
+ } else if (message == WM_QT_ACTIVATENOTIFIERS) {
+ Q_ASSERT(d != 0);
+
+ // register all socket notifiers
+ for (QSFDict::iterator it = d->active_fd.begin(), end = d->active_fd.end();
+ it != end; ++it) {
+ QSockFd &sd = it.value();
+ if (!sd.selected) {
+ d->doWsaAsyncSelect(it.key(), sd.event);
+ sd.selected = true;
+ }
+ }
+ d->activateNotifiersPosted = false;
+ return 0;
} else if (message == WM_QT_SENDPOSTEDEVENTS
// we also use a Windows timer to send posted events when the message queue is full
|| (message == WM_TIMER
@@ -643,6 +659,12 @@ void QEventDispatcherWin32Private::doWsaAsyncSelect(int socket, long event)
WSAAsyncSelect(socket, internalHwnd, event ? int(WM_QT_SOCKETNOTIFIER) : 0, event);
}
+void QEventDispatcherWin32Private::postActivateSocketNotifiers()
+{
+ if (!activateNotifiersPosted)
+ activateNotifiersPosted = PostMessage(internalHwnd, WM_QT_ACTIVATENOTIFIERS, 0, 0);
+}
+
void QEventDispatcherWin32::createInternalHwnd()
{
Q_D(QEventDispatcherWin32);
@@ -761,16 +783,6 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
d->queuedSocketEvents.append(msg);
continue;
}
- } else if (!(flags & QEventLoop::ExcludeSocketNotifiers)) {
- // register all socket notifiers
- for (QSFDict::iterator it = d->active_fd.begin(), end = d->active_fd.end();
- it != end; ++it) {
- QSockFd &sd = it.value();
- if (!sd.selected) {
- d->doWsaAsyncSelect(it.key(), sd.event);
- sd.selected = true;
- }
- }
}
}
if (!haveMessage) {
@@ -891,6 +903,8 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier)
"same socket %d and type %s", sockfd, t[type]);
}
+ createInternalHwnd();
+
QSockNot *sn = new QSockNot;
sn->obj = notifier;
sn->fd = sockfd;
@@ -915,6 +929,8 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier)
} else {
d->active_fd.insert(sockfd, QSockFd(event));
}
+
+ d->postActivateSocketNotifiers();
}
void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier)
@@ -940,10 +956,12 @@ void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier)
d->doWsaAsyncSelect(sockfd, 0);
const long event[3] = { FD_READ | FD_CLOSE | FD_ACCEPT, FD_WRITE | FD_CONNECT, FD_OOB };
sd.event ^= event[type];
- if (sd.event == 0)
+ if (sd.event == 0) {
d->active_fd.erase(it);
- else
+ } else if (sd.selected) {
sd.selected = false;
+ d->postActivateSocketNotifiers();
+ }
}
QSNDict *sn_vec[3] = { &d->sn_read, &d->sn_write, &d->sn_except };
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index 8578110ee4..9a53e06730 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -178,7 +178,9 @@ public:
QSNDict sn_write;
QSNDict sn_except;
QSFDict active_fd;
+ bool activateNotifiersPosted;
void doWsaAsyncSelect(int socket, long event);
+ void postActivateSocketNotifiers();
QList<QWinEventNotifier *> winEventNotifierList;
void activateEventNotifier(QWinEventNotifier * wen);
diff --git a/tests/auto/gui/kernel/kernel.pro b/tests/auto/gui/kernel/kernel.pro
index b03a117f83..5254e755d4 100644
--- a/tests/auto/gui/kernel/kernel.pro
+++ b/tests/auto/gui/kernel/kernel.pro
@@ -24,7 +24,7 @@ SUBDIRS=\
qopenglwindow \
qrasterwindow
-win32:!wince*:!winrt: SUBDIRS += noqteventloop
+win32:!wince:!winrt:qtHaveModule(network): SUBDIRS += noqteventloop
!qtHaveModule(widgets): SUBDIRS -= \
qmouseevent_modal \
diff --git a/tests/auto/gui/kernel/noqteventloop/noqteventloop.pro b/tests/auto/gui/kernel/noqteventloop/noqteventloop.pro
index de5715e147..a42b359f29 100644
--- a/tests/auto/gui/kernel/noqteventloop/noqteventloop.pro
+++ b/tests/auto/gui/kernel/noqteventloop/noqteventloop.pro
@@ -1,7 +1,7 @@
CONFIG += testcase
TARGET = tst_noqteventloop
-QT += core-private gui-private testlib
+QT += core-private network gui-private testlib
SOURCES += tst_noqteventloop.cpp
diff --git a/tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp b/tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp
index d21569dcc0..735d23b137 100644
--- a/tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp
+++ b/tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp
@@ -36,6 +36,9 @@
#include <QEvent>
#include <QtCore/qthread.h>
#include <QtGui/qguiapplication.h>
+#include <QtNetwork/qtcpserver.h>
+#include <QtNetwork/qtcpsocket.h>
+#include <QtCore/qelapsedtimer.h>
#include <QtCore/qt_windows.h>
@@ -47,6 +50,7 @@ private slots:
void initTestCase();
void cleanup();
void consumeMouseEvents();
+ void consumeSocketEvents();
};
@@ -265,6 +269,36 @@ void tst_NoQtEventLoop::consumeMouseEvents()
}
+void tst_NoQtEventLoop::consumeSocketEvents()
+{
+ int argc = 1;
+ char *argv[] = { const_cast<char *>("test"), 0 };
+ QGuiApplication app(argc, argv);
+ QTcpServer server;
+ QTcpSocket client;
+
+ QVERIFY(server.listen(QHostAddress::LocalHost));
+ client.connectToHost(server.serverAddress(), server.serverPort());
+ QVERIFY(client.waitForConnected());
+
+ QElapsedTimer elapsedTimer;
+ elapsedTimer.start();
+
+ // Exec own message loop
+ MSG msg;
+ forever {
+ if (elapsedTimer.hasExpired(3000) || server.hasPendingConnections())
+ break;
+
+ if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+ }
+ }
+
+ QVERIFY(server.hasPendingConnections());
+}
+
#include <tst_noqteventloop.moc>
QTEST_APPLESS_MAIN(tst_NoQtEventLoop)