From 2d54aac427d588be73a28e52fc59d0e62f975941 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 10 Jul 2017 15:41:37 +0200 Subject: Fix warning messages in QWindowsPipeReader/Writer We forgot to update the warnings when removing qt_cancelIo. Also, use %p instead of %x, because HANDLE is void*. This amends commit fade2958. Change-Id: Ia11d7d094aa6beb939e0be4bbe4ab3654eaa1c02 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipereader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib/io/qwindowspipereader.cpp') diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp index 827ed43b633..4065b194468 100644 --- a/src/corelib/io/qwindowspipereader.cpp +++ b/src/corelib/io/qwindowspipereader.cpp @@ -98,7 +98,7 @@ void QWindowsPipeReader::stop() if (!CancelIoEx(handle, &overlapped)) { const DWORD dwError = GetLastError(); if (dwError != ERROR_NOT_FOUND) { - qErrnoWarning(dwError, "QWindowsPipeReader: qt_cancelIo on handle %x failed.", + qErrnoWarning(dwError, "QWindowsPipeReader: CancelIoEx on handle %p failed.", handle); } } -- cgit v1.2.3 From c7ec07d40115bef849574c81d619b629af9434a9 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 12 Jul 2017 14:20:54 +0200 Subject: Do not wait in QWindowsPipe{Reader|Writer}::stop() A deadlock can occur if the user does QLocalSocket *ls = new QLocalSocket; ls->moveToThread(t); ... delete ls; Then QLocalSocket calls QWindowsPipeReader::stop() in a different thread than the I/O operation is running in. The waitForNotified(-1) call would then wait indefinitely until the I/O thread is in alertable wait state again. Especially on application shut down this might never be the case, and the application would deadlock. Solve this by detaching the Overlapped object from the QWindowsPipe{Reader|Writer} in stop() and delete it in the callback. Task-number: QTBUG-61643 Change-Id: Ie262d75c5fd92ac7cf7dfcdbf1519050be9fd3c4 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipereader.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src/corelib/io/qwindowspipereader.cpp') diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp index 4065b194468..b93fed5ba8e 100644 --- a/src/corelib/io/qwindowspipereader.cpp +++ b/src/corelib/io/qwindowspipereader.cpp @@ -57,7 +57,7 @@ void QWindowsPipeReader::Overlapped::clear() QWindowsPipeReader::QWindowsPipeReader(QObject *parent) : QObject(parent), handle(INVALID_HANDLE_VALUE), - overlapped(this), + overlapped(nullptr), readBufferMaxSize(0), actualReadBufferSize(0), stopped(true), @@ -74,6 +74,7 @@ QWindowsPipeReader::QWindowsPipeReader(QObject *parent) QWindowsPipeReader::~QWindowsPipeReader() { stop(); + delete overlapped; } /*! @@ -95,14 +96,16 @@ void QWindowsPipeReader::stop() { stopped = true; if (readSequenceStarted) { - if (!CancelIoEx(handle, &overlapped)) { + overlapped->pipeReader = nullptr; + if (!CancelIoEx(handle, overlapped)) { const DWORD dwError = GetLastError(); if (dwError != ERROR_NOT_FOUND) { qErrnoWarning(dwError, "QWindowsPipeReader: CancelIoEx on handle %p failed.", handle); } } - waitForNotification(-1); + overlapped = nullptr; // The object will be deleted in the I/O callback. + readSequenceStarted = false; } } @@ -232,8 +235,10 @@ void QWindowsPipeReader::startAsyncRead() stopped = false; readSequenceStarted = true; - overlapped.clear(); - if (!ReadFileEx(handle, ptr, bytesToRead, &overlapped, &readFileCompleted)) { + if (!overlapped) + overlapped = new Overlapped(this); + overlapped->clear(); + if (!ReadFileEx(handle, ptr, bytesToRead, overlapped, &readFileCompleted)) { readSequenceStarted = false; const DWORD dwError = GetLastError(); @@ -260,7 +265,10 @@ void QWindowsPipeReader::readFileCompleted(DWORD errorCode, DWORD numberOfBytesT OVERLAPPED *overlappedBase) { Overlapped *overlapped = static_cast(overlappedBase); - overlapped->pipeReader->notified(errorCode, numberOfBytesTransfered); + if (overlapped->pipeReader) + overlapped->pipeReader->notified(errorCode, numberOfBytesTransfered); + else + delete overlapped; } /*! -- cgit v1.2.3