From 9c7cabb880954d97d68cdbf34abc567a7494c922 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Wed, 12 May 2021 19:25:15 +0300 Subject: QLocalSocket/Win: fix closed state detection in waitFor...() functions A delayed close should only be completed in the _q_bytesWritten() slot as a confirmation of a successful write operation on the socket. Otherwise, a failed write operation may cause the socket to be closed unexpectedly within the waitFor...() function, which may result in a malfunction. Change-Id: I14cff26734f64a89090b6b5c13037466a6400597 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipereader.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'src/corelib/io') diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp index d8e9834ea0..d1a1782529 100644 --- a/src/corelib/io/qwindowspipereader.cpp +++ b/src/corelib/io/qwindowspipereader.cpp @@ -58,7 +58,7 @@ QWindowsPipeReader::QWindowsPipeReader(QObject *parent) lastError(ERROR_SUCCESS), state(Stopped), readSequenceStarted(false), - pipeBroken(false), + pipeBroken(true), readyReadPending(false), winEventActPosted(false) { @@ -112,10 +112,6 @@ void QWindowsPipeReader::stop() void QWindowsPipeReader::drainAndStop() { cancelAsyncRead(Draining); - - // Note that signals are not emitted in the call below, as the caller - // is expected to do that synchronously. - consumePending(); } /*! @@ -123,10 +119,11 @@ void QWindowsPipeReader::drainAndStop() */ void QWindowsPipeReader::cancelAsyncRead(State newState) { + pipeBroken = true; if (state != Running) return; - QMutexLocker locker(&mutex); + mutex.lock(); state = newState; if (readSequenceStarted) { // This can legitimately fail due to the GetOverlappedResult() @@ -142,11 +139,17 @@ void QWindowsPipeReader::cancelAsyncRead(State newState) // Wait for callback to complete. do { - locker.unlock(); + mutex.unlock(); waitForNotification(); - locker.relock(); + mutex.lock(); } while (readSequenceStarted); } + mutex.unlock(); + + // Because pipeBroken was set earlier, finish reading to keep the class + // state consistent. Note that signals are not emitted in the call + // below, as the caller is expected to do that synchronously. + consumePending(); } /*! -- cgit v1.2.3