[Kst] kdeextragear-2/kst/kst

Barth Netterfield netterfield at astro.utoronto.ca
Thu Aug 26 05:00:03 CEST 2004


CVS commit by netterfield: 

Jeff Klien found a critical real time bug (race condition) in which
a plot repaint could (and would) happen after the X vector had been
but before the Y vector had been updated, leading to an inconsistent plot.

This fixes this, by (and at the cost of) not letting the update thread
do any processing until the UI thread is finished painting.  This does not
influence the responsiveness of the UI, and has little or no performance
penalty for a single CPU sustem, but does slow things down on the
multi-cpu system.  There are few, if any, other options, however.


  M +17 -16    updatethread.cpp   1.26


--- kdeextragear-2/kst/kst/updatethread.cpp  #1.25:1.26
@@ -80,30 +80,31 @@ void UpdateThread::run() {
       kdDebug() << "Update resulted in: TRUE!" << endl;
 #endif
-      // Wait for UI thread to finish events.  This is a
-      // a hack to keep update thread from getting ahead of the UI thread,
-      // which would block UI thread by filling it with un-processable requests.
-      bool do_wait = false;
+      if (gotData) {
+        QApplication::postEvent(_doc, new ThreadEvent(ThreadEvent::UpdateDataDialogs));
+        // this event also triggers an implicit repaint
+      } else {
+        QApplication::postEvent(_doc, new ThreadEvent(ThreadEvent::Repaint));
+      }
+      // Wait for UI thread to finish events.  If we don't wait
+      // 1: the UI thread could get flooded with events
+      // 2: the update thread could change vectors during a paint, causing
+      //    inconsistent curves to be plotted ie, the X vector updated and the Y vector
+      //    not yet updated...
+
       // Race warning: Syncronization of updating() is not assured, but updating() will always
       // return a valid answer which was true 'close' to when we asked.  This will safely keep
-      // the update thread from over filling the UI thread.
+      // the update thread from over filling the UI thread.  The usleeps will hopefully give the UI
+      // thread a chance to set itself...
+      usleep(1000); // 1 ms on 2.6 kernel.  NOTE: on 2.4 kernel, the minimum usleep is 10ms,
+                    // So this will run more coarsly on 2.4.  Should be OK though.
       while (_doc->updating()) {  // wait for the UI to finish old events
-        do_wait = true;
         usleep(1000); // 1 ms on 2.6 kernel.  NOTE: on 2.4 kernel, the minimum usleep is 10ms,
                       // So this will run more coarsly on 2.4.  Should be OK though.
       }
-      if (do_wait) { // one extra usleep in case something was pending.
         usleep(1000);
-      }
       while (_doc->updating()) { // check again... not strictly needed given implicit repaint below,
                                  // but it should just return false, so no harm done.
         usleep(1000);
       }
-
-      if (gotData) {
-        QApplication::postEvent(_doc, new ThreadEvent(ThreadEvent::UpdateDataDialogs));
-        // this event also triggers an implicit repaint
-      } else {
-        QApplication::postEvent(_doc, new ThreadEvent(ThreadEvent::Repaint));
-      }
     }
   }





More information about the Kst mailing list