From 40c9a3ef11ba8b513633dce3d0cf352efdf2352e Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 1 Nov 2012 14:57:27 +0100 Subject: fix cleanup of QWinIoCompletionPort The QWinIoCompletionPort thread was never properly cleaned up. Maintain a reference count for QWinIoCompletionPort and create/destroy it on demand. Change-Id: I607b574484554dd3ad107dfb43b0a248bcf8b7a4 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwinoverlappedionotifier.cpp | 21 ++++++++++++++++++--- src/corelib/io/qwinoverlappedionotifier_p.h | 5 +++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qwinoverlappedionotifier.cpp b/src/corelib/io/qwinoverlappedionotifier.cpp index c084912897..8fa3648987 100644 --- a/src/corelib/io/qwinoverlappedionotifier.cpp +++ b/src/corelib/io/qwinoverlappedionotifier.cpp @@ -161,12 +161,20 @@ private: QMutex mutex; }; -Q_GLOBAL_STATIC(QWinIoCompletionPort, iocp) +QWinIoCompletionPort *QWinOverlappedIoNotifier::iocp = 0; +HANDLE QWinOverlappedIoNotifier::iocpInstanceLock = CreateMutex(NULL, FALSE, NULL); +unsigned int QWinOverlappedIoNotifier::iocpInstanceRefCount = 0; QWinOverlappedIoNotifier::QWinOverlappedIoNotifier(QObject *parent) : QObject(parent), hHandle(INVALID_HANDLE_VALUE) { + WaitForSingleObject(iocpInstanceLock, INFINITE); + if (!iocp) + iocp = new QWinIoCompletionPort; + iocpInstanceRefCount++; + ReleaseMutex(iocpInstanceLock); + hSemaphore = CreateSemaphore(NULL, 0, 255, NULL); hResultsMutex = CreateMutex(NULL, FALSE, NULL); connect(this, &QWinOverlappedIoNotifier::_q_notify, @@ -178,6 +186,13 @@ QWinOverlappedIoNotifier::~QWinOverlappedIoNotifier() setEnabled(false); CloseHandle(hResultsMutex); CloseHandle(hSemaphore); + + WaitForSingleObject(iocpInstanceLock, INFINITE); + if (!--iocpInstanceRefCount) { + delete iocp; + iocp = 0; + } + ReleaseMutex(iocpInstanceLock); } void QWinOverlappedIoNotifier::setHandle(HANDLE h) @@ -188,9 +203,9 @@ void QWinOverlappedIoNotifier::setHandle(HANDLE h) void QWinOverlappedIoNotifier::setEnabled(bool enabled) { if (enabled) - iocp()->registerNotifier(this); + iocp->registerNotifier(this); else - iocp()->unregisterNotifier(this); + iocp->unregisterNotifier(this); } /*! diff --git a/src/corelib/io/qwinoverlappedionotifier_p.h b/src/corelib/io/qwinoverlappedionotifier_p.h index 331d915ccc..d8d851a3a1 100644 --- a/src/corelib/io/qwinoverlappedionotifier_p.h +++ b/src/corelib/io/qwinoverlappedionotifier_p.h @@ -61,6 +61,8 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +class QWinIoCompletionPort; + class Q_CORE_EXPORT QWinOverlappedIoNotifier : public QObject { Q_OBJECT @@ -85,6 +87,9 @@ private: void notify(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped); private: + static QWinIoCompletionPort *iocp; + static HANDLE iocpInstanceLock; + static unsigned int iocpInstanceRefCount; HANDLE hHandle; HANDLE hSemaphore; HANDLE hResultsMutex; -- cgit v1.2.3