[Kst] extragear/graphics/kst/src/libkstapp

George Staikos staikos at kde.org
Mon Jan 22 08:15:27 CET 2007


SVN commit 626107 by staikos:

Fix some races and crashes in multicore update.  Cannot reproduce any problems
right now.


 M  +44 -14    updatethread-multicore.cpp  
 M  +6 -0      updatethread-multicore.h  


--- trunk/extragear/graphics/kst/src/libkstapp/updatethread-multicore.cpp #626106:626107
@@ -41,6 +41,7 @@
   // Update variables
   _updateCounter = 0;
   _force = false;
+  _jobCount = 0;
 }
 
 
@@ -59,40 +60,44 @@
   protected:
     virtual void run() {
       for (KstObjectPtr o;;) {
+        UpdateThread *t = _t;
+        if (!t || t->finished()) {
+          break;
+        }
+
         if (!o) {
-          o = _t->dequeueUpdate();
+          o = t->dequeueUpdate();
         }
 
         if (o) {
+          t->jobIsRunning();
           o->writeLock();
-          KstObject::UpdateType rc = o->update(_t->_updateCounter);
+          KstObject::UpdateType rc = o->update(t->_updateCounter);
           o->unlock();
           if (rc == KstObject::UPDATE) {
-            _t->_updateResult = rc;
+            t->_updateResult = rc;
           }
+          t->jobIsDone();
         }
 
         o = 0L;
 
-        if (_t->finished()) {
+        if (t->finished()) {
           break;
         }
 
-        o = _t->dequeueUpdate();
+        o = t->dequeueUpdate();
 
         if (o) {
           continue;
         }
 
-        _t->_queueCondition.wait();
-
-        if (_t->finished()) {
-          break;
-        }
+        t->_queueCondition.wait();
       }
       // FIXME need to signify to the update thread that we're dead
     }
 
+    friend class UpdateThread;
     UpdateThread *_t;
 };
 
@@ -185,11 +190,11 @@
   }
 
   _done = true; // should be redundant
+  for (QValueList<UpdateJob*>::Iterator i = jobs.begin(); i != jobs.end(); ++i) {
+    (*i)->_t = 0L;
+  }
   _queueCondition.wakeAll();
   usleep(1000);
-  for (QValueList<UpdateJob*>::Iterator i = jobs.begin(); i != jobs.end(); ++i) {
-    delete *i;
-  }
   QApplication::postEvent(_doc, new ThreadEvent(ThreadEvent::Done));
 }
 
@@ -386,7 +391,9 @@
   KstObjectPtr rc;
   _updateQueueMutex.lock();
   if (_updateQueue.isEmpty()) {
-    _emptyQueueCondition.wakeAll();
+    if (!jobsAreRunning()) {
+      _emptyQueueCondition.wakeAll();
+    }
   } else {
     // We could make this smarter if we had isLocked()
     rc = _updateQueue.first();
@@ -397,6 +404,29 @@
 }
 
 
+bool UpdateThread::jobsAreRunning() const {
+  bool running;
+  _jobCountMutex.lock();
+  running = _jobCount > 0;
+  _jobCountMutex.unlock();
+  return running;
+}
+  
+
+void UpdateThread::jobIsRunning() {
+  _jobCountMutex.lock();
+  ++_jobCount;
+  _jobCountMutex.unlock();
+}
+
+
+void UpdateThread::jobIsDone() {
+  _jobCountMutex.lock();
+  --_jobCount;
+  _jobCountMutex.unlock();
+}
+
+
 void UpdateThread::enqueueUpdate(KstObject *obj) {
   _updateQueueMutex.lock();
   _updateQueue.append(obj);
--- trunk/extragear/graphics/kst/src/libkstapp/updatethread-multicore.h #626106:626107
@@ -56,6 +56,10 @@
     int _updateCounter;
     KstObject::UpdateType _updateResult;
 
+    void jobIsRunning();
+    void jobIsDone();
+    bool jobsAreRunning() const;
+
   private:
     bool _paused, _done;
     bool _force;
@@ -66,6 +70,8 @@
     QValueList<KstBaseCurve*> _updatedCurves; // HACK: temporary use in update reworking
     KstObjectList<KstObjectPtr> _updateQueue;
     QMutex _updateQueueMutex;
+    mutable QMutex _jobCountMutex;
+    int _jobCount;
 };
 
 


More information about the Kst mailing list