remove the "wonderful Windows notifier" from QProcess

Remove the 100 ms timer that was used to nudge QProcess to write data
to the child's stdin. Instead, react on the canWrite() signal of
QWindowsPipeWriter.
QProcess::writeData needs to call _q_canWrite via the event loop to
start the write operation. The socket notifier code was never in use on
Windows.

Task-number: QTBUG-45457
Change-Id: I99c956ba5f2169f80068eee206543ceb9788b2e0
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
This commit is contained in:
Joerg Bornemann 2015-04-09 11:24:15 +02:00
parent 95b481ea6d
commit 96cc8eec9b
6 changed files with 30 additions and 36 deletions

View File

@ -36,6 +36,9 @@
#include <qdebug.h>
#include <qdir.h>
#if defined(Q_OS_WIN)
#include <qtimer.h>
#endif
#if defined QPROCESS_DEBUG
#include <qstring.h>
#include <ctype.h>
@ -819,7 +822,7 @@ QProcessPrivate::QProcessPrivate()
emittedReadyRead = false;
emittedBytesWritten = false;
#ifdef Q_OS_WIN
notifier = 0;
stdinWriteTrigger = 0;
processFinishedNotifier = 0;
#endif // Q_OS_WIN
}
@ -848,6 +851,10 @@ void QProcessPrivate::cleanup()
delete pid;
pid = 0;
}
if (stdinWriteTrigger) {
delete stdinWriteTrigger;
stdinWriteTrigger = 0;
}
if (processFinishedNotifier) {
delete processFinishedNotifier;
processFinishedNotifier = 0;
@ -878,12 +885,6 @@ void QProcessPrivate::cleanup()
delete deathNotifier;
deathNotifier = 0;
}
#ifdef Q_OS_WIN
if (notifier) {
delete notifier;
notifier = 0;
}
#endif
closeChannel(&stdoutChannel);
closeChannel(&stderrChannel);
closeChannel(&stdinChannel);
@ -1953,10 +1954,24 @@ qint64 QProcess::writeData(const char *data, qint64 len)
return 0;
}
#if defined(Q_OS_WIN)
if (!d->stdinWriteTrigger) {
d->stdinWriteTrigger = new QTimer;
d->stdinWriteTrigger->setSingleShot(true);
QObjectPrivate::connect(d->stdinWriteTrigger, &QTimer::timeout,
d, &QProcessPrivate::_q_canWrite);
}
#endif
if (len == 1) {
d->stdinChannel.buffer.putChar(*data);
#ifdef Q_OS_WIN
if (!d->stdinWriteTrigger->isActive())
d->stdinWriteTrigger->start();
#else
if (d->stdinChannel.notifier)
d->stdinChannel.notifier->setEnabled(true);
#endif
#if defined QPROCESS_DEBUG
qDebug("QProcess::writeData(%p \"%s\", %lld) == 1 (written to buffer)",
data, qt_prettyDebug(data, len, 16).constData(), len);
@ -1966,8 +1981,13 @@ qint64 QProcess::writeData(const char *data, qint64 len)
char *dest = d->stdinChannel.buffer.reserve(len);
memcpy(dest, data, len);
#ifdef Q_OS_WIN
if (!d->stdinWriteTrigger->isActive())
d->stdinWriteTrigger->start();
#else
if (d->stdinChannel.notifier)
d->stdinChannel.notifier->setEnabled(true);
#endif
#if defined QPROCESS_DEBUG
qDebug("QProcess::writeData(%p \"%s\", %lld) == %lld (written to buffer)",
data, qt_prettyDebug(data, len, 16).constData(), len, len);

View File

@ -266,7 +266,6 @@ private:
Q_PRIVATE_SLOT(d_func(), bool _q_canWrite())
Q_PRIVATE_SLOT(d_func(), bool _q_startupNotification())
Q_PRIVATE_SLOT(d_func(), bool _q_processDied())
Q_PRIVATE_SLOT(d_func(), void _q_notified())
friend class QProcessManager;
};

View File

@ -303,7 +303,6 @@ public:
bool _q_canWrite();
bool _q_startupNotification();
bool _q_processDied();
void _q_notified();
QProcess::ProcessChannel processChannel;
QProcess::ProcessChannelMode processChannelMode;
@ -342,8 +341,7 @@ public:
int forkfd;
#ifdef Q_OS_WIN
// the wonderful windows notifier
QTimer *notifier;
QTimer *stdinWriteTrigger;
QWinEventNotifier *processFinishedNotifier;
#endif

View File

@ -1111,10 +1111,6 @@ bool QProcessPrivate::waitForDeadChild()
return true;
}
void QProcessPrivate::_q_notified()
{
}
#if defined(QPROCESS_USE_SPAWN)
bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid)
{

View File

@ -41,7 +41,6 @@
#include <qelapsedtimer.h>
#include <qfileinfo.h>
#include <qregexp.h>
#include <qtimer.h>
#include <qwineventnotifier.h>
#include <private/qthread_p.h>
#include <qdebug.h>
@ -58,8 +57,6 @@ QT_BEGIN_NAMESPACE
//#define QPROCESS_DEBUG
#define NOTIFYTIMEOUT 100
static void qt_create_pipe(Q_PIPE *pipe, bool isInputPipe)
{
// Anomymous pipes do not support asynchronous I/O. Thus we
@ -543,9 +540,6 @@ void QProcessPrivate::startProcess()
processFinishedNotifier = new QWinEventNotifier(pid->hProcess, q);
QObject::connect(processFinishedNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_processDied()));
processFinishedNotifier->setEnabled(true);
notifier = new QTimer(q);
QObject::connect(notifier, SIGNAL(timeout()), q, SLOT(_q_notified()));
notifier->start(NOTIFYTIMEOUT);
}
_q_startupNotification();
@ -810,6 +804,8 @@ qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
if (!stdinChannel.writer) {
stdinChannel.writer = new QWindowsPipeWriter(stdinChannel.pipe[1], q);
QObjectPrivate::connect(stdinChannel.writer, &QWindowsPipeWriter::canWrite,
this, &QProcessPrivate::_q_canWrite);
stdinChannel.writer->start();
}
@ -828,17 +824,6 @@ bool QProcessPrivate::waitForWrite(int msecs)
return false;
}
void QProcessPrivate::_q_notified()
{
notifier->stop();
if (!stdinChannel.buffer.isEmpty() && (!stdinChannel.writer || stdinChannel.writer->waitForWrite(0)))
_q_canWrite();
if (processState != QProcess::NotRunning)
notifier->start(NOTIFYTIMEOUT);
}
bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDir, qint64 *pid)
{
QString args = qt_create_commandline(program, arguments);

View File

@ -288,10 +288,6 @@ bool QProcessPrivate::waitForWrite(int msecs)
return false;
}
void QProcessPrivate::_q_notified()
{
}
bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDir, qint64 *pid)
{
Q_UNUSED(workingDir);