Parcourir la source

Fixed crash in case # of "sendEvent" calls exceeds thread pool size.

The ctkEALinkedQueue class deleted the wrong node element. Further,
clean up code for memory handling of ctkEARunnable objects.
Sascha Zelzer il y a 13 ans
Parent
commit
22d496e556

+ 3 - 1
Plugins/org.commontk.eventadmin/dispatch/ctkEALinkedQueue.cpp

@@ -87,6 +87,7 @@ ctkEARunnable* ctkEALinkedQueue::take()
       catch(const ctkEAInterruptedException& ex)
       {
         --waitingForTake_;
+        if (x && x->autoDelete() && !--x->ref) delete x;
         putLockWait_.wakeOne();
         throw ex;
       }
@@ -144,6 +145,7 @@ ctkEARunnable* ctkEALinkedQueue::poll(long msecs)
     catch(const ctkEAInterruptedException& ex)
     {
       --waitingForTake_;
+      if (x && x->autoDelete() && !--x->ref) delete x;
       putLockWait_.wakeOne();
       throw ex;
     }
@@ -176,8 +178,8 @@ ctkEARunnable* ctkEALinkedQueue::extract()
     {
       x = first->value;
       first->value = 0;
+      delete head_;
       head_ = first;
-      delete first;
     }
     return x;
   }

+ 1 - 1
Plugins/org.commontk.eventadmin/dispatch/ctkEALinkedQueue_p.h

@@ -48,7 +48,7 @@ struct ctkEALinkedNode
   {
     if (value && value->autoDelete())
     {
-      if (!--value->ref) delete value;
+      !--value->ref;
     }
   }
 

+ 15 - 4
Plugins/org.commontk.eventadmin/dispatch/ctkEAPooledExecutor.cpp

@@ -379,7 +379,9 @@ ctkEAPooledExecutor::DiscardOldestWhenBlocked::DiscardOldestWhenBlocked(ctkEAPoo
 
 bool ctkEAPooledExecutor::DiscardOldestWhenBlocked::blockedAction(ctkEARunnable* command)
 {
-  pe->handOff_->poll(0);
+  ctkEARunnable* tmp = pe->handOff_->poll(0);
+  if (tmp && tmp->autoDelete() && !--tmp->ref) delete tmp;
+
   if (!pe->handOff_->offer(command, 0))
   {
     const bool autoDelete = command->autoDelete();
@@ -393,7 +395,7 @@ void ctkEAPooledExecutor::addThread(ctkEARunnable* command)
 {
   Worker* worker = new Worker(this, command);
   ++worker->ref;
- ctkEAInterruptibleThread* thread = getThreadFactory()->newThread(worker);
+  ctkEAInterruptibleThread* thread = getThreadFactory()->newThread(worker);
   threads_.insert(worker, thread);
   ++poolSize_;
 
@@ -426,8 +428,17 @@ void ctkEAPooledExecutor::workerDone(Worker* w)
     try
     {
       ctkEARunnable* r = handOff_->poll(0);
-      if (r != 0 && !shutdown_) // just consume task if shut down
-        addThread(r);
+      if (r != 0)
+      {
+        if(shutdown_) // just consume task if shut down
+        {
+          if (r->autoDelete() && !r->ref) delete r;
+        }
+        else
+        {
+          addThread(r);
+        }
+      }
     }
     catch(const ctkEAInterruptedException& ) {
       return;