void MainWindow::requestRun(void)
{
if (proc)
return;
connect(proc, SIGNAL(finished(int)), this, SLOT(processFinished()));
connect(proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStdout()));
connect(proc, SIGNAL(readyReadStandardError()), this, SLOT(readyReadStderr()));
ui->pushButtonRun->setEnabled(false);
proc->setWorkingDirectory(workdir.absolutePath());
if (ui->checkBoxMergeOutputs->isChecked())
proc
->setProcessChannelMode
(QProcess::MergedChannels);
proc->start(ui->comboCmdLine->currentText());
if (!proc->waitForStarted(-1))
{
ui->pushButtonRun->setEnabled(true);
QMessageBox::critical(this,
"error",
"error running command");
proc->deleteLater();
proc = 0;
return;
}
if (proc)
{
ui->plainTextEditStdout->clear();
proc->write(ui->plainTextEditStdin->toPlainText().toAscii().constData());
/*! \warning it is possible that the processFinished()
* slot gets invoked prior to returning from
* the QProcess::waitForBytesWritten(-1) call
* below; as processFinished() deletes the 'proc'
* variable (and resets it to a null pointer),
* the 'proc' pointer below must be checked if
* usable */
/*! \todo strange... this below - if toggled between
* 'if (1) ...' / 'if (0) ...'
* causes some thread lockup in the qt code... strange thing
* is, on three different machines it behaves in three
* different ways; summarized:
*
* if (0) proc->waitForBytesWritten(-1);
*
* - on a core2 quad machine - does not hang
* - on a core2 duo machine - does not hang
* - on a single core pentium4 - DOES hang
*
* if (1) proc->waitForBytesWritten(-1);
*
* - on a core2 quad machine - DOES hang
* - on a core2 duo machine - does not hang
* - on a single core pentium4 - does not hang
*
* test platforms:
* - core2 quad - os windows xp pro, tested with qt2009.05 and qt2010.02.1
* - core2 duo - os windows xp pro, qt2009.05
* - single core pentium4 - os windows xp home, qt2009.05
*
* when gdb is attached (via qt-creator) to the locked-up process,
* all threads seem to be waiting on events (via waitforsingleobject()),
* only one thread seems to have invoked sleepex(), but unluckily
* gdb seems unable to unwind back to the program to see the locations
* of the calls in the source code; i tried single stepping on the
* core2 quad machine, and it seems the lock-up occurs when in
* qprocess.cpp, around line 820 - in qprocessprivate::cleanup() - when
* calling 'destroyPipe(stdinChannel.pipe);' - but take this as only a
* very rought estimate, i may well be very wrong... i really did not get
* any far when trying to debug this...
*
* i guess this all is some inter-thread synchronization problem, on the
* core2 quad it seems easiest to hang the program - just paste some text
* in the left textedit pane, enter some command in the combobox - i tested with
* 'gcc' and hold down the 'enter' button so that gcc is continuously invoked;
* the program hangs almost immediately... on the core2 duo i did not manage to
* hang the program, and on the single core the program hangs when it doesn't
* on the core2 quad... go figure... */
if (1) proc->waitForBytesWritten(-1);
if (!proc)
{
}
else
{
proc->closeWriteChannel();
}
}
}
void MainWindow::processFinished(void)
{
ui->pushButtonRun->setEnabled(true);
while (!proc->atEnd())
{
//qDebug() << "waiting for end";
//Sleep(500);
}
ui->plainTextEditStderr->appendPlainText(proc->readAllStandardError());
ui->plainTextEditStdout->appendPlainText(proc->readAllStandardOutput());
proc->deleteLater();
proc->write(ui->plainTextEditStdin->toPlainText().toAscii().constData());
proc = 0;
}
void MainWindow::readyReadStdout(void)
{
ui->plainTextEditStdout->appendPlainText(proc->readAllStandardOutput());
}
void MainWindow::readyReadStderr(void)
{
ui->plainTextEditStderr->appendPlainText(proc->readAllStandardError());
}
Bookmarks