changeset 452:80f7539147a2

WaitEmpty
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 04 Jul 2013 11:48:02 +0200
parents 0e8bd937a0f3
children 30086c1aca30
files Core/MultiThreading/SharedMessageQueue.cpp Core/MultiThreading/SharedMessageQueue.h UnitTests/main.cpp
diffstat 3 files changed, 39 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/Core/MultiThreading/SharedMessageQueue.cpp	Thu Jul 04 09:53:15 2013 +0200
+++ b/Core/MultiThreading/SharedMessageQueue.cpp	Thu Jul 04 11:48:02 2013 +0200
@@ -89,7 +89,34 @@
 
     std::auto_ptr<IDynamicObject> message(queue_.front());
     queue_.pop_front();
+    emptied_.notify_all();
 
     return message.release();
   }
+
+
+
+  bool SharedMessageQueue::WaitEmpty(int32_t millisecondsTimeout)
+  {
+    boost::mutex::scoped_lock lock(mutex_);
+    
+    // Wait for the queue to become empty
+    if (!queue_.empty())
+    {
+      if (millisecondsTimeout == 0)
+      {
+        emptied_.wait(lock);
+      }
+      else
+      {
+        if (!emptied_.timed_wait
+            (lock, boost::posix_time::milliseconds(millisecondsTimeout)))
+        {
+          return false;
+        }
+      }
+    }
+
+    return true;
+  }
 }
--- a/Core/MultiThreading/SharedMessageQueue.h	Thu Jul 04 09:53:15 2013 +0200
+++ b/Core/MultiThreading/SharedMessageQueue.h	Thu Jul 04 11:48:02 2013 +0200
@@ -49,6 +49,7 @@
     Queue queue_;
     boost::mutex mutex_;
     boost::condition_variable elementAvailable_;
+    boost::condition_variable emptied_;
 
   public:
     SharedMessageQueue(unsigned int maxSize = 0);
@@ -60,5 +61,7 @@
 
     // The caller is responsible to delete the dequeud message!
     IDynamicObject* Dequeue(int32_t millisecondsTimeout);
+
+    bool WaitEmpty(int32_t millisecondsTimeout);
   };
 }
--- a/UnitTests/main.cpp	Thu Jul 04 09:53:15 2013 +0200
+++ b/UnitTests/main.cpp	Thu Jul 04 11:48:02 2013 +0200
@@ -419,18 +419,21 @@
 TEST(SharedMessageQueue, Basic)
 {
   SharedMessageQueue q;
+  ASSERT_TRUE(q.WaitEmpty(0));
   q.Enqueue(new DynamicInteger(10));
+  ASSERT_FALSE(q.WaitEmpty(1));
   q.Enqueue(new DynamicInteger(20));
   q.Enqueue(new DynamicInteger(30));
   q.Enqueue(new DynamicInteger(40));
 
   std::auto_ptr<DynamicInteger> i;
-  i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(10))); ASSERT_EQ(10, i->GetValue());
-  i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(10))); ASSERT_EQ(20, i->GetValue());
-  i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(10))); ASSERT_EQ(30, i->GetValue());
-  i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(10))); ASSERT_EQ(40, i->GetValue());
-  
-  ASSERT_EQ(NULL, q.Dequeue(10));
+  i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(10, i->GetValue());
+  i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(20, i->GetValue());
+  i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(30, i->GetValue());
+  ASSERT_FALSE(q.WaitEmpty(1));
+  i.reset(dynamic_cast<DynamicInteger*>(q.Dequeue(1))); ASSERT_EQ(40, i->GetValue());
+  ASSERT_TRUE(q.WaitEmpty(0));
+  ASSERT_EQ(NULL, q.Dequeue(1));
 }