Quellcode durchsuchen

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 vor 13 Jahren
Ursprung
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;