Deadlock fix for the file cache.
authorJim Carroll <thecarrolls@jiminger.com>
Sat, 25 Jun 2011 00:35:56 +0000 (20:35 -0400)
committerJim Carroll <thecarrolls@jiminger.com>
Sat, 25 Jun 2011 03:06:12 +0000 (23:06 -0400)
xbmc/threads/Event.cpp
xbmc/threads/Event.h
xbmc/threads/test/TestEvent.cpp

index 7795aa8..03a693c 100644 (file)
@@ -116,4 +116,15 @@ namespace XbmcThreads
       (*iter)->removeGroup(this);
   }
 
+  CEvent* CEventGroup::anyEventsSignaled()
+  {
+    for (std::vector<CEvent*>::iterator iter = events.begin();
+         iter != events.end(); iter++)
+    {
+      CEvent* cur = *iter;
+      if (cur->signaled) return cur;
+    }
+    return NULL;
+  }
+
 }
index 82ac37b..40dbc76 100644 (file)
@@ -116,6 +116,7 @@ namespace XbmcThreads
     friend class ::CEvent;
 
     inline CEvent* prepReturn() { CEvent* ret = signaled; if (numWaits == 0) signaled = NULL; return ret; }
+    CEvent* anyEventsSignaled();
 
   public:
 
@@ -141,7 +142,14 @@ namespace XbmcThreads
      * signaled at which point a pointer to that CEvents will be 
      * returned.
      */
-    inline CEvent* wait() { CSingleLock lock(mutex); numWaits++; condVar.wait(mutex); numWaits--; return prepReturn(); }
+    inline CEvent* wait() 
+    { CSingleLock lock(mutex); 
+      numWaits++; 
+      signaled = anyEventsSignaled(); 
+      if (!signaled) condVar.wait(mutex); 
+      numWaits--; 
+      return prepReturn(); 
+    }
 
     /**
      * This will block until any one of the CEvents in the group are
@@ -149,6 +157,13 @@ namespace XbmcThreads
      * it will return a pointer to that CEvent, otherwise it will return
      * NULL.
      */
-    inline CEvent* wait(unsigned int milliseconds)  { CSingleLock lock(mutex); numWaits++; condVar.wait(mutex,milliseconds); numWaits--; return prepReturn(); }
+    inline CEvent* wait(unsigned int milliseconds)  
+    { CSingleLock lock(mutex);
+      numWaits++; 
+      signaled = anyEventsSignaled(); 
+      if(!signaled) condVar.wait(mutex,milliseconds); 
+      numWaits--; 
+      return prepReturn(); 
+    }
   };
 }
index 7f50ee1..e14b72e 100644 (file)
@@ -349,3 +349,36 @@ BOOST_AUTO_TEST_CASE(TestEventSimpleTimeoutCase)
   BOOST_CHECK(!event.WaitMSec(50));
 }
 
+BOOST_AUTO_TEST_CASE(TestEventGroupChildSet)
+{
+  CEvent event1(true);
+  CEvent event2;
+
+  event1.Set();
+  CEventGroup group(&event1,&event2,NULL);
+
+  bool result1 = false;
+  bool result2 = false;
+
+  waiter w1(event1,result1);
+  waiter w2(event2,result2);
+  group_wait w3(group);
+
+  boost::thread waitThread1(boost::ref(w1));
+  boost::thread waitThread2(boost::ref(w2));
+  boost::thread waitThread3(boost::ref(w3));
+
+  Sleep(10);
+
+  BOOST_CHECK(result1);
+  BOOST_CHECK(!result2);
+
+  BOOST_CHECK(!w3.waiting);
+  BOOST_CHECK(w3.result == &event1);
+
+  Sleep(10);
+
+  event2.Set();
+
+  Sleep(50);
+}