[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    kdenonbeta/frontman/plugins/basicprocess
From:       Ravikiran Rajagopal <ravi () kde ! org>
Date:       2004-01-26 0:39:15
Message-ID: 20040126003915.BE5D38FEA () office ! kde ! org
[Download RAW message or body]

CVS commit by ravi: 

Eliminate some obscure race conditions; the solution is rather inefficient but \
simple, and I will stick with this until it is shown that the performance hit is \
unacceptable.


  M +50 -5     fmbasicprocess.cpp   1.2
  M +5 -1      fmbasicprocess.h   1.2


--- kdenonbeta/frontman/plugins/basicprocess/fmbasicprocess.cpp  #1.1:1.2
@@ -20,4 +20,5 @@
 #include "fmbasicprocess.moc"
 
+#include <kdebug.h>
 #include <kgenericfactory.h>
 #include <kprocio.h>
@@ -26,4 +27,5 @@
 
 #include <qstringlist.h>
+#include <qtimer.h>
 
 typedef KGenericFactory<FM::BasicProcess> FMBasicProcessFactory;
@@ -33,5 +35,6 @@ namespace FM
 {
   BasicProcess::BasicProcess( QObject *parent, const char *name, const QStringList & \
                )
-    : ProcessIface( parent, name ), mProcess( 0 ), mHostName( QString::null ), \
mCommandLine( QString::null ), mPriority( 0 ) +    : ProcessIface( parent, name ), \
mProcess( 0 ), mTimer( 0 ), +      mHostName( QString::null ), mCommandLine( \
QString::null ), mPriority( 0 )  {
   }
@@ -51,4 +54,9 @@ namespace FM
       mProcess = new KProcIO;
     mProcess->clearArguments();
+    if ( !mTimer )
+    {
+      mTimer = new QTimer( this );
+      connect( mTimer, SIGNAL( timeout() ), SLOT( checkForPartial() ) );
+    }
 
     if ( isRemote() )
@@ -69,4 +77,5 @@ namespace FM
     // Connect some signals.
     connect( mProcess, SIGNAL( readReady( KProcIO* ) ), SLOT( readOutput( KProcIO* ) \
) ); +    connect( mProcess, SIGNAL( receivedStdout( KProcess*, char*, int ) ), SLOT( \
partialTextAvailable() ) );  
     bool result = mProcess->start( KProcess::NotifyOnExit, true );
@@ -130,8 +139,44 @@ namespace FM
     // Assumption: proc == mProcess.
     QString output, total;
-    while ( proc->readln( output, false ) != -1 )
-      total += output;
+
+    // Read whole lines.
+    while ( proc->readln( output, true ) != -1 )
+      total += ( output+"\n" );
+
+    if ( !total.isEmpty() )
+    {
+      // Wait at least 100ms before we try to read partial lines.
+      // There's a problem here. If there is no partial line output right now, we \
check for it 100ms later. However, if there is +      // none 100ms later either but \
appears later than that, say 200ms from now, then we don't get it until we get a \
readReady() +      // signal from mProcess, which is emitted _after_ a new line is \
complete. For our case, this means that we might miss a prompt +      // that appears \
well after the last output from the previous command. The right way to fix it is to \
connect to +      // receivedStdout() signal in partialTextAvailable() and use a \
timer there, but it can be very inefficient. +      mTimer->stop();
+      mTimer->start( 100, true );
+      kdDebug() << total << endl;
     emit outputLines( this, total );
-    proc->ackRead();
+    }
+    //proc->ackRead();
+  }
+
+  void BasicProcess::checkForPartial()
+  {
+    QString output;
+    bool partial;
+    // We waited the requisite time but we did not get a complete line.
+    if ( mProcess->readln( output, true, &partial ) != -1 )
+    {
+      //kdDebug() << output << endl;
+      if ( partial )
+        emit partialLine( this, output );
+      else
+        emit outputLines( this, output );
+    }
+  }
+
+  void BasicProcess::partialTextAvailable()
+  {
+    if ( !mTimer->isActive() )
+      mTimer->start( 300, true );
   }
 }

--- kdenonbeta/frontman/plugins/basicprocess/fmbasicprocess.h  #1.1:1.2
@@ -25,4 +25,5 @@
 
 class KProcIO;
+class QTimer;
 
 namespace FM
@@ -47,9 +48,12 @@ namespace FM
     bool isRemote() const;
 
-  protected:
+  protected slots:
     void readOutput( KProcIO *proc );
+    void checkForPartial();
+    void partialTextAvailable();
 
   private:
     KProcIO *mProcess;
+    QTimer *mTimer;
     QString mHostName;
     QString mCommandLine;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic