Skip to content

Commit

Permalink
Revert "Support more than 62 instances of QWinEventNotifier"
Browse files Browse the repository at this point in the history
It breaks sth in QLocalSocket which is used in QtRemoteObject.

This reverts commit 5c6210e.

Task-number: QTBUG-61668
Change-Id: Ib11890923773496e5d998b7709ef93b0a839a759
Reviewed-by: Joerg Bornemann <[email protected]>
  • Loading branch information
liangqi committed Jun 28, 2017
1 parent 57a77fe commit 80406bd
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 260 deletions.
3 changes: 1 addition & 2 deletions src/corelib/kernel/kernel.pri
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ win32 {
kernel/qsharedmemory_win.cpp \
kernel/qsystemsemaphore_win.cpp
HEADERS += \
kernel/qwineventnotifier.h \
kernel/qwineventnotifier_p.h
kernel/qwineventnotifier.h

winrt {
SOURCES += kernel/qeventdispatcher_winrt.cpp
Expand Down
67 changes: 26 additions & 41 deletions src/corelib/kernel/qeventdispatcher_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
#include "qcoreapplication_p.h"
#include <private/qthread_p.h>
#include <private/qmutexpool_p.h>
#include <private/qwineventnotifier_p.h>

QT_BEGIN_NAMESPACE

Expand Down Expand Up @@ -97,14 +96,13 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
: threadId(GetCurrentThreadId()), interrupt(false), closingDown(false), internalHwnd(0),
getMessageHook(0), serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0),
wakeUps(0), activateNotifiersPosted(false), winEventNotifierActivatedEvent(NULL)
wakeUps(0)
, activateNotifiersPosted(false)
{
}

QEventDispatcherWin32Private::~QEventDispatcherWin32Private()
{
if (winEventNotifierActivatedEvent)
CloseHandle(winEventNotifierActivatedEvent);
if (internalHwnd)
DestroyWindow(internalHwnd);
}
Expand Down Expand Up @@ -539,14 +537,12 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
bool needWM_QT_SENDPOSTEDEVENTS = false;
do {
DWORD waitRet = 0;
DWORD nCount = 0;
HANDLE *pHandles = nullptr;
if (d->winEventNotifierActivatedEvent) {
nCount = 1;
pHandles = &d->winEventNotifierActivatedEvent;
}
HANDLE pHandles[MAXIMUM_WAIT_OBJECTS - 1];
QVarLengthArray<MSG> processedTimers;
while (!d->interrupt) {
DWORD nCount = d->winEventNotifierList.count();
Q_ASSERT(nCount < MAXIMUM_WAIT_OBJECTS - 1);

MSG msg;
bool haveMessage;

Expand Down Expand Up @@ -588,6 +584,8 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
}
if (!haveMessage) {
// no message - check for signalled objects
for (int i=0; i<(int)nCount; i++)
pHandles[i] = d->winEventNotifierList.at(i)->handle();
waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, 0, QS_ALLINPUT, MWMO_ALERTABLE);
if ((haveMessage = (waitRet == WAIT_OBJECT_0 + nCount))) {
// a new message has arrived, process it
Expand Down Expand Up @@ -628,7 +626,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
DispatchMessage(&msg);
}
} else if (waitRet - WAIT_OBJECT_0 < nCount) {
activateEventNotifiers();
d->activateEventNotifier(d->winEventNotifierList.at(waitRet - WAIT_OBJECT_0));
} else {
// nothing todo so break
break;
Expand All @@ -641,11 +639,16 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
&& !d->interrupt
&& (flags & QEventLoop::WaitForMoreEvents));
if (canWait) {
DWORD nCount = d->winEventNotifierList.count();
Q_ASSERT(nCount < MAXIMUM_WAIT_OBJECTS - 1);
for (int i=0; i<(int)nCount; i++)
pHandles[i] = d->winEventNotifierList.at(i)->handle();

emit aboutToBlock();
waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
emit awake();
if (waitRet - WAIT_OBJECT_0 < nCount) {
activateEventNotifiers();
d->activateEventNotifier(d->winEventNotifierList.at(waitRet - WAIT_OBJECT_0));
retVal = true;
}
}
Expand Down Expand Up @@ -903,12 +906,12 @@ bool QEventDispatcherWin32::registerEventNotifier(QWinEventNotifier *notifier)
if (d->winEventNotifierList.contains(notifier))
return true;

if (d->winEventNotifierList.count() >= MAXIMUM_WAIT_OBJECTS - 2) {
qWarning("QWinEventNotifier: Cannot have more than %d enabled at one time", MAXIMUM_WAIT_OBJECTS - 2);
return false;
}
d->winEventNotifierList.append(notifier);

if (!d->winEventNotifierActivatedEvent)
d->winEventNotifierActivatedEvent = CreateEvent(0, TRUE, FALSE, nullptr);

return QWinEventNotifierPrivate::get(notifier)->registerWaitObject();
return true;
}

void QEventDispatcherWin32::unregisterEventNotifier(QWinEventNotifier *notifier)
Expand All @@ -924,35 +927,17 @@ void QEventDispatcherWin32::unregisterEventNotifier(QWinEventNotifier *notifier)
Q_D(QEventDispatcherWin32);

int i = d->winEventNotifierList.indexOf(notifier);
if (i == -1)
return;
d->winEventNotifierList.takeAt(i);
QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier);
if (nd->waitHandle)
nd->unregisterWaitObject();
if (i != -1)
d->winEventNotifierList.takeAt(i);
}

void QEventDispatcherWin32::activateEventNotifiers()
{
Q_D(QEventDispatcherWin32);
ResetEvent(d->winEventNotifierActivatedEvent);

// Iterate backwards, because the notifier might remove itself on activate().
for (int i = d->winEventNotifierList.count(); --i >= 0;) {
QWinEventNotifier *notifier = d->winEventNotifierList.at(i);
QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier);
if (WaitForSingleObject(nd->handleToEvent, 0) == WAIT_OBJECT_0) {
nd->unregisterWaitObject();
d->activateEventNotifier(notifier);
}
}

// Re-register the remaining activated notifiers.
for (int i = 0; i < d->winEventNotifierList.count(); ++i) {
QWinEventNotifier *notifier = d->winEventNotifierList.at(i);
QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier);
if (nd->waitHandle || !nd->registerWaitObject())
return;
//### this could break if events are removed/added in the activation
for (int i=0; i<d->winEventNotifierList.count(); i++) {
if (WaitForSingleObjectEx(d->winEventNotifierList.at(i)->handle(), 0, TRUE) == WAIT_OBJECT_0)
d->activateEventNotifier(d->winEventNotifierList.at(i));
}
}

Expand Down
2 changes: 0 additions & 2 deletions src/corelib/kernel/qeventdispatcher_win_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ class Q_CORE_EXPORT QEventDispatcherWin32Private : public QAbstractEventDispatch
public:
QEventDispatcherWin32Private();
~QEventDispatcherWin32Private();
static QEventDispatcherWin32Private *get(QEventDispatcherWin32 *q) { return q->d_func(); }

DWORD threadId;

Expand Down Expand Up @@ -193,7 +192,6 @@ class Q_CORE_EXPORT QEventDispatcherWin32Private : public QAbstractEventDispatch
void postActivateSocketNotifiers();
void doWsaAsyncSelect(int socket, long event);

HANDLE winEventNotifierActivatedEvent;
QList<QWinEventNotifier *> winEventNotifierList;
void activateEventNotifier(QWinEventNotifier * wen);

Expand Down
60 changes: 14 additions & 46 deletions src/corelib/kernel/qwineventnotifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
**
****************************************************************************/

#include "qwineventnotifier_p.h"
#include "qwineventnotifier.h"

#ifdef Q_OS_WINRT
#include "qeventdispatcher_winrt_p.h"
Expand All @@ -50,6 +50,19 @@

QT_BEGIN_NAMESPACE

class QWinEventNotifierPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QWinEventNotifier)
public:
QWinEventNotifierPrivate()
: handleToEvent(0), enabled(false) {}
QWinEventNotifierPrivate(HANDLE h, bool e)
: handleToEvent(h), enabled(e) {}

HANDLE handleToEvent;
bool enabled;
};

/*!
\class QWinEventNotifier
\inmodule QtCore
Expand Down Expand Up @@ -233,49 +246,4 @@ bool QWinEventNotifier::event(QEvent * e)
return false;
}

#if defined(Q_OS_WINRT)

bool QWinEventNotifierPrivate::registerWaitObject()
{
Q_UNIMPLEMENTED();
return false;
}

void QWinEventNotifierPrivate::unregisterWaitObject()
{
Q_UNIMPLEMENTED();
}

#else // defined(Q_OS_WINRT)

static void CALLBACK wfsoCallback(void *context, BOOLEAN /*ignore*/)
{
QWinEventNotifierPrivate *nd = reinterpret_cast<QWinEventNotifierPrivate *>(context);
QAbstractEventDispatcher *eventDispatcher = nd->threadData->eventDispatcher.load();
QEventDispatcherWin32Private *edp = QEventDispatcherWin32Private::get(
static_cast<QEventDispatcherWin32 *>(eventDispatcher));
SetEvent(edp->winEventNotifierActivatedEvent);
}

bool QWinEventNotifierPrivate::registerWaitObject()
{
if (RegisterWaitForSingleObject(&waitHandle, handleToEvent, wfsoCallback, this,
INFINITE, WT_EXECUTEONLYONCE) == 0) {
qErrnoWarning("QWinEventNotifier: RegisterWaitForSingleObject failed.");
return false;
}
return true;
}

void QWinEventNotifierPrivate::unregisterWaitObject()
{
// Unregister the wait handle and wait for pending callbacks to finish.
if (UnregisterWaitEx(waitHandle, INVALID_HANDLE_VALUE))
waitHandle = NULL;
else
qErrnoWarning("QWinEventNotifier: UnregisterWaitEx failed.");
}

#endif // !defined(Q_OS_WINRT)

QT_END_NAMESPACE
81 changes: 0 additions & 81 deletions src/corelib/kernel/qwineventnotifier_p.h

This file was deleted.

Loading

0 comments on commit 80406bd

Please sign in to comment.