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 <oswald.buddenhagen@gmx.de>
This commit is contained in:
Alex Trotsenko 2021-03-07 14:44:23 +02:00
parent 5fa8f5df7b
commit 6bd6151329
3 changed files with 8 additions and 13 deletions

View File

@ -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();
}

View File

@ -365,7 +365,6 @@ public:
STARTUPINFOW createStartupInfo();
bool callCreateProcess(QProcess::CreateProcessArguments *cpargs);
bool drainOutputPipes();
void flushPipeWriter();
qint64 pipeWriterBytesToWrite() const;
#endif

View File

@ -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);