From 6bd61513290ef23783220b0e7507c4f03d5114e7 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Sun, 7 Mar 2021 14:44:23 +0200 Subject: [PATCH] QProcess/Win: implement async closing of write channel Instead of blocking in QProcessPrivate::closeWriteChannel(), we can handle a pending close in _q_canWrite() slot when there is no more data to write. Change-Id: I2a30789b6099a2ec075292348ebe33a11341bca3 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qprocess.cpp | 14 ++++++++------ src/corelib/io/qprocess_p.h | 1 - src/corelib/io/qprocess_win.cpp | 6 ------ 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index f03fc067cf..745c88e726 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1097,8 +1097,13 @@ bool QProcessPrivate::_q_canReadStandardError() bool QProcessPrivate::_q_canWrite() { if (writeBuffer.isEmpty()) { +#ifdef Q_OS_WIN + if (stdinChannel.closed && pipeWriterBytesToWrite() == 0) + closeWriteChannel(); +#else if (stdinChannel.notifier) stdinChannel.notifier->setEnabled(false); +#endif #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::canWrite(), not writing anything (empty write buffer)."); #endif @@ -1107,10 +1112,12 @@ bool QProcessPrivate::_q_canWrite() const bool writeSucceeded = writeToStdin(); +#ifdef Q_OS_UNIX if (writeBuffer.isEmpty() && stdinChannel.closed) closeWriteChannel(); else if (stdinChannel.notifier) stdinChannel.notifier->setEnabled(!writeBuffer.isEmpty()); +#endif return writeSucceeded; } @@ -1211,11 +1218,6 @@ void QProcessPrivate::closeWriteChannel() qDebug("QProcessPrivate::closeWriteChannel()"); #endif -#ifdef Q_OS_WIN - // ### Find a better fix, feeding the process little by little - // instead. - flushPipeWriter(); -#endif closeChannel(&stdinChannel); } @@ -1373,7 +1375,7 @@ void QProcess::closeWriteChannel() { Q_D(QProcess); d->stdinChannel.closed = true; // closing - if (d->writeBuffer.isEmpty()) + if (bytesToWrite() == 0) d->closeWriteChannel(); } diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 7b58b32369..73db9423e6 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -365,7 +365,6 @@ public: STARTUPINFOW createStartupInfo(); bool callCreateProcess(QProcess::CreateProcessArguments *cpargs); bool drainOutputPipes(); - void flushPipeWriter(); qint64 pipeWriterBytesToWrite() const; #endif diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 0088284d2d..3bdf070be4 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -796,12 +796,6 @@ void QProcessPrivate::findExitCode() } } -void QProcessPrivate::flushPipeWriter() -{ - if (stdinChannel.writer && stdinChannel.writer->bytesToWrite() > 0) - stdinChannel.writer->waitForWrite(ULONG_MAX); -} - qint64 QProcessPrivate::pipeWriterBytesToWrite() const { return stdinChannel.writer ? stdinChannel.writer->bytesToWrite() : qint64(0);