fix spurious QWindowsPipeWriter deadlock

We must check the return value of CancelIo(Ex) and only wait for a
notification if it was successful.
CancelIoEx can fail, if the handle is closed before the
QWindowsPipeWriter destructor is called.

Change-Id: I2dcc97052be917c69d18c277856374cbc07e2169
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
This commit is contained in:
Joerg Bornemann 2013-03-01 15:47:15 +01:00 committed by The Qt Project
parent ba75f60449
commit 17869a544e

View File

@ -64,7 +64,7 @@ QWindowsPipeReader::QWindowsPipeReader(QObject *parent)
connect(dataReadNotifier, &QWinOverlappedIoNotifier::notified, this, &QWindowsPipeReader::notified);
}
static void qt_cancelIo(HANDLE handle, OVERLAPPED *overlapped)
static bool qt_cancelIo(HANDLE handle, OVERLAPPED *overlapped)
{
typedef BOOL (WINAPI *PtrCancelIoEx)(HANDLE, LPOVERLAPPED);
static PtrCancelIoEx ptrCancelIoEx = 0;
@ -74,16 +74,18 @@ static void qt_cancelIo(HANDLE handle, OVERLAPPED *overlapped)
ptrCancelIoEx = PtrCancelIoEx(GetProcAddress(kernel32, "CancelIoEx"));
}
if (ptrCancelIoEx)
ptrCancelIoEx(handle, overlapped);
return ptrCancelIoEx(handle, overlapped);
else
CancelIo(handle);
return CancelIo(handle);
}
QWindowsPipeReader::~QWindowsPipeReader()
{
if (readSequenceStarted) {
qt_cancelIo(handle, &overlapped);
dataReadNotifier->waitForNotified(-1, &overlapped);
if (qt_cancelIo(handle, &overlapped))
dataReadNotifier->waitForNotified(-1, &overlapped);
else
qErrnoWarning("QWindowsPipeReader: qt_cancelIo on handle %x failed.", handle);
}
}