Skip to content

Commit

Permalink
Omit waitForBytesWritten() on client processes
Browse files Browse the repository at this point in the history
  • Loading branch information
hluk committed Jan 18, 2017
1 parent dec3338 commit a1c61b6
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 28 deletions.
54 changes: 26 additions & 28 deletions src/common/action.cpp
Expand Up @@ -32,8 +32,6 @@

namespace {

const int bufferSize = 4096;

void startProcess(QProcess *process, const QStringList &args)
{
QString executable = args.value(0);
Expand All @@ -45,27 +43,6 @@ void startProcess(QProcess *process, const QStringList &args)
process->start(executable, args.mid(1), QIODevice::ReadWrite);
}

void startWritingInput(const QByteArray input, QPointer<QProcess> p)
{
if (!p)
return;

if (!input.isEmpty()) {
// Write input in batches, otherwise on Windows with Qt 5
// the application can be blocked when writing huge amount of data.
for (int pos = 0; pos < input.size(); pos += bufferSize) {
p->write(input.mid(pos, bufferSize));
do {
QCoreApplication::processEvents();
if (!p || p->state() == QProcess::NotRunning)
return;
} while ( p->waitForBytesWritten(0) );
}
}

p->closeWriteChannel();
}

template <typename Entry, typename Container>
void appendAndClearNonEmpty(Entry &entry, Container &containter)
{
Expand Down Expand Up @@ -302,6 +279,8 @@ void Action::start()
// Writing directly to stdin of a process on Windows can hang the app.
connect( m_processes.first(), SIGNAL(started()),
this, SLOT(writeInput()), Qt::QueuedConnection );
connect( m_processes.first(), SIGNAL(bytesWritten(qint64)),
this, SLOT(onBytesWritten()), Qt::QueuedConnection );

if (m_outputFormat.isEmpty())
m_processes.last()->closeReadChannel(QProcess::StandardOutput);
Expand All @@ -317,8 +296,14 @@ bool Action::waitForStarted(int msecs)

bool Action::waitForFinished(int msecs)
{
QCoreApplication::processEvents();
return m_processes.isEmpty() || m_processes.last()->waitForFinished(msecs);
for ( int waitMsec = 0;
waitMsec < msecs && !m_processes.isEmpty() && !m_processes.last()->waitForFinished(100);
waitMsec += 100 )
{
QCoreApplication::processEvents();
}

return !isRunning();
}

bool Action::isRunning() const
Expand Down Expand Up @@ -437,8 +422,21 @@ void Action::actionErrorOutput()

void Action::writeInput()
{
if (m_processes.value(0) == sender())
startWritingInput(m_input, m_processes.value(0));
if (m_processes.isEmpty())
return;

QProcess *p = m_processes.first();

if (m_input.isEmpty())
p->closeWriteChannel();
else
p->write(m_input);
}

void Action::onBytesWritten()
{
if ( !m_processes.isEmpty() )
m_processes.first()->closeWriteChannel();
}

bool Action::hasTextOutput() const
Expand All @@ -456,7 +454,7 @@ void Action::terminate()
p->terminate();

// if process still running: kill it
if ( !m_processes.last()->waitForFinished(5000) )
if ( !waitForFinished(5000) )
m_processes.last()->kill();
}

Expand Down
1 change: 1 addition & 0 deletions src/common/action.h
Expand Up @@ -135,6 +135,7 @@ private slots:
void actionOutput();
void actionErrorOutput();
void writeInput();
void onBytesWritten();

private:
static QMutex actionsLock;
Expand Down

0 comments on commit a1c61b6

Please sign in to comment.