Quantcast
Channel: Jobs
Viewing all articles
Browse latest Browse all 18427

QProcess killed with SIGPIPE

$
0
0
I am trying to make an application that starts a subprocess, reads raw video frames from its standard output, and processes them. However, after some frames, my subprocess gets killed with SIGPIPE for no obvious reason. Here is a minimal non-working example: app.cpp #include <QCoreApplication> #include <QProcess> #include <QDebug>   class MyApp : public QObject { Q_OBJECT   private:   static const quint64 frameLength = 614400;   QProcess process;   char* buffer;   signals:   void wantNewFrame(); // gets emitted when a new frame is needed   void frameReady(); // gets emitted when a frame is ready for processing   public:   MyApp() {     // Start a trivial process that never runs out of data.     process.start("cat /dev/zero");     buffer = new char[frameLength];     // Connect the signals - note that the application is single threaded     // so queued connections are used to avoid infinite recursion.     connect(this, SIGNAL(wantNewFrame()), SLOT(readFrame()), Qt::QueuedConnection);     connect(this, SIGNAL(frameReady()), SLOT(frameHandler()), Qt::QueuedConnection);     // Initiate the reading of the first frame.     emit wantNewFrame();   }     ~MyApp() { delete[] buffer; }   public slots:   // This method accumulates the data coming from the QProcess' standard   // output until there is enough to form a frame.   void readFrame() {     qint64 bytesNeeded = frameLength;     qint64 bytesRead = 0;     char* ptr = buffer;     while (bytesNeeded > 0) {       process.waitForReadyRead();       bytesRead = process.read(ptr, bytesNeeded);       if (bytesRead == -1) {         qDebug() << "process state" << process.state();         qDebug() << "process error" << process.error();         qDebug() << "QIODevice error" << process.errorString();         QCoreApplication::quit();         return;       }       ptr += bytesRead;       bytesNeeded -= bytesRead;     }     emit frameReady(); // will eventually invoke frameHandler()   }     // A trivial data processor - it only counts frames.   void frameHandler() {     static qint64 frameno = 0;     qDebug() << "frame" << frameno++;     emit wantNewFrame(); // will eventually invoke readFrame()   } };     int main(int argc, char** argv) {   QCoreApplication coreapp(argc, argv);   MyApp a;   return coreapp.exec(); }   #include "moc_app.cpp" The results are not what one would expect: $ ./app frame 0 ... frame 249 process state 0 process error 1 QIODevice error "Process crashed" The number of frames read varies: I’ve seen anything from about ten to a few thousand, but eventually, the subprocess gets killed with SIGPIPE. This obviously means that the parent had closed the pipe on it. But why? And where? Due to the randomness observed, I would say that I am almost certainly racing against something, but—against what? Note that in this particular simplified case, there would actually be no need to use the signal/slot mechanism to implement the reading/processing loop; I retained the event driven approach because it features in my original application. Incidentally, I tried rewriting the above example without using signals and slots, but having a simple loop like this instead: forever {   readFrame();   processFrame(); } In this case, the program worked fine. So what is the problem with the original implementation? Am I misusing the signal/slot mechanism in any way? Qt 4.8.4, x86_64 quad, Gentoo Linux

Viewing all articles
Browse latest Browse all 18427

Trending Articles