fix cleanup of QWinIoCompletionPort
authorJoerg Bornemann <joerg.bornemann@digia.com>
Thu, 1 Nov 2012 13:57:27 +0000 (14:57 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 2 Nov 2012 17:07:35 +0000 (18:07 +0100)
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 <oswald.buddenhagen@digia.com>
src/corelib/io/qwinoverlappedionotifier.cpp
src/corelib/io/qwinoverlappedionotifier_p.h

index c084912..8fa3648 100644 (file)
@@ -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);
 }
 
 /*!
index 331d915..d8d851a 100644 (file)
@@ -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;