Move the QProcessPrivate Windows objects into QProcessPrivate::Channel

Similar to the previous commit, this simplifies the code.

Change-Id: Ia02b9b5174b4bc6fd04ec2534231b7db5fc914fa
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
This commit is contained in:
Thiago Macieira 2014-06-05 15:05:56 -07:00 committed by The Qt Project
parent 29f92d112a
commit 15a0a6e8c5
3 changed files with 56 additions and 67 deletions

View File

@ -819,9 +819,6 @@ QProcessPrivate::QProcessPrivate()
emittedBytesWritten = false; emittedBytesWritten = false;
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
notifier = 0; notifier = 0;
stdoutReader = 0;
stderrReader = 0;
pipeWriter = 0;
processFinishedNotifier = 0; processFinishedNotifier = 0;
#endif // Q_OS_WIN #endif // Q_OS_WIN
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX

View File

@ -253,6 +253,9 @@ public:
{ {
pipe[0] = INVALID_Q_PIPE; pipe[0] = INVALID_Q_PIPE;
pipe[1] = INVALID_Q_PIPE; pipe[1] = INVALID_Q_PIPE;
#ifdef Q_OS_WIN
reader = 0;
#endif
} }
void clear(); void clear();
@ -282,6 +285,12 @@ public:
QString file; QString file;
QProcessPrivate *process; QProcessPrivate *process;
QSocketNotifier *notifier; QSocketNotifier *notifier;
#ifdef Q_OS_WIN
union {
QWindowsPipeReader *reader;
QWindowsPipeWriter *writer;
};
#endif
QRingBuffer buffer; QRingBuffer buffer;
Q_PIPE pipe[2]; Q_PIPE pipe[2];
@ -338,9 +347,6 @@ public:
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// the wonderful windows notifier // the wonderful windows notifier
QTimer *notifier; QTimer *notifier;
QWindowsPipeReader *stdoutReader;
QWindowsPipeReader *stderrReader;
QWindowsPipeWriter *pipeWriter;
QWinEventNotifier *processFinishedNotifier; QWinEventNotifier *processFinishedNotifier;
#endif #endif

View File

@ -180,34 +180,31 @@ bool QProcessPrivate::createChannel(Channel &channel)
&channel.pipe[0], 0, TRUE, DUPLICATE_SAME_ACCESS); &channel.pipe[0], 0, TRUE, DUPLICATE_SAME_ACCESS);
} }
} else { } else {
QWindowsPipeReader *pipeReader = 0;
if (&channel == &stdoutChannel) { if (&channel == &stdoutChannel) {
if (processChannelMode != QProcess::ForwardedChannels if (processChannelMode != QProcess::ForwardedChannels
&& processChannelMode != QProcess::ForwardedOutputChannel) { && processChannelMode != QProcess::ForwardedOutputChannel) {
if (!stdoutReader) { if (!stdoutChannel.reader) {
stdoutReader = new QWindowsPipeReader(q); stdoutChannel.reader = new QWindowsPipeReader(q);
q->connect(stdoutReader, SIGNAL(readyRead()), SLOT(_q_canReadStandardOutput())); q->connect(stdoutChannel.reader, SIGNAL(readyRead()), SLOT(_q_canReadStandardOutput()));
} }
pipeReader = stdoutReader;
} else { } else {
duplicateStdWriteChannel(channel.pipe, STD_OUTPUT_HANDLE); duplicateStdWriteChannel(channel.pipe, STD_OUTPUT_HANDLE);
} }
} else /* if (&channel == &stderrChannel) */ { } else /* if (&channel == &stderrChannel) */ {
if (processChannelMode != QProcess::ForwardedChannels if (processChannelMode != QProcess::ForwardedChannels
&& processChannelMode != QProcess::ForwardedErrorChannel) { && processChannelMode != QProcess::ForwardedErrorChannel) {
if (!stderrReader) { if (!stderrChannel.reader) {
stderrReader = new QWindowsPipeReader(q); stderrChannel.reader = new QWindowsPipeReader(q);
q->connect(stderrReader, SIGNAL(readyRead()), SLOT(_q_canReadStandardError())); q->connect(stderrChannel.reader, SIGNAL(readyRead()), SLOT(_q_canReadStandardError()));
} }
pipeReader = stderrReader;
} else { } else {
duplicateStdWriteChannel(channel.pipe, STD_ERROR_HANDLE); duplicateStdWriteChannel(channel.pipe, STD_ERROR_HANDLE);
} }
} }
if (pipeReader) { if (channel.reader) {
qt_create_pipe(channel.pipe, false); qt_create_pipe(channel.pipe, false);
pipeReader->setHandle(channel.pipe[0]); channel.reader->setHandle(channel.pipe[0]);
pipeReader->startAsyncRead(); channel.reader->startAsyncRead();
} }
} }
@ -335,22 +332,12 @@ void QProcessPrivate::destroyPipe(Q_PIPE pipe[2])
void QProcessPrivate::destroyChannel(Channel *channel) void QProcessPrivate::destroyChannel(Channel *channel)
{ {
if (channel == &stdinChannel) { if (channel == &stdinChannel) {
if (pipeWriter) { delete stdinChannel.writer;
delete pipeWriter; stdinChannel.writer = 0;
pipeWriter = 0; } else if (channel->reader) {
} channel->reader->stop();
} else if (channel == &stdoutChannel) { channel->reader->deleteLater();
if (stdoutReader) { channel->reader = 0;
stdoutReader->stop();
stdoutReader->deleteLater();
stdoutReader = 0;
}
} else if (channel == &stderrChannel) {
if (stderrReader) {
stderrReader->stop();
stderrReader->deleteLater();
stderrReader = 0;
}
} }
destroyPipe(channel->pipe); destroyPipe(channel->pipe);
} }
@ -582,10 +569,10 @@ qint64 QProcessPrivate::bytesAvailableFromStdout() const
if (stdoutChannel.pipe[0] == INVALID_Q_PIPE) if (stdoutChannel.pipe[0] == INVALID_Q_PIPE)
return 0; return 0;
if (!stdoutReader) if (!stdoutChannel.reader)
return 0; return 0;
DWORD bytesAvail = stdoutReader->bytesAvailable(); DWORD bytesAvail = stdoutChannel.reader->bytesAvailable();
#if defined QPROCESS_DEBUG #if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::bytesAvailableFromStdout() == %d", bytesAvail); qDebug("QProcessPrivate::bytesAvailableFromStdout() == %d", bytesAvail);
#endif #endif
@ -597,10 +584,10 @@ qint64 QProcessPrivate::bytesAvailableFromStderr() const
if (stderrChannel.pipe[0] == INVALID_Q_PIPE) if (stderrChannel.pipe[0] == INVALID_Q_PIPE)
return 0; return 0;
if (!stderrReader) if (!stderrChannel.reader)
return 0; return 0;
DWORD bytesAvail = stderrReader->bytesAvailable(); DWORD bytesAvail = stderrChannel.reader->bytesAvailable();
#if defined QPROCESS_DEBUG #if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::bytesAvailableFromStderr() == %d", bytesAvail); qDebug("QProcessPrivate::bytesAvailableFromStderr() == %d", bytesAvail);
#endif #endif
@ -609,12 +596,12 @@ qint64 QProcessPrivate::bytesAvailableFromStderr() const
qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen) qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen)
{ {
return stdoutReader ? stdoutReader->read(data, maxlen) : 0; return stdoutChannel.reader ? stdoutChannel.reader->read(data, maxlen) : 0;
} }
qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen) qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen)
{ {
return stderrReader ? stderrReader->read(data, maxlen) : 0; return stderrChannel.reader ? stderrChannel.reader->read(data, maxlen) : 0;
} }
@ -659,20 +646,20 @@ bool QProcessPrivate::waitForStarted(int)
bool QProcessPrivate::drainOutputPipes() bool QProcessPrivate::drainOutputPipes()
{ {
if (!stdoutReader && !stderrReader) if (!stdoutChannel.reader && !stderrChannel.reader)
return false; return false;
bool someReadyReadEmitted = false; bool someReadyReadEmitted = false;
forever { forever {
bool readyReadEmitted = false; bool readyReadEmitted = false;
bool readOperationActive = false; bool readOperationActive = false;
if (stdoutReader) { if (stdoutChannel.reader) {
readyReadEmitted |= stdoutReader->waitForReadyRead(0); readyReadEmitted |= stdoutChannel.reader->waitForReadyRead(0);
readOperationActive = stdoutReader && stdoutReader->isReadOperationActive(); readOperationActive = stdoutChannel.reader && stdoutChannel.reader->isReadOperationActive();
} }
if (stderrReader) { if (stderrChannel.reader) {
readyReadEmitted |= stderrReader->waitForReadyRead(0); readyReadEmitted |= stderrChannel.reader->waitForReadyRead(0);
readOperationActive |= stderrReader && stderrReader->isReadOperationActive(); readOperationActive |= stderrChannel.reader && stderrChannel.reader->isReadOperationActive();
} }
someReadyReadEmitted |= readyReadEmitted; someReadyReadEmitted |= readyReadEmitted;
if (!readOperationActive || !readyReadEmitted) if (!readOperationActive || !readyReadEmitted)
@ -692,11 +679,11 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
forever { forever {
if (!stdinChannel.buffer.isEmpty() && !_q_canWrite()) if (!stdinChannel.buffer.isEmpty() && !_q_canWrite())
return false; return false;
if (pipeWriter && pipeWriter->waitForWrite(0)) if (stdinChannel.writer && stdinChannel.writer->waitForWrite(0))
timer.resetIncrements(); timer.resetIncrements();
if ((stdoutReader && stdoutReader->waitForReadyRead(0)) if ((stdoutChannel.reader && stdoutChannel.reader->waitForReadyRead(0))
|| (stderrReader && stderrReader->waitForReadyRead(0))) || (stderrChannel.reader && stderrChannel.reader->waitForReadyRead(0)))
return true; return true;
if (!pid) if (!pid)
@ -726,8 +713,8 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
forever { forever {
// Check if we have any data pending: the pipe writer has // Check if we have any data pending: the pipe writer has
// bytes waiting to written, or it has written data since the // bytes waiting to written, or it has written data since the
// last time we called pipeWriter->waitForWrite(). // last time we called stdinChannel.writer->waitForWrite().
bool pendingDataInPipe = pipeWriter && (pipeWriter->bytesToWrite() || pipeWriter->hadWritten()); bool pendingDataInPipe = stdinChannel.writer && (stdinChannel.writer->bytesToWrite() || stdinChannel.writer->hadWritten());
// If we don't have pending data, and our write buffer is // If we don't have pending data, and our write buffer is
// empty, we fail. // empty, we fail.
@ -746,10 +733,10 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
// written. This will succeed if either the pipe writer has // written. This will succeed if either the pipe writer has
// already written the data, or if it manages to write data // already written the data, or if it manages to write data
// within the given timeout. If the write buffer was non-empty // within the given timeout. If the write buffer was non-empty
// and the pipeWriter is now dead, that means _q_canWrite() // and the stdinChannel.writer is now dead, that means _q_canWrite()
// destroyed the writer after it successfully wrote the last // destroyed the writer after it successfully wrote the last
// batch. // batch.
if (!pipeWriter || pipeWriter->waitForWrite(0)) if (!stdinChannel.writer || stdinChannel.writer->waitForWrite(0))
return true; return true;
// If we wouldn't write anything, check if we can read stdout. // If we wouldn't write anything, check if we can read stdout.
@ -797,11 +784,11 @@ bool QProcessPrivate::waitForFinished(int msecs)
forever { forever {
if (!stdinChannel.buffer.isEmpty() && !_q_canWrite()) if (!stdinChannel.buffer.isEmpty() && !_q_canWrite())
return false; return false;
if (pipeWriter && pipeWriter->waitForWrite(0)) if (stdinChannel.writer && stdinChannel.writer->waitForWrite(0))
timer.resetIncrements(); timer.resetIncrements();
if (stdoutReader && stdoutReader->waitForReadyRead(0)) if (stdoutChannel.reader && stdoutChannel.reader->waitForReadyRead(0))
timer.resetIncrements(); timer.resetIncrements();
if (stderrReader && stderrReader->waitForReadyRead(0)) if (stderrChannel.reader && stderrChannel.reader->waitForReadyRead(0))
timer.resetIncrements(); timer.resetIncrements();
if (!pid) { if (!pid) {
@ -837,33 +824,32 @@ void QProcessPrivate::findExitCode()
void QProcessPrivate::flushPipeWriter() void QProcessPrivate::flushPipeWriter()
{ {
if (pipeWriter && pipeWriter->bytesToWrite() > 0) { if (stdinChannel.writer && stdinChannel.writer->bytesToWrite() > 0)
pipeWriter->waitForWrite(ULONG_MAX); stdinChannel.writer->waitForWrite(ULONG_MAX);
}
} }
qint64 QProcessPrivate::pipeWriterBytesToWrite() const qint64 QProcessPrivate::pipeWriterBytesToWrite() const
{ {
return pipeWriter ? pipeWriter->bytesToWrite() : qint64(0); return stdinChannel.writer ? stdinChannel.writer->bytesToWrite() : qint64(0);
} }
qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
{ {
Q_Q(QProcess); Q_Q(QProcess);
if (!pipeWriter) { if (!stdinChannel.writer) {
pipeWriter = new QWindowsPipeWriter(stdinChannel.pipe[1], q); stdinChannel.writer = new QWindowsPipeWriter(stdinChannel.pipe[1], q);
pipeWriter->start(); stdinChannel.writer->start();
} }
return pipeWriter->write(data, maxlen); return stdinChannel.writer->write(data, maxlen);
} }
bool QProcessPrivate::waitForWrite(int msecs) bool QProcessPrivate::waitForWrite(int msecs)
{ {
Q_Q(QProcess); Q_Q(QProcess);
if (!pipeWriter || pipeWriter->waitForWrite(msecs)) if (!stdinChannel.writer || stdinChannel.writer->waitForWrite(msecs))
return true; return true;
processError = QProcess::Timedout; processError = QProcess::Timedout;
@ -875,7 +861,7 @@ void QProcessPrivate::_q_notified()
{ {
notifier->stop(); notifier->stop();
if (!stdinChannel.buffer.isEmpty() && (!pipeWriter || pipeWriter->waitForWrite(0))) if (!stdinChannel.buffer.isEmpty() && (!stdinChannel.writer || stdinChannel.writer->waitForWrite(0)))
_q_canWrite(); _q_canWrite();
if (processState != QProcess::NotRunning) if (processState != QProcess::NotRunning)