Removed all WaitForSingleObject and WaitForMultipleObjects calls and replaced them...
authorJim Carroll <thecarrolls@jiminger.com>
Mon, 20 Jun 2011 02:30:53 +0000 (22:30 -0400)
committerJim Carroll <thecarrolls@jiminger.com>
Thu, 23 Jun 2011 14:15:27 +0000 (10:15 -0400)
41 files changed:
lib/UnrarXLib/extract.cpp
lib/UnrarXLib/rdwrfn.cpp
lib/UnrarXLib/rdwrfn.hpp
lib/UnrarXLib/unpack.cpp
lib/UnrarXLib/unpack15.cpp
xbmc/ApplicationMessenger.cpp
xbmc/ApplicationMessenger.h
xbmc/cdrip/CDDAReader.cpp
xbmc/cdrip/CDDAReader.h
xbmc/cores/DllLoader/exports/emu_kernel32.cpp
xbmc/cores/DllLoader/exports/emu_kernel32.h
xbmc/cores/VideoRenderers/LinuxRendererGL.cpp
xbmc/cores/VideoRenderers/LinuxRendererGL.h
xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
xbmc/cores/VideoRenderers/LinuxRendererGLES.h
xbmc/cores/dvdplayer/DVDMessageQueue.cpp
xbmc/cores/dvdplayer/DVDMessageQueue.h
xbmc/filesystem/CacheStrategy.cpp
xbmc/filesystem/CacheStrategy.h
xbmc/filesystem/FileRar.cpp
xbmc/filesystem/FileRar.h
xbmc/filesystem/PluginDirectory.cpp
xbmc/filesystem/PluginDirectory.h
xbmc/interfaces/python/XBPython.cpp
xbmc/interfaces/python/XBPython.h
xbmc/interfaces/python/xbmcmodule/GUIPythonWindow.cpp
xbmc/interfaces/python/xbmcmodule/GUIPythonWindow.h
xbmc/interfaces/python/xbmcmodule/GUIPythonWindowXML.cpp
xbmc/interfaces/python/xbmcmodule/GUIPythonWindowXML.h
xbmc/linux/XSyncUtils.cpp
xbmc/linux/XSyncUtils.h
xbmc/music/LastFmManager.cpp
xbmc/music/LastFmManager.h
xbmc/network/libscrobbler/scrobbler.cpp
xbmc/network/libscrobbler/scrobbler.h
xbmc/pictures/GUIWindowSlideShow.cpp
xbmc/pictures/GUIWindowSlideShow.h
xbmc/threads/Event.cpp
xbmc/threads/Event.h
xbmc/threads/test/Makefile [new file with mode: 0644]
xbmc/threads/test/TestEvent.cpp [new file with mode: 0644]

index 17e5052..74a795b 100644 (file)
@@ -751,7 +751,7 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
       }
 
       if (DataIO.UnpackToMemorySize > -1)
-        if (WaitForSingleObject(DataIO.hQuit,1) == WAIT_OBJECT_0)
+        if (DataIO.hQuit->WaitMSec(1))
         {
           return false;
         }
@@ -841,14 +841,14 @@ void CmdExtract::UnstoreFile(ComprDataIO &DataIO,Int64 DestUnpSize)
   {
     while (1)
     {
-      if (WaitForSingleObject(DataIO.hQuit,1) == WAIT_OBJECT_0)
+      if (DataIO.hQuit->WaitMSec(1))
       {
         return;
       }
       int Code=DataIO.UnpRead(&Buffer[0],Buffer.Size());
       if (DataIO.UnpackToMemorySize > -1 && !DataIO.NextVolumeMissing)
       {
-        if (WaitForSingleObject(DataIO.hSeek,1) == WAIT_OBJECT_0)
+        if (DataIO.hSeek->WaitMSec(1))
           continue;
       }
       if (Code > 0)
@@ -861,14 +861,14 @@ void CmdExtract::UnstoreFile(ComprDataIO &DataIO,Int64 DestUnpSize)
       else 
       {
         if (DataIO.NextVolumeMissing)
-          SetEvent(DataIO.hSeekDone);
+          DataIO.hSeekDone->Set();
         else 
-        if (WaitForSingleObject(DataIO.hSeek,1) == WAIT_OBJECT_0)
+          if (DataIO.hSeek->WaitMSec(1))
            continue;
-        ResetEvent(DataIO.hBufferFilled);
-        SetEvent(DataIO.hBufferEmpty);
-        while (WaitForSingleObject(DataIO.hBufferFilled,1) != WAIT_OBJECT_0)
-          if (WaitForSingleObject(DataIO.hQuit,1) == WAIT_OBJECT_0)
+        DataIO.hBufferFilled->Reset();
+        DataIO.hBufferEmpty->Set();
+        while (DataIO.hBufferFilled->WaitMSec(1))
+          if (DataIO.hQuit->WaitMSec(1))
             return;
       }
     }
index dd87a07..6d1c055 100644 (file)
@@ -63,7 +63,7 @@ int ComprDataIO::UnpRead(byte *Addr,uint Count)
         return(-1);
       }
       if (UnpackToMemory)
-        if (WaitForSingleObject(hSeek,1) == WAIT_OBJECT_0) // we are seeking
+        if (hSeek->WaitMSec(1)) // we are seeking
         {
           if (m_iSeekTo > CurUnpStart+SrcArc->NewLhd.FullPackSize) // need to seek outside this block
           {
@@ -113,8 +113,8 @@ int ComprDataIO::UnpRead(byte *Addr,uint Count)
             CurUnpRead = CurUnpStart + iSeekTo - iStartOfFile;
             CurUnpWrite = SrcFile->Tell() - iStartOfFile + CurUnpStart;
             
-            ResetEvent(hSeek);
-            SetEvent(hSeekDone);
+            hSeek->Reset();
+            hSeekDone->Set();
           }
         }
       if (bRead)
@@ -210,13 +210,13 @@ void ComprDataIO::UnpWrite(byte *Addr,uint Count)
   {
     while(UnpackToMemorySize < (int)Count)
     {
-      SetEvent(hBufferEmpty);
-      while( WaitForSingleObject(hBufferFilled,1) != WAIT_OBJECT_0
-        if (WaitForSingleObject(hQuit,1) == WAIT_OBJECT_0)
+      hBufferEmpty->Set();
+      while( hBufferFilled->WaitMSec(1)
+        if (hQuit->WaitMSec(1))
           return;
     }
     
-    if (WaitForSingleObject(hSeek,1) != WAIT_OBJECT_0) // we are seeking
+    if (hSeek->WaitMSec(1)) // we are seeking
     {
       memcpy(UnpackToMemoryAddr,Addr,Count);
       UnpackToMemoryAddr+=Count;
index 95111ca..69d7f59 100644 (file)
@@ -5,6 +5,7 @@ class CmdAdd;
 class Unpack;
 
 #include "system.h"
+#include "threads/Event.h"
 
 class CGUIDialogProgress;
 
@@ -84,11 +85,11 @@ class ComprDataIO
     int UnpackToMemorySize;
     
     // added stuff
-    HANDLE hBufferFilled;
-    HANDLE hBufferEmpty;
-    HANDLE hSeek;
-    HANDLE hSeekDone;
-    HANDLE hQuit;
+    CEvent* hBufferFilled;
+    CEvent* hBufferEmpty;
+    CEvent* hSeek;
+    CEvent* hSeekDone;
+    CEvent* hQuit;
     CGUIDialogProgress* m_pDlgProgress;
     bool bQuit;
     Int64 m_iSeekTo;
index 1361128..113260b 100644 (file)
@@ -410,9 +410,9 @@ void Unpack::Unpack29(bool Solid)
 
   if (UnpIO->UnpackToMemorySize > -1)
   {
-    SetEvent(UnpIO->hBufferEmpty);
-    while (WaitForSingleObject(UnpIO->hBufferFilled,1) != WAIT_OBJECT_0)
-      if (WaitForSingleObject(UnpIO->hQuit,1) == WAIT_OBJECT_0)
+    UnpIO->hBufferEmpty->Set();
+    while (UnpIO->hBufferFilled->WaitMSec(1))
+      if (UnpIO->hQuit->WaitMSec(1))
         return;
   }
 }
index fa69b3e..e1b5f10 100644 (file)
@@ -67,7 +67,7 @@ void Unpack::Unpack15(bool Solid)
 
   while (DestUnpSize>=0)
   {
-    if (WaitForSingleObject(UnpIO->hQuit,1) == WAIT_OBJECT_0)
+    if (UnpIO->hQuit->WaitMSec(1))
       return;
 
     UnpPtr&=MAXWINMASK;
index bcf208e..a38d2c4 100644 (file)
@@ -103,7 +103,7 @@ void CApplicationMessenger::Cleanup()
     ThreadMessage* pMsg = m_vecMessages.front();
 
     if (pMsg->hWaitEvent)
-      SetEvent(pMsg->hWaitEvent);
+      pMsg->hWaitEvent->Set();
 
     delete pMsg;
     m_vecMessages.pop();
@@ -114,7 +114,7 @@ void CApplicationMessenger::Cleanup()
     ThreadMessage* pMsg = m_vecWindowMessages.front();
 
     if (pMsg->hWaitEvent)
-      SetEvent(pMsg->hWaitEvent);
+      pMsg->hWaitEvent->Set();
 
     delete pMsg;
     m_vecWindowMessages.pop();
@@ -128,7 +128,7 @@ void CApplicationMessenger::SendMessage(ThreadMessage& message, bool wait)
   { // check that we're not being called from our application thread, else we'll be waiting
     // forever!
     if (!g_application.IsCurrentThread())
-      message.hWaitEvent = CreateEvent(NULL, true, false, NULL);
+      message.hWaitEvent = new CEvent(true);
     else
     {
       //OutputDebugString("Attempting to wait on a SendMessage() from our application thread will cause lockup!\n");
@@ -144,7 +144,7 @@ void CApplicationMessenger::SendMessage(ThreadMessage& message, bool wait)
   {
     if (message.hWaitEvent)
     {
-      CloseHandle(message.hWaitEvent);
+      delete message.hWaitEvent;
       message.hWaitEvent = NULL;
     }
     return;
@@ -168,8 +168,8 @@ void CApplicationMessenger::SendMessage(ThreadMessage& message, bool wait)
   if (message.hWaitEvent)
   { // ensure the thread doesn't hold the graphics lock
     CSingleExit exit(g_graphicsContext);
-    WaitForSingleObject(message.hWaitEvent, INFINITE);
-    CloseHandle(message.hWaitEvent);
+    message.hWaitEvent->Wait();
+    delete message.hWaitEvent;
     message.hWaitEvent = NULL;
   }
 }
@@ -190,7 +190,7 @@ void CApplicationMessenger::ProcessMessages()
 
     ProcessMessage(pMsg);
     if (pMsg->hWaitEvent)
-      SetEvent(pMsg->hWaitEvent);
+      pMsg->hWaitEvent->Set();
     delete pMsg;
 
     lock.Enter();
@@ -733,7 +733,7 @@ void CApplicationMessenger::ProcessWindowMessages()
 
     ProcessMessage(pMsg);
     if (pMsg->hWaitEvent)
-      SetEvent(pMsg->hWaitEvent);
+      pMsg->hWaitEvent->Set();
     delete pMsg;
 
     lock.Enter();
index e7f2c47..184ed20 100644 (file)
@@ -25,6 +25,7 @@
 #include "utils/StdString.h"
 #include "guilib/Key.h"
 #include "threads/Thread.h"
+#include "threads/Event.h"
 
 #include <queue>
 
@@ -99,7 +100,7 @@ typedef struct
   DWORD dwParam2;
   CStdString strParam;
   std::vector<CStdString> params;
-  HANDLE hWaitEvent;
+  CEvent* hWaitEvent;
   LPVOID lpVoid;
 }
 ThreadMessage;
index 31346cd..95fcc2c 100644 (file)
@@ -35,9 +35,6 @@ CCDDAReader::CCDDAReader()
   m_sRipBuffer[1].pbtStream = NULL;
 
   m_iCurrentBuffer = 0;
-
-  m_hReadEvent = CreateEvent(NULL, false, false, NULL);
-  m_hDataReadyEvent = CreateEvent(NULL, false, false, NULL);
 }
 
 CCDDAReader::~CCDDAReader()
@@ -45,9 +42,6 @@ CCDDAReader::~CCDDAReader()
   m_bStop = true;
   StopThread();
 
-  CloseHandle(m_hReadEvent);
-  CloseHandle(m_hDataReadyEvent);
-
   if (m_sRipBuffer[0].pbtStream) delete []m_sRipBuffer[0].pbtStream;
   if (m_sRipBuffer[1].pbtStream) delete []m_sRipBuffer[1].pbtStream;
 }
@@ -117,19 +111,19 @@ void CCDDAReader::Process()
   m_iCurrentBuffer = 0;
 
   m_sRipBuffer[0].iRipError = ReadChunk();
-  SetEvent(m_hDataReadyEvent);
+  m_hDataReadyEvent.Set();
 
   while (!m_bStop)
   {
     // wait until someone called GetData()
-    if (WaitForSingleObject(m_hReadEvent, INFINITE) == WAIT_OBJECT_0)
+    if (m_hReadEvent.Wait())
     {
       // event generated by m_hReadEvent, continue
       // switch buffer and start reading in this one
       m_iCurrentBuffer = m_iCurrentBuffer ? 0 : 1;
       m_sRipBuffer[m_iCurrentBuffer].iRipError = ReadChunk();
 
-      SetEvent(m_hDataReadyEvent);
+      m_hDataReadyEvent.Set();
     }
   }
 }
@@ -137,14 +131,14 @@ void CCDDAReader::Process()
 int CCDDAReader::GetData(BYTE** stream, long& lBytes)
 {
   // wait until we are sure we have a buffer that is filled
-  WaitForSingleObject(m_hDataReadyEvent, INFINITE);
+  m_hDataReadyEvent.Wait();
 
   int iError = m_sRipBuffer[m_iCurrentBuffer].iRipError;
   *stream = m_sRipBuffer[m_iCurrentBuffer].pbtStream;
   lBytes = m_sRipBuffer[m_iCurrentBuffer].lBytesRead;
 
   // got data buffer, signal thread so it can start filling the other buffer
-  SetEvent(m_hReadEvent);
+  m_hReadEvent.Set();
   return iError;
 }
 
index 3f5cf7d..754bce5 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "FileItem.h"
 #include "filesystem/File.h"
+#include "threads/Event.h"
 
 struct RipBuffer
 {
@@ -57,8 +58,8 @@ protected:
   RipBuffer m_sRipBuffer[2]; // hold space for 2 buffers
   int m_iCurrentBuffer;   // 0 or 1
 
-  HANDLE m_hReadEvent;       // data is fetched
-  HANDLE m_hDataReadyEvent;  // data is ready to be fetched
+  CEvent m_hReadEvent;       // data is fetched
+  CEvent m_hDataReadyEvent;  // data is ready to be fetched
 
   bool m_iInitialized;
 
index a3c19c5..13a23e2 100644 (file)
@@ -821,27 +821,6 @@ extern "C" int WINAPI dllCreateDirectoryA(const char *pathname, void *sa)
   return 1;
 }
 
-extern "C" DWORD WINAPI dllWaitForSingleObject(HANDLE hHandle, DWORD dwMiliseconds)
-{
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "WaitForSingleObject(0x%x, %d)", hHandle, dwMiliseconds);
-#endif
-  return WaitForSingleObject(hHandle, dwMiliseconds);
-}
-
-#ifdef _LINUX
-extern "C" DWORD WINAPI dllWaitForMultipleObjects(DWORD nCount, HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds)
-#else
-extern "C" DWORD WINAPI dllWaitForMultipleObjects(DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds)
-#endif
-{
-#ifdef API_DEBUG
-  CLog::Log(LOGDEBUG, "WaitForMultipleObjects(..)");
-#endif
-
-  return WaitForMultipleObjects(nCount, lpHandles, fWaitAll, dwMilliseconds);
-}
-
 extern "C" BOOL WINAPI dllGetProcessAffinityMask(HANDLE hProcess, LPDWORD lpProcessAffinityMask, LPDWORD lpSystemAffinityMask)
 {
   CLog::Log(LOGDEBUG, "GetProcessAffinityMask(%p, %p, %p) => 1\n",
index 77648cd..2e637a7 100644 (file)
@@ -682,19 +682,6 @@ extern "C" int WINAPI dllSetUnhandledExceptionFilter(void* filter);
 extern "C" int WINAPI dllSetEnvironmentVariableA(const char *name, const char *value);
 extern "C" int WINAPI dllCreateDirectoryA(const char *pathname, void *sa);
 
-extern "C" DWORD WINAPI dllWaitForSingleObject(HANDLE hHandle, DWORD dwMiliseconds);
-
-// in linux we didnt define the handle array -  const.
-// the reason is that in linux we implement it as
-// a pointer to an object and the wait function does change it.
-// so - to avoid conversions we change the spec of the function.
-// come to think about it - it makes more senes that it wont be const.
-#ifdef _LINUX
-extern "C" DWORD WINAPI dllWaitForMultipleObjects(DWORD nCount, HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds);
-#else
-extern "C" DWORD WINAPI dllWaitForMultipleObjects(DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds);
-#endif
-
 extern "C" BOOL WINAPI dllGetProcessAffinityMask(HANDLE hProcess, LPDWORD lpProcessAffinityMask, LPDWORD lpSystemAffinityMask);
 
 extern "C" HGLOBAL WINAPI dllLoadResource(HMODULE module, HRSRC res);
index 625f5fc..465e6e6 100644 (file)
@@ -132,7 +132,7 @@ CLinuxRendererGL::CLinuxRendererGL()
 {
   m_textureTarget = GL_TEXTURE_2D;
   for (int i = 0; i < NUM_BUFFERS; i++)
-    m_eventTexturesDone[i] = CreateEvent(NULL,FALSE,TRUE,NULL);
+    m_eventTexturesDone[i] = new CEvent;
 
   m_renderMethod = RENDER_GLSL;
   m_renderQuality = RQ_SINGLEPASS;
@@ -164,7 +164,7 @@ CLinuxRendererGL::~CLinuxRendererGL()
 {
   UnInit();
   for (int i = 0; i < NUM_BUFFERS; i++)
-    CloseHandle(m_eventTexturesDone[i]);
+    delete m_eventTexturesDone[i];
 
   if (m_rgbPbo)
   {
@@ -314,7 +314,7 @@ int CLinuxRendererGL::GetImage(YV12Image *image, int source, bool readonly)
     im.flags |= IMAGE_FLAG_READING;
   else
   {
-    if( WaitForSingleObject(m_eventTexturesDone[source], 500) == WAIT_TIMEOUT )
+    if( ! m_eventTexturesDone[source]->WaitMSec(500))
       CLog::Log(LOGWARNING, "%s - Timeout waiting for texture %d", __FUNCTION__, source);
 
     im.flags |= IMAGE_FLAG_WRITING;
@@ -342,7 +342,7 @@ void CLinuxRendererGL::ReleaseImage(int source, bool preserve)
   YV12Image &im = m_buffers[source].image;
 
   if( im.flags & IMAGE_FLAG_WRITING )
-    SetEvent(m_eventTexturesDone[source]);
+    m_eventTexturesDone[source]->Set();
 
   im.flags &= ~IMAGE_FLAG_INUSE;
   im.flags |= IMAGE_FLAG_READY;
@@ -470,7 +470,7 @@ void CLinuxRendererGL::UploadYV12Texture(int source)
 
   if (!(im->flags&IMAGE_FLAG_READY))
   {
-    SetEvent(m_eventTexturesDone[source]);
+    m_eventTexturesDone[source]->Set();
     return;
   }
 
@@ -533,7 +533,7 @@ void CLinuxRendererGL::UploadYV12Texture(int source)
              , im->stride[2], im->plane[2] );
   }
 
-  SetEvent(m_eventTexturesDone[source]);
+  m_eventTexturesDone[source]->Set();
 
   VerifyGLState();
 
@@ -549,7 +549,7 @@ void CLinuxRendererGL::Reset()
     /* reset all image flags, this will cleanup textures later */
     m_buffers[i].image.flags = 0;
     /* reset texture locks, a bit ugly, could result in tearing */
-    SetEvent(m_eventTexturesDone[i]);
+    m_eventTexturesDone[i]->Set();
   }
 }
 
@@ -577,7 +577,7 @@ void CLinuxRendererGL::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
 
   g_graphicsContext.BeginPaint();
 
-  if( WaitForSingleObject(m_eventTexturesDone[index], 500) == WAIT_TIMEOUT )
+  if( !m_eventTexturesDone[index]->WaitMSec(500))
   {
     CLog::Log(LOGWARNING, "%s - Timeout waiting for texture %d", __FUNCTION__, index);
 
@@ -766,7 +766,7 @@ unsigned int CLinuxRendererGL::DrawSlice(unsigned char *src[], int stride[], int
     }
   }
 
-  SetEvent(m_eventTexturesDone[index]);
+  m_eventTexturesDone[index]->Set();
   return 0;
 }
 
@@ -1926,7 +1926,7 @@ bool CLinuxRendererGL::CreateYV12Texture(int index)
     }
   }
   glDisable(m_textureTarget);
-  SetEvent(m_eventTexturesDone[index]);
+  m_eventTexturesDone[index]->Set();
   return true;
 }
 
@@ -1941,7 +1941,7 @@ void CLinuxRendererGL::UploadNV12Texture(int source)
 
   if (!(im->flags & IMAGE_FLAG_READY))
   {
-    SetEvent(m_eventTexturesDone[source]);
+    m_eventTexturesDone[source]->Set();
     return;
   }
 
@@ -1992,7 +1992,7 @@ void CLinuxRendererGL::UploadNV12Texture(int source)
              , im->stride[1]/2, im->plane[1] );
   }
 
-  SetEvent(m_eventTexturesDone[source]);
+  m_eventTexturesDone[source]->Set();
 
   VerifyGLState();
 
@@ -2156,7 +2156,7 @@ bool CLinuxRendererGL::CreateNV12Texture(int index)
     }
   }
   glDisable(m_textureTarget);
-  SetEvent(m_eventTexturesDone[index]);
+  m_eventTexturesDone[index]->Set();
 
   return true;
 }
@@ -2247,7 +2247,7 @@ bool CLinuxRendererGL::CreateVDPAUTexture(int index)
 
   glGenTextures(1, &plane.id);
 
-  SetEvent(m_eventTexturesDone[index]);
+  m_eventTexturesDone[index]->Set();
 #endif
   return true;
 }
@@ -2255,7 +2255,7 @@ bool CLinuxRendererGL::CreateVDPAUTexture(int index)
 void CLinuxRendererGL::UploadVDPAUTexture(int index)
 {
 #ifdef HAVE_LIBVDPAU
-  SetEvent(m_eventTexturesDone[index]);
+  m_eventTexturesDone[index]->Set();
   glPixelStorei(GL_UNPACK_ALIGNMENT,1); //what's this for?
 #endif
 }
@@ -2317,7 +2317,7 @@ bool CLinuxRendererGL::CreateVAAPITexture(int index)
   glTexImage2D(m_textureTarget, 0, GL_RGBA, plane.texwidth, plane.texheight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
   glBindTexture(m_textureTarget, 0);
   glDisable(m_textureTarget);
-  SetEvent(m_eventTexturesDone[index]);
+  m_eventTexturesDone[index]->Set();
 #endif
   return true;
 }
@@ -2402,7 +2402,7 @@ void CLinuxRendererGL::UploadVAAPITexture(int index)
   if(status != VA_STATUS_SUCCESS)
     CLog::Log(LOGERROR, "CLinuxRendererGL::UploadVAAPITexture - failed to copy surface to glx %d - %s", status, vaErrorStr(status));
 
-  SetEvent(m_eventTexturesDone[index]);
+  m_eventTexturesDone[index]->Set();
 #endif
 }
 
@@ -2414,7 +2414,7 @@ void CLinuxRendererGL::UploadYUV422PackedTexture(int source)
 
   if (!(im->flags & IMAGE_FLAG_READY))
   {
-    SetEvent(m_eventTexturesDone[source]);
+    m_eventTexturesDone[source]->Set();
     return;
   }
 
@@ -2448,7 +2448,7 @@ void CLinuxRendererGL::UploadYUV422PackedTexture(int source)
              , im->stride[0] / 4, im->plane[0] );
   }
 
-  SetEvent(m_eventTexturesDone[source]);
+  m_eventTexturesDone[source]->Set();
 
   VerifyGLState();
 
@@ -2645,7 +2645,7 @@ bool CLinuxRendererGL::CreateYUV422PackedTexture(int index)
     VerifyGLState();
   }
   glDisable(m_textureTarget);
-  SetEvent(m_eventTexturesDone[index]);
+  m_eventTexturesDone[index]->Set();
 
   return true;
 }
@@ -2848,7 +2848,7 @@ void CLinuxRendererGL::UploadRGBTexture(int source)
 
   if (!(im->flags&IMAGE_FLAG_READY))
   {
-    SetEvent(m_eventTexturesDone[source]);
+    m_eventTexturesDone[source]->Set();
     return;
   }
 
@@ -2866,7 +2866,7 @@ void CLinuxRendererGL::UploadRGBTexture(int source)
   else
     ToRGBFrame(im, fields[FIELD_FULL][0].flipindex, buf.flipindex);
 
-  SetEvent(m_eventTexturesDone[source]);
+  m_eventTexturesDone[source]->Set();
 
   static int imaging = -1;
   if (imaging==-1)
index c32cd92..01be38b 100644 (file)
@@ -31,6 +31,8 @@
 #include "guilib/GraphicContext.h"
 #include "BaseRenderer.h"
 
+#include "threads/Event.h"
+
 class CRenderCapture;
 
 class CVDPAU;
@@ -293,7 +295,7 @@ protected:
   GLuint             m_rgbPbo;
   struct SwsContext *m_context;
 
-  HANDLE m_eventTexturesDone[NUM_BUFFERS];
+  CEvent* m_eventTexturesDone[NUM_BUFFERS];
 
   void BindPbo(YUVBUFFER& buff);
   void UnBindPbo(YUVBUFFER& buff);
index 3c95e98..ada6e02 100644 (file)
@@ -69,7 +69,7 @@ CLinuxRendererGLES::CLinuxRendererGLES()
   m_textureTarget = GL_TEXTURE_2D;
   for (int i = 0; i < NUM_BUFFERS; i++)
   {
-    m_eventTexturesDone[i] = CreateEvent(NULL,FALSE,TRUE,NULL);
+    m_eventTexturesDone[i] = new CEvent;
 #if defined(HAVE_LIBOPENMAX)
     m_buffers[i].openMaxBuffer = 0;
 #endif
@@ -107,7 +107,7 @@ CLinuxRendererGLES::~CLinuxRendererGLES()
 {
   UnInit();
   for (int i = 0; i < NUM_BUFFERS; i++)
-    CloseHandle(m_eventTexturesDone[i]);
+    delete m_eventTexturesDone[i];
 
   if (m_rgbBuffer != NULL) {
     delete [] m_rgbBuffer;
@@ -215,7 +215,7 @@ int CLinuxRendererGLES::GetImage(YV12Image *image, int source, bool readonly)
     im.flags |= IMAGE_FLAG_READING;
   else
   {
-    if( WaitForSingleObject(m_eventTexturesDone[source], 500) == WAIT_TIMEOUT )
+    if( !m_eventTexturesDone[source]->WaitMSec(500) )
       CLog::Log(LOGWARNING, "%s - Timeout waiting for texture %d", __FUNCTION__, source);
 
     im.flags |= IMAGE_FLAG_WRITING;
@@ -243,7 +243,7 @@ void CLinuxRendererGLES::ReleaseImage(int source, bool preserve)
   YV12Image &im = m_buffers[source].image;
 
   if( im.flags & IMAGE_FLAG_WRITING )
-    SetEvent(m_eventTexturesDone[source]);
+    m_eventTexturesDone[source]->Set();
 
   im.flags &= ~IMAGE_FLAG_INUSE;
   im.flags |= IMAGE_FLAG_READY;
@@ -372,7 +372,7 @@ void CLinuxRendererGLES::Reset()
     /* reset all image flags, this will cleanup textures later */
     m_buffers[i].image.flags = 0;
     /* reset texture locks, a bit ugly, could result in tearing */
-    SetEvent(m_eventTexturesDone[i]);
+    m_eventTexturesDone[i]->Set();
   }
 }
 
@@ -409,7 +409,7 @@ void CLinuxRendererGLES::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
 
   g_graphicsContext.BeginPaint();
 
-  if( WaitForSingleObject(m_eventTexturesDone[index], 500) == WAIT_TIMEOUT )
+  if( !m_eventTexturesDone[index]->WaitMSec(500))
   {
     CLog::Log(LOGWARNING, "%s - Timeout waiting for texture %d", __FUNCTION__, index);
 
@@ -522,7 +522,7 @@ unsigned int CLinuxRendererGLES::DrawSlice(unsigned char *src[], int stride[], i
     }
   }
 
-  SetEvent(m_eventTexturesDone[index]);
+  m_eventTexturesDone[index]->Set();
   return 0;
 }
 
@@ -1337,7 +1337,7 @@ void CLinuxRendererGLES::UploadYV12Texture(int source)
   if (!(im->flags&IMAGE_FLAG_READY))
 #endif
   {
-    SetEvent(m_eventTexturesDone[source]);
+    m_eventTexturesDone[source]->Set();
     return;
   }
 
@@ -1459,7 +1459,7 @@ void CLinuxRendererGLES::UploadYV12Texture(int source)
                , im->stride[2], im->plane[2] );
     }
   }
-  SetEvent(m_eventTexturesDone[source]);
+  m_eventTexturesDone[source]->Set();
 
   CalculateTextureSourceRects(source, 3);
 
@@ -1604,7 +1604,7 @@ bool CLinuxRendererGLES::CreateYV12Texture(int index)
     }
   }
   glDisable(m_textureTarget);
-  SetEvent(m_eventTexturesDone[index]);
+  m_eventTexturesDone[index]->Set();
   return true;
 }
 
@@ -1664,7 +1664,7 @@ void CLinuxRendererGLES::UploadCVRefTexture(int index)
     plane.flipindex = m_buffers[index].flipindex;
   }
 
-  SetEvent(m_eventTexturesDone[index]);
+  m_eventTexturesDone[index]->Set();
 #endif
 }
 void CLinuxRendererGLES::DeleteCVRefTexture(int index)
@@ -1737,7 +1737,7 @@ bool CLinuxRendererGLES::CreateCVRefTexture(int index)
   glBindTexture(m_textureTarget, 0);
   glDisable(m_textureTarget);
 
-  SetEvent(m_eventTexturesDone[index]);
+  m_eventTexturesDone[index]->Set();
 #endif
   return true;
 }
index 7f1511a..009ee91 100644 (file)
@@ -267,7 +267,7 @@ protected:
   BYTE       *m_rgbBuffer;  // if software scale is used, this will hold the result image
   unsigned int m_rgbBufferSize;
 
-  HANDLE m_eventTexturesDone[NUM_BUFFERS];
+  CEvent* m_eventTexturesDone[NUM_BUFFERS];
 
 };
 
index e58532a..c949e35 100644 (file)
@@ -28,7 +28,7 @@
 
 using namespace std;
 
-CDVDMessageQueue::CDVDMessageQueue(const string &owner)
+CDVDMessageQueue::CDVDMessageQueue(const string &owner) : m_hEvent(true)
 {
   m_owner = owner;
   m_iDataSize     = 0;
@@ -40,15 +40,12 @@ CDVDMessageQueue::CDVDMessageQueue(const string &owner)
   m_TimeBack      = DVD_NOPTS_VALUE;
   m_TimeFront     = DVD_NOPTS_VALUE;
   m_TimeSize      = 1.0 / 4.0; /* 4 seconds */
-  m_hEvent = CreateEvent(NULL, true, false, NULL);
 }
 
 CDVDMessageQueue::~CDVDMessageQueue()
 {
   // remove all remaining messages
   Flush();
-
-  CloseHandle(m_hEvent);
 }
 
 void CDVDMessageQueue::Init()
@@ -88,7 +85,7 @@ void CDVDMessageQueue::Abort()
 
   m_bAbortRequest = true;
 
-  SetEvent(m_hEvent); // inform waiter for abort action
+  m_hEvent.Set(); // inform waiter for abort action
 }
 
 void CDVDMessageQueue::End()
@@ -145,7 +142,7 @@ MsgQueueReturnCode CDVDMessageQueue::Put(CDVDMsg* pMsg, int priority)
 
   pMsg->Release();
 
-  SetEvent(m_hEvent); // inform waiter for new packet
+  m_hEvent.Set(); // inform waiter for new packet
 
   return MSGQ_OK;
 }
@@ -206,11 +203,11 @@ MsgQueueReturnCode CDVDMessageQueue::Get(CDVDMsg** pMsg, unsigned int iTimeoutIn
     }
     else
     {
-      ResetEvent(m_hEvent);
+      m_hEvent.Reset();
       lock.Leave();
 
       // wait for a new message
-      if (WaitForSingleObject(m_hEvent, iTimeoutInMilliSeconds) == WAIT_TIMEOUT)
+      if (!m_hEvent.WaitMSec(iTimeoutInMilliSeconds))
         return MSGQ_TIMEOUT;
 
       lock.Enter();
index ca81faa..3fa8e94 100644 (file)
@@ -25,6 +25,7 @@
 #include <string>
 #include <list>
 #include "threads/CriticalSection.h"
+#include "threads/Event.h"
 
 struct DVDMessageListItem
 {
@@ -121,7 +122,7 @@ public:
 
 private:
 
-  HANDLE m_hEvent;
+  CEvent m_hEvent;
   mutable CCriticalSection m_section;
 
   bool m_bAbortRequest;
index 17f9779..4afdd7c 100644 (file)
@@ -75,7 +75,7 @@ int CSimpleFileCache::Open()
 {
   Close();
 
-  m_hDataAvailEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+  m_hDataAvailEvent = new CEvent;
 
   CStdString fileName = CSpecialProtocol::TranslatePath(CUtil::GetNextFilename("special://temp/filecache%03d.cache", 999));
   if(fileName.empty())
@@ -119,7 +119,7 @@ int CSimpleFileCache::Open()
 void CSimpleFileCache::Close()
 {
   if (m_hDataAvailEvent)
-    CloseHandle(m_hDataAvailEvent);
+    delete m_hDataAvailEvent;
 
   m_hDataAvailEvent = NULL;
 
@@ -145,7 +145,7 @@ int CSimpleFileCache::WriteToCache(const char *pBuffer, size_t iSize)
   }
 
   // when reader waits for data it will wait on the event.
-  SetEvent(m_hDataAvailEvent);
+  m_hDataAvailEvent->Set();
 
   m_nWritePosition += iWritten;
   return iWritten;
@@ -193,8 +193,7 @@ int64_t CSimpleFileCache::WaitForData(unsigned int iMinAvail, unsigned int iMill
       return iAvail;
 
     // busy look (sleep max 1 sec each round)
-    DWORD dwRc = WaitForSingleObject(m_hDataAvailEvent, (timeout - time)>1000?(timeout - time):1000 );
-    if (dwRc == WAIT_FAILED || dwRc == WAIT_ABANDONED)
+    if (!m_hDataAvailEvent->WaitMSec((timeout - time)>1000?(timeout - time):1000 ))
       return CACHE_RC_ERROR;
   }
 
@@ -250,7 +249,7 @@ void CSimpleFileCache::Reset(int64_t iSourcePosition)
 void CSimpleFileCache::EndOfInput()
 {
   CCacheStrategy::EndOfInput();
-  SetEvent(m_hDataAvailEvent);
+  m_hDataAvailEvent->Set();
 }
 
 }
index 38628ae..18194d4 100644 (file)
@@ -86,7 +86,7 @@ public:
 protected:
   HANDLE  m_hCacheFileRead;
   HANDLE  m_hCacheFileWrite;
-  HANDLE  m_hDataAvailEvent;
+  CEvent*  m_hDataAvailEvent;
   volatile int64_t m_nStartPosition;
   volatile int64_t m_nWritePosition;
   volatile int64_t m_nReadPosition;
index afd84e8..7fbce3c 100644 (file)
@@ -42,27 +42,20 @@ using namespace std;
 #define SEEKTIMOUT 30000
 
 #ifdef HAS_FILESYSTEM_RAR
-CFileRarExtractThread::CFileRarExtractThread()
+CFileRarExtractThread::CFileRarExtractThread() : hRunning(true), hQuit(true)
 {
   m_pArc = NULL;
   m_pCmd = NULL;
   m_pExtract = NULL;
-  hRunning = CreateEvent(NULL,true,false,NULL);
-  hRestart = CreateEvent(NULL,false,false,NULL);
-  hQuit = CreateEvent(NULL,true,false,NULL);
   StopThread();
   Create();
 }
 
 CFileRarExtractThread::~CFileRarExtractThread()
 {
-  SetEvent(hQuit);
-  WaitForSingleObject(hRestart,INFINITE);
+  hQuit.Set();
+  hRestart.Wait();
   StopThread();
-
-  CloseHandle(hRunning);
-  CloseHandle(hQuit);
-  CloseHandle(hRestart);
 }
 
 void CFileRarExtractThread::Start(Archive* pArc, CommandData* pCmd, CmdExtract* pExtract, int iSize)
@@ -72,14 +65,14 @@ void CFileRarExtractThread::Start(Archive* pArc, CommandData* pCmd, CmdExtract*
   m_pExtract = pExtract;
   m_iSize = iSize;
 
-  m_pExtract->GetDataIO().hBufferFilled = CreateEvent(NULL,false,false,NULL);
-  m_pExtract->GetDataIO().hBufferEmpty = CreateEvent(NULL,false,false,NULL);
-  m_pExtract->GetDataIO().hSeek = CreateEvent(NULL,true,false,NULL);
-  m_pExtract->GetDataIO().hSeekDone = CreateEvent(NULL,false,false,NULL);
-  m_pExtract->GetDataIO().hQuit = CreateEvent(NULL,true,false,NULL);
+  m_pExtract->GetDataIO().hBufferFilled = new CEvent;
+  m_pExtract->GetDataIO().hBufferEmpty = new CEvent;
+  m_pExtract->GetDataIO().hSeek = new CEvent(true);
+  m_pExtract->GetDataIO().hSeekDone = new CEvent;
+  m_pExtract->GetDataIO().hQuit = new CEvent(true);
 
-  SetEvent(hRunning);
-  SetEvent(hRestart);
+  hRunning.Set();
+  hRestart.Set();
 }
 
 void CFileRarExtractThread::OnStartup()
@@ -92,16 +85,16 @@ void CFileRarExtractThread::OnExit()
 
 void CFileRarExtractThread::Process()
 {
-  while (WaitForSingleObject(hQuit,1) != WAIT_OBJECT_0)
+  while (hQuit.WaitMSec(1))
   {
-    if (WaitForSingleObject(hRestart,1) == WAIT_OBJECT_0)
+    if (hRestart.WaitMSec(1))
     {
       bool Repeat = false;
       m_pExtract->ExtractCurrentFile(m_pCmd,*m_pArc,m_iSize,Repeat);
-      ResetEvent(hRunning);
+      hRunning.Reset();
     }
   }
-  SetEvent(hRestart);
+  hRestart.Set();
 }
 #endif
 
@@ -264,7 +257,7 @@ unsigned int CFileRar::Read(void *lpBuf, int64_t uiBufSize)
   if (m_iFilePosition >= GetLength()) // we are done
     return 0;
 
-  if( WaitForSingleObject(m_pExtract->GetDataIO().hBufferEmpty,5000) == WAIT_TIMEOUT )
+  if( !m_pExtract->GetDataIO().hBufferEmpty->WaitMSec(5000) )
   {
     CLog::Log(LOGERROR, "%s - Timeout waiting for buffer to empty", __FUNCTION__);
     return 0;
@@ -293,8 +286,8 @@ unsigned int CFileRar::Read(void *lpBuf, int64_t uiBufSize)
       m_iBufferStart = m_iFilePosition;
     }
 
-    SetEvent(m_pExtract->GetDataIO().hBufferFilled);
-    WaitForSingleObject(m_pExtract->GetDataIO().hBufferEmpty,INFINITE);
+    m_pExtract->GetDataIO().hBufferFilled->Set();
+    m_pExtract->GetDataIO().hBufferEmpty->Wait();
 
     if (m_pExtract->GetDataIO().NextVolumeMissing)
       break;
@@ -324,7 +317,7 @@ unsigned int CFileRar::Read(void *lpBuf, int64_t uiBufSize)
     }
   }
 
-  SetEvent(m_pExtract->GetDataIO().hBufferEmpty);
+  m_pExtract->GetDataIO().hBufferEmpty->Set();
 
   return static_cast<unsigned int>(uiBufSize-uicBufSize);
 #else
@@ -374,13 +367,13 @@ int64_t CFileRar::Seek(int64_t iFilePosition, int iWhence)
   if (m_bUseFile)
     return m_File.Seek(iFilePosition,iWhence);
 
-  if( WaitForSingleObject(m_pExtract->GetDataIO().hBufferEmpty,SEEKTIMOUT) == WAIT_TIMEOUT )
+  if( !m_pExtract->GetDataIO().hBufferEmpty->WaitMSec(SEEKTIMOUT) )
   {
     CLog::Log(LOGERROR, "%s - Timeout waiting for buffer to empty", __FUNCTION__);
     return -1;
   }
 
-  SetEvent(m_pExtract->GetDataIO().hBufferEmpty);
+  m_pExtract->GetDataIO().hBufferEmpty->Set();
 
   switch (iWhence)
   {
@@ -429,21 +422,21 @@ int64_t CFileRar::Seek(int64_t iFilePosition, int iWhence)
     if (!OpenInArchive())
       return -1;
 
-    if( WaitForSingleObject(m_pExtract->GetDataIO().hBufferEmpty,SEEKTIMOUT) == WAIT_TIMEOUT )
+    if( !m_pExtract->GetDataIO().hBufferEmpty->WaitMSec(SEEKTIMOUT) )
     {
       CLog::Log(LOGERROR, "%s - Timeout waiting for buffer to empty", __FUNCTION__);
       return -1;
     }
-    SetEvent(m_pExtract->GetDataIO().hBufferEmpty);
+    m_pExtract->GetDataIO().hBufferEmpty->Set();
     m_pExtract->GetDataIO().m_iSeekTo = iFilePosition;
   }
   else
     m_pExtract->GetDataIO().m_iSeekTo = iFilePosition;
 
   m_pExtract->GetDataIO().SetUnpackToMemory(m_szBuffer,MAXWINMEMSIZE);
-  SetEvent(m_pExtract->GetDataIO().hSeek);
-  SetEvent(m_pExtract->GetDataIO().hBufferFilled);
-  if( WaitForSingleObject(m_pExtract->GetDataIO().hSeekDone,SEEKTIMOUT) == WAIT_TIMEOUT )
+  m_pExtract->GetDataIO().hSeek->Set();
+  m_pExtract->GetDataIO().hBufferFilled->Set();
+  if( !m_pExtract->GetDataIO().hSeekDone->WaitMSec(SEEKTIMOUT))
   {
     CLog::Log(LOGERROR, "%s - Timeout waiting for seek to finish", __FUNCTION__);
     return -1;
@@ -455,7 +448,7 @@ int64_t CFileRar::Seek(int64_t iFilePosition, int iWhence)
     return -1;
   }
 
-  if( WaitForSingleObject(m_pExtract->GetDataIO().hBufferEmpty,SEEKTIMOUT) == WAIT_TIMEOUT )
+  if( !m_pExtract->GetDataIO().hBufferEmpty->WaitMSec(SEEKTIMOUT) )
   {
     CLog::Log(LOGERROR, "%s - Timeout waiting for buffer to empty", __FUNCTION__);
     return -1;
@@ -539,18 +532,17 @@ void CFileRar::CleanUp()
 #ifdef HAS_FILESYSTEM_RAR
   if (m_pExtractThread)
   {
-    if (WaitForSingleObject(m_pExtractThread->hRunning,1) == WAIT_OBJECT_0)
+    if (m_pExtractThread->hRunning.WaitMSec(1))
     {
-      SetEvent(m_pExtract->GetDataIO().hQuit);
-      while (WaitForSingleObject(m_pExtractThread->hRunning,1) == WAIT_OBJECT_0)
+      m_pExtract->GetDataIO().hQuit->Set();
+      while (m_pExtractThread->hRunning.WaitMSec(1))
         Sleep(1);
-
     }
-    CloseHandle(m_pExtract->GetDataIO().hBufferFilled);
-    CloseHandle(m_pExtract->GetDataIO().hBufferEmpty);
-    CloseHandle(m_pExtract->GetDataIO().hSeek);
-    CloseHandle(m_pExtract->GetDataIO().hSeekDone);
-    CloseHandle(m_pExtract->GetDataIO().hQuit);
+    delete m_pExtract->GetDataIO().hBufferFilled;
+    delete m_pExtract->GetDataIO().hBufferEmpty;
+    delete m_pExtract->GetDataIO().hSeek;
+    delete m_pExtract->GetDataIO().hSeekDone;
+    delete m_pExtract->GetDataIO().hQuit;
   }
   if (m_pExtract)
   {
index 23d5c4b..dd825d2 100644 (file)
@@ -28,6 +28,7 @@
 #include "File.h"
 #include "UnrarXLib/rar.hpp"
 #include "threads/Thread.h"
+#include "threads/Event.h"
 
 namespace XFILE
 {
@@ -44,9 +45,9 @@ namespace XFILE
     virtual void OnExit();
     virtual void Process();
 
-    HANDLE hRunning;
-    HANDLE hRestart;
-    HANDLE hQuit;
+    CEvent hRunning;
+    CEvent hRestart;
+    CEvent hQuit;
 
   protected:
     Archive* m_pArc;
index 8488017..de6ab16 100644 (file)
@@ -47,14 +47,12 @@ CCriticalSection CPluginDirectory::m_handleLock;
 
 CPluginDirectory::CPluginDirectory()
 {
-  m_fetchComplete = CreateEvent(NULL, false, false, NULL);
   m_listItems = new CFileItemList;
   m_fileResult = new CFileItem;
 }
 
 CPluginDirectory::~CPluginDirectory(void)
 {
-  CloseHandle(m_fetchComplete);
   delete m_listItems;
   delete m_fileResult;
 }
@@ -93,7 +91,7 @@ bool CPluginDirectory::StartScript(const CStdString& strPath, bool retrievingDir
 
   CStdString basePath(url.Get());
   // reset our wait event, and grab a new handle
-  ResetEvent(m_fetchComplete);
+  m_fetchComplete.Reset();
   int handle = getNewHandle(this);
 
   // clear out our status variables
@@ -207,7 +205,7 @@ void CPluginDirectory::EndOfDirectory(int handle, bool success, bool replaceList
     dir->m_listItems->AddSortMethod(SORT_METHOD_NONE, 552, LABEL_MASKS("%L", "%D"));
 
   // set the event to mark that we're done
-  SetEvent(dir->m_fetchComplete);
+  dir->m_fetchComplete.Set();
 }
 
 void CPluginDirectory::AddSortMethod(int handle, SORT_METHOD sortMethod, const CStdString &label2Mask)
@@ -457,7 +455,7 @@ bool CPluginDirectory::WaitOnScriptResult(const CStdString &scriptPath, const CS
     {
       CSingleExit ex(g_graphicsContext);
       // check if the python script is finished
-      if (WaitForSingleObject(m_fetchComplete, 20) == WAIT_OBJECT_0)
+      if (m_fetchComplete.WaitMSec(20))
       { // python has returned
         CLog::Log(LOGDEBUG, "%s- plugin returned %s", __FUNCTION__, m_success ? "successfully" : "failure");
         break;
@@ -468,7 +466,7 @@ bool CPluginDirectory::WaitOnScriptResult(const CStdString &scriptPath, const CS
     if (!g_pythonParser.isRunning(g_pythonParser.getScriptId(scriptPath.c_str())))
 #endif
     { // check whether we exited normally
-      if (WaitForSingleObject(m_fetchComplete, 0) == WAIT_TIMEOUT)
+      if (!m_fetchComplete.WaitMSec(0))
       { // python didn't return correctly
         CLog::Log(LOGDEBUG, " %s - plugin exited prematurely - terminating", __FUNCTION__);
         m_success = false;
@@ -557,7 +555,7 @@ void CPluginDirectory::SetResolvedUrl(int handle, bool success, const CFileItem
   *dir->m_fileResult = *resultItem;
 
   // set the event to mark that we're done
-  SetEvent(dir->m_fetchComplete);
+  dir->m_fetchComplete.Set();
 }
 
 CStdString CPluginDirectory::GetSetting(int handle, const CStdString &strID)
index f08f9d0..acc6cdb 100644 (file)
@@ -31,6 +31,8 @@
 #include "addons/IAddon.h"
 #include "PlatformDefs.h"
 
+#include "threads/Event.h"
+
 class CURL;
 class CFileItemList;
 
@@ -72,7 +74,7 @@ private:
 
   CFileItemList* m_listItems;
   CFileItem*     m_fileResult;
-  HANDLE         m_fetchComplete;
+  CEvent         m_fetchComplete;
 
   bool          m_cancelled;    // set to true when we are cancelled
   bool          m_success;      // set by script in EndOfDirectory
index 30f2f77..f9dfe9f 100644 (file)
@@ -67,7 +67,6 @@ XBPython::XBPython()
   m_bLogin            = false;
   m_nextid            = 0;
   m_mainThreadState   = NULL;
-  m_globalEvent       = CreateEvent(NULL, false, false, (char*)"pythonGlobalEvent");
   m_ThreadId          = CThread::GetCurrentThreadId();
   m_iDllScriptCounter = 0;
   m_vecPlayerCallbackList.clear();
@@ -75,7 +74,6 @@ XBPython::XBPython()
 
 XBPython::~XBPython()
 {
-  CloseHandle(m_globalEvent);
 }
 
 // message all registered callbacks that xbmc stopped playing
@@ -674,15 +672,15 @@ int XBPython::GetPythonScriptId(int scriptPosition)
 
 void XBPython::PulseGlobalEvent()
 {
-  SetEvent(m_globalEvent);
+  m_globalEvent.Set();
 }
 
-void XBPython::WaitForEvent(HANDLE hEvent, unsigned int timeout)
+void XBPython::WaitForEvent(CEvent& hEvent, unsigned int timeout)
 {
   // wait for either this event our our global event
-  HANDLE handles[2] = { hEvent, m_globalEvent };
-  WaitForMultipleObjects(2, handles, FALSE, timeout);
-  ResetEvent(m_globalEvent);
+  XbmcThreads::CEventGroup eventGroup(&hEvent, &m_globalEvent, NULL);
+  eventGroup.wait(timeout);
+  m_globalEvent.Reset();
 }
 
 // execute script, returns -1 if script doesn't exist
index c46039d..7737744 100644 (file)
@@ -61,7 +61,7 @@ public:
   void Process();
 
   void PulseGlobalEvent();
-  void WaitForEvent(HANDLE hEvent, unsigned int timeout);
+  void WaitForEvent(CEvent& hEvent, unsigned int timeout);
 
   int ScriptsSize();
   int GetPythonScriptId(int scriptPosition);
@@ -110,7 +110,6 @@ private:
   void*             m_mainThreadState;
   ThreadIdentifier  m_ThreadId;
   bool              m_bInitialized;
-  HANDLE            m_hEvent;
   int               m_iDllScriptCounter; // to keep track of the total scripts running that need the dll
   HMODULE           m_hModule;
   unsigned int      m_endtime;
@@ -121,7 +120,7 @@ private:
   LibraryLoader*      m_pDll;
 
   // any global events that scripts should be using
-  HANDLE m_globalEvent;
+  CEvent m_globalEvent;
 
   // in order to finalize and unload the python library, need to save all the extension libraries that are
   // loaded by it and unload them first (not done by finalize)
index 46a254e..52724a2 100644 (file)
@@ -56,17 +56,15 @@ PyXBMCAction::~PyXBMCAction() {
 }
 
 CGUIPythonWindow::CGUIPythonWindow(int id)
-: CGUIWindow(id, "")
+  : CGUIWindow(id, ""), m_actionEvent(true)
 {
   pCallbackWindow = NULL;
   m_threadState = NULL;
-  m_actionEvent = CreateEvent(NULL, true, false, NULL);
   m_loadOnDemand = false;
 }
 
 CGUIPythonWindow::~CGUIPythonWindow(void)
 {
-  CloseHandle(m_actionEvent);
 }
 
 bool CGUIPythonWindow::OnAction(const CAction &action)
@@ -165,12 +163,12 @@ void CGUIPythonWindow::SetCallbackWindow(void *state, void *object)
 void CGUIPythonWindow::WaitForActionEvent(unsigned int timeout)
 {
   g_pythonParser.WaitForEvent(m_actionEvent, timeout);
-  ResetEvent(m_actionEvent);
+  m_actionEvent.Reset();
 }
 
 void CGUIPythonWindow::PulseActionEvent()
 {
-  SetEvent(m_actionEvent);
+  m_actionEvent.Set();
 }
 
 
index 2146d90..9a90eff 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include "guilib/GUIWindow.h"
+#include "threads/Event.h"
 
 class PyXBMCAction
 {
@@ -54,5 +55,5 @@ public:
 protected:
   void* pCallbackWindow;
   void* m_threadState;
-  HANDLE           m_actionEvent;
+  CEvent           m_actionEvent;
 };
index bef2cb1..86a77dd 100644 (file)
@@ -45,18 +45,16 @@ using namespace std;
 using namespace PYXBMC;
 
 CGUIPythonWindowXML::CGUIPythonWindowXML(int id, CStdString strXML, CStdString strFallBackPath)
-: CGUIMediaWindow(id, strXML)
+  : CGUIMediaWindow(id, strXML), m_actionEvent(true)
 {
   pCallbackWindow = NULL;
   m_threadState = NULL;
-  m_actionEvent = CreateEvent(NULL, true, false, NULL);
   m_loadOnDemand = false;
   m_scriptPath = strFallBackPath;
 }
 
 CGUIPythonWindowXML::~CGUIPythonWindowXML(void)
 {
-  CloseHandle(m_actionEvent);
 }
 
 bool CGUIPythonWindowXML::Update(const CStdString &strPath)
@@ -263,12 +261,12 @@ void CGUIPythonWindowXML::ClearList()
 void CGUIPythonWindowXML::WaitForActionEvent(unsigned int timeout)
 {
   g_pythonParser.WaitForEvent(m_actionEvent, timeout);
-  ResetEvent(m_actionEvent);
+  m_actionEvent.Reset();
 }
 
 void CGUIPythonWindowXML::PulseActionEvent()
 {
-  SetEvent(m_actionEvent);
+  m_actionEvent.Set();
 }
 
 void CGUIPythonWindowXML::AllocResources(bool forceLoad /*= FALSE */)
index 86b6a88..8cbc60c 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "GUIPythonWindow.h"
 #include "windows/GUIMediaWindow.h"
+#include "threads/Event.h"
 
 int Py_XBMC_Event_OnClick(void* arg);
 int Py_XBMC_Event_OnFocus(void* arg);
@@ -60,7 +61,7 @@ protected:
   void             SetupShares();
   void*            pCallbackWindow;
   void*            m_threadState;
-  HANDLE           m_actionEvent;
+  CEvent           m_actionEvent;
   bool             m_bRunning;
   CStdString       m_scriptPath;
   CStdString       m_mediaDir;
index bd171bc..454ff85 100644 (file)
@@ -168,193 +168,4 @@ void GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer)
 #endif
 }
 
-//////////////////////////////////////////////////////////////////////////////
-static DWORD WINAPI WaitForEvent(HANDLE hHandle, CSingleLock& lock, DWORD dwMilliseconds)
-{
-  DWORD dwRet = 0;
-  ConditionVariable::TimedWaitResponse nRet = ConditionVariable::TW_OK;
-  // something like the following would be nice,
-  // but I can't figure a wait to check if a mutex is locked:
-  // assert(hHandle->m_hMutex.IsLocked());
-  if (hHandle->m_bEventSet == false)
-  {
-    if (dwMilliseconds == 0)
-    {
-      nRet = ConditionVariable::TW_TIMEDOUT;
-    }
-    else if (dwMilliseconds == INFINITE)
-    {
-      //wait until event is set
-      while( hHandle->m_bEventSet == false )
-      {
-        hHandle->m_hCond->wait(lock);
-        nRet = ConditionVariable::TW_OK;
-      }
-    }
-    else
-    {
-      //wait until event is set, but modify remaining time
-      DWORD dwStartTime = CTimeUtils::GetTimeMS();
-      DWORD dwRemainingTime = dwMilliseconds;
-      while( hHandle->m_bEventSet == false )
-      {
-        nRet = hHandle->m_hCond->wait(lock, dwRemainingTime);
-        if(hHandle->m_bEventSet)
-          break;
-
-        //fix time to wait because of spurious wakeups
-        DWORD dwElapsed = CTimeUtils::GetTimeMS() - dwStartTime;
-        if(dwElapsed < dwMilliseconds)
-        {
-          dwRemainingTime = dwMilliseconds - dwElapsed;
-        }
-        else
-        {
-          //ran out of time
-          nRet = ConditionVariable::TW_TIMEDOUT;
-          break;
-        }
-      }
-    }
-  }
-
-  if (hHandle->m_bManualEvent == false && nRet == 0)
-    hHandle->m_bEventSet = false;
-
-  // Translate return code.
-  if (nRet == ConditionVariable::TW_OK)
-    dwRet = WAIT_OBJECT_0;
-  else if (nRet == ConditionVariable::TW_TIMEDOUT)
-    dwRet = WAIT_TIMEOUT;
-  else
-    dwRet = WAIT_FAILED;
-
-  return dwRet;
-}
-
-DWORD WINAPI WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds ) {
-  if (hHandle == NULL ||  hHandle == (HANDLE)-1)
-    return WAIT_FAILED;
-
-  DWORD dwRet = WAIT_FAILED;
-
-  switch (hHandle->GetType()) {
-    case CXHandle::HND_EVENT:
-    case CXHandle::HND_THREAD:
-      {
-        CSingleLock lock(*(hHandle->m_hMutex));
-
-        // Perform the wait.
-        dwRet = WaitForEvent(hHandle, lock, dwMilliseconds);
-      }
-      break;
-
-    case CXHandle::HND_MUTEX:
-      {
-        CSingleLock lock(*(hHandle->m_hMutex));
-        if (hHandle->OwningThread == pthread_self() &&
-            hHandle->RecursionCount > 0) {
-          hHandle->RecursionCount++;
-          dwRet = WAIT_OBJECT_0;
-          break;
-        }
-
-        // Perform the wait.
-        dwRet = WaitForEvent(hHandle, lock, dwMilliseconds);
-
-        if (dwRet == WAIT_OBJECT_0)
-        {
-          hHandle->OwningThread = pthread_self();
-          hHandle->RecursionCount = 1;
-        }
-      }
-      break;
-    default:
-      XXLog(ERROR, "cant wait for this type of object");
-  }
-
-  return dwRet;
-}
-
-DWORD WINAPI WaitForMultipleObjects( DWORD nCount, HANDLE* lpHandles, BOOL bWaitAll,  DWORD dwMilliseconds) {
-  DWORD dwRet = WAIT_FAILED;
-
-  if (nCount < 1 || lpHandles == NULL)
-    return dwRet;
-
-  BOOL bWaitEnded    = FALSE;
-  DWORD dwStartTime   = CTimeUtils::GetTimeMS();
-  BOOL *bDone = new BOOL[nCount];
-  CXHandle* multi = CreateEvent(NULL, FALSE, FALSE, NULL);
-
-  for (unsigned int i=0; i < nCount; i++)
-  {
-    bDone[i] = FALSE;
-    CSingleLock lock (*(lpHandles[i]->m_hMutex));
-    lpHandles[i]->m_hParents.push_back(multi);
-  }
-
-  DWORD nSignalled = 0;
-  while (!bWaitEnded) {
-
-    for (unsigned int i=0; i < nCount; i++) {
-
-      if (!bDone[i]) {
-        DWORD dwWaitRC = WaitForSingleObject(lpHandles[i], 0);
-        if (dwWaitRC == WAIT_OBJECT_0) {
-          dwRet = WAIT_OBJECT_0 + i;
-
-          nSignalled++;
-
-          bDone[i] = TRUE;
-
-          if ( (bWaitAll && nSignalled == nCount) || !bWaitAll ) {
-            bWaitEnded = TRUE;
-            break;
-          }
-        }
-        else if (dwWaitRC == WAIT_FAILED) {
-          dwRet = WAIT_FAILED;
-          bWaitEnded = TRUE;
-          break;
-        }
-      }
-
-    }
-
-    if (bWaitEnded)
-      break;
-
-    DWORD dwElapsed = CTimeUtils::GetTimeMS() - dwStartTime;
-    if (dwMilliseconds != INFINITE && dwElapsed >= dwMilliseconds) {
-      dwRet = WAIT_TIMEOUT;
-      bWaitEnded = TRUE;
-      break;
-    }
-
-    DWORD dwWaitRC;
-    {
-      CSingleLock lock(*(multi->m_hMutex));
-      dwWaitRC = WaitForEvent(multi, lock, 200);
-    }
-
-    if(dwWaitRC == WAIT_FAILED)
-    {
-      dwRet = WAIT_FAILED;
-      bWaitEnded = TRUE;
-      break;
-    }
-  }
-
-  for (unsigned int i=0; i < nCount; i++)
-  {
-    CSingleLock lock(*(lpHandles[i]->m_hMutex));
-    lpHandles[i]->m_hParents.remove_if(bind2nd(equal_to<CXHandle*>(), multi));
-  }
-
-  delete [] bDone;
-  CloseHandle(multi);
-  return dwRet;
-}
-
 #endif
index 5cb0c29..c8effa2 100644 (file)
@@ -38,9 +38,6 @@
 
 void GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer);
 
-DWORD WINAPI WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds );
-DWORD WINAPI WaitForMultipleObjects( DWORD nCount, HANDLE* lpHandles, BOOL bWaitAll,  DWORD dwMilliseconds);
-
 #endif
 
 #endif
index 1a1898e..d3c34de 100644 (file)
@@ -70,14 +70,12 @@ CLastFmManager* CLastFmManager::m_pInstance=NULL;
 
 CLastFmManager::CLastFmManager()
 {
-  m_hWorkerEvent = CreateEvent(NULL, false, false, NULL);
   m_RadioTrackQueue = new CPlayList;
 }
 
 CLastFmManager::~CLastFmManager()
 {
   StopRadio(true);
-  CloseHandle(m_hWorkerEvent);
   StopThread();
   CLog::Log(LOGINFO,"lastfm destroyed");
   delete m_RadioTrackQueue;
@@ -250,7 +248,7 @@ bool CLastFmManager::ChangeStation(const CURL& stationUrl)
   CacheTrackThumb(XBMC_LASTFM_MINTRACKS);
   AddToPlaylist(XBMC_LASTFM_MINTRACKS);
   Create(); //start thread
-  SetEvent(m_hWorkerEvent); //kickstart the thread
+  m_hWorkerEvent.Set(); //kickstart the thread
 
   CSingleLock lock(m_lockPlaylist);
   CPlayList& playlist = g_playlistPlayer.GetPlaylist(PLAYLIST_MUSIC);
@@ -536,7 +534,7 @@ void CLastFmManager::Update()
       //get more tracks
       if (ThreadHandle() != NULL)
       {
-        SetEvent(m_hWorkerEvent);
+        m_hWorkerEvent.Set();
       }
     }
   }
@@ -608,7 +606,7 @@ void CLastFmManager::Process()
 
   while (!m_bStop)
   {
-    WaitForSingleObject(m_hWorkerEvent, INFINITE);
+    m_hWorkerEvent.Wait();
     if (m_bStop)
       break;
     int iNrCachedTracks = m_RadioTrackQueue->size();
@@ -636,7 +634,7 @@ void CLastFmManager::StopRadio(bool bKillSession /*= true*/)
   if (m_ThreadHandle)
   {
     m_bStop = true;
-    SetEvent(m_hWorkerEvent);
+    m_hWorkerEvent.Set();
     StopThread();
   }
   m_CurrentSong.CurrentSong = NULL;
index 1135590..a520af0 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "threads/CriticalSection.h"
 #include "threads/Thread.h"
+#include "threads/Event.h"
 #include "PlayListPlayer.h"
 
 namespace PLAYLIST
@@ -99,7 +100,7 @@ private:
   LastFmManagerSong m_CurrentSong;
 
   PLAYLIST::CPlayList* m_RadioTrackQueue;
-  HANDLE m_hWorkerEvent;
+  CEvent m_hWorkerEvent;
   CCriticalSection m_lockCache;
   CCriticalSection m_lockPlaylist;
 
index 3969118..aaac14f 100644 (file)
@@ -54,14 +54,10 @@ CScrobbler::CScrobbler(const CStdString &strHandshakeURL, const CStdString &strL
   m_strHandshakeURL = strHandshakeURL;
   m_strLogPrefix    = strLogPrefix;
   ResetState();
-
-  if (!(m_hEvent = CreateEvent(NULL, false, false, NULL)))
-    throw EOutOfMemory();
 }
 
 CScrobbler::~CScrobbler()
 {
-  CloseHandle(m_hEvent);
 }
 
 void CScrobbler::Init()
@@ -141,7 +137,7 @@ void CScrobbler::UpdateStatus()
       CSingleLock lock(m_actionLock);
       m_action = SCROBBLER_ACTION_NOWPLAYING;
     }
-    SetEvent(m_hEvent);
+    m_hEvent.Set();
     return;
   }
 
@@ -169,7 +165,7 @@ void CScrobbler::SubmitQueue()
       CSingleLock lock(m_actionLock);
       m_action = SCROBBLER_ACTION_SUBMIT;
     }
-    SetEvent(m_hEvent);
+    m_hEvent.Set();
   }
 }
 
@@ -642,8 +638,8 @@ void CScrobbler::Process()
   }
   while (!m_bStop)
   {
-    WaitForSingleObject(m_hEvent, INFINITE);
-       if (m_bStop)
+    m_hEvent.Wait();
+    if (m_bStop)
       break;
     
     if (m_strSessionID.IsEmpty())
index 5593d49..560a794 100644 (file)
@@ -26,6 +26,7 @@
 #include "utils/StdString.h"
 #include "threads/Thread.h"
 #include "threads/CriticalSection.h"
+#include "threads/Event.h"
 
 #define SCROBBLER_USER_ERROR_BADAUTH  1
 #define SCROBBLER_USER_ERROR_BANNED   2
@@ -132,7 +133,7 @@ protected:
   CStdString m_strSubmissionURL;
   CStdString m_strHandshakeTimeStamp;
   SubmissionJournalEntry m_CurrentTrack;
-  HANDLE m_hEvent;
+  CEvent m_hEvent;
   XFILE::CFileCurl  *m_pHttp;
   CCriticalSection  m_queueLock;
   CCriticalSection  m_actionLock;
index 9ce99c0..15a76f2 100644 (file)
@@ -70,14 +70,12 @@ static float zoomamount[10] = { 1.0f, 1.2f, 1.5f, 2.0f, 2.8f, 4.0f, 6.0f, 9.0f,
 CBackgroundPicLoader::CBackgroundPicLoader()
 {
   m_pCallback = NULL;
-  m_loadPic = CreateEvent(NULL,false,false,NULL);
   m_isLoading = false;
 }
 
 CBackgroundPicLoader::~CBackgroundPicLoader()
 {
   StopThread();
-  CloseHandle(m_loadPic);
 }
 
 void CBackgroundPicLoader::Create(CGUIWindowSlideShow *pCallback)
@@ -93,7 +91,7 @@ void CBackgroundPicLoader::Process()
   unsigned int count = 0;
   while (!m_bStop)
   { // loop around forever, waiting for the app to call LoadPic
-    if (WaitForSingleObject(m_loadPic, 10) == WAIT_OBJECT_0)
+    if (m_loadPic.WaitMSec(10))
     {
       if (m_pCallback)
       {
@@ -134,7 +132,7 @@ void CBackgroundPicLoader::LoadPic(int iPic, int iSlideNumber, const CStdString
   m_maxWidth = maxWidth;
   m_maxHeight = maxHeight;
   m_isLoading = true;
-  SetEvent(m_loadPic);
+  m_loadPic.Set();
 }
 
 CGUIWindowSlideShow::CGUIWindowSlideShow(void)
index 664dd71..7c90a5d 100644 (file)
@@ -25,6 +25,7 @@
 #include "guilib/GUIWindow.h"
 #include "threads/Thread.h"
 #include "threads/CriticalSection.h"
+#include "threads/Event.h"
 #include "SlideShowPicture.h"
 #include "DllImageLib.h"
 #include "SortFileItem.h"
@@ -51,7 +52,7 @@ private:
   int m_maxWidth;
   int m_maxHeight;
 
-  HANDLE m_loadPic;
+  CEvent m_loadPic;
   bool m_isLoading;
 
   CGUIWindowSlideShow *m_pCallback;
index f1f01a1..561ccc1 100644 (file)
 
 #include "Event.h"
 
+class CountGuard
+{
+  unsigned int& count;
+public:
+  inline CountGuard(unsigned int& count_) : count(count_) { count++; }
+  inline ~CountGuard() { count--; }
+};
+
 void CEvent::Interrupt() 
 { 
   CSingleLock lock(mutex);
@@ -32,19 +40,18 @@ void CEvent::Interrupt()
 bool CEvent::Wait()
 {
   CSingleLock lock(mutex);
-  numWaits++;
-  interrupted = false;
-  Guard g(interruptible ? this : NULL);
+  { CountGuard cg(numWaits);
+    interrupted = false;
+    Guard g(interruptible ? this : NULL);
 
-  while (!signaled && !interrupted)
-    condVar.wait(mutex);
+    while (!signaled && !interrupted)
+      condVar.wait(mutex);
+  }
 
   bool ret = signaled;
 
-  numWaits--;
   if (!manualReset && numWaits == 0)
     signaled = false;
-
   return ret;
 }
 
@@ -52,35 +59,34 @@ bool CEvent::WaitMSec(unsigned int milliSeconds)
 {
 
   CSingleLock lock(mutex);
-  numWaits++;
-  interrupted = false;
-  Guard g(interruptible ? this : NULL);
+  { CountGuard cg(numWaits);
+    interrupted = false;
+    Guard g(interruptible ? this : NULL);
 
-  long remainingTime = (long)milliSeconds;
+    long remainingTime = (long)milliSeconds;
 
-  boost::system_time const timeout=boost::get_system_time() + boost::posix_time::milliseconds(milliSeconds);
+    boost::system_time const timeout=boost::get_system_time() + boost::posix_time::milliseconds(milliSeconds);
 
-  while(!signaled && !interrupted)
-  {
-    XbmcThreads::ConditionVariable::TimedWaitResponse resp = condVar.wait(mutex,(unsigned int)remainingTime);
+    while(!signaled && !interrupted)
+    {
+      XbmcThreads::ConditionVariable::TimedWaitResponse resp = condVar.wait(mutex,(unsigned int)remainingTime);
 
-    if (signaled)
-      return true;
+      if (signaled)
+        return true;
 
-    if (resp == XbmcThreads::ConditionVariable::TW_TIMEDOUT)
-      return false;
+      if (resp == XbmcThreads::ConditionVariable::TW_TIMEDOUT)
+        return false;
 
-    boost::posix_time::time_duration diff = timeout - boost::get_system_time();
+      boost::posix_time::time_duration diff = timeout - boost::get_system_time();
 
-    remainingTime = diff.total_milliseconds();
+      remainingTime = diff.total_milliseconds();
 
-    if (remainingTime <= 0)
-      return false;
+      if (remainingTime <= 0)
+        return false;
+    }
   }
 
   bool ret = signaled;
-
-  numWaits--;
   if (!manualReset && numWaits == 0)
     signaled = false;
 
@@ -175,12 +181,45 @@ namespace XbmcThreads
   CEvent* CEventGroup::wait()
   {
     CSingleLock lock(mutex);
-    numWaits++;
-    while (!signaled)
-      condVar.wait(mutex);
+    { CountGuard cg(numWaits);
+      while (!signaled)
+        condVar.wait(mutex);
+    }
+    CEvent* ret = signaled;
+    if (numWaits == 0)
+      signaled = NULL;
+
+    return ret;
+  }
+
+  CEvent* CEventGroup::wait(unsigned int milliSeconds)
+  {
+    CSingleLock lock(mutex);
+    { CountGuard cg(numWaits);
+      long remainingTime = (long)milliSeconds;
+
+      boost::system_time const timeout=boost::get_system_time() + boost::posix_time::milliseconds(milliSeconds);
+
+      while(!signaled)
+      {
+        XbmcThreads::ConditionVariable::TimedWaitResponse resp = condVar.wait(mutex,(unsigned int)remainingTime);
+
+        if (signaled)
+          return signaled;
+
+        if (resp == XbmcThreads::ConditionVariable::TW_TIMEDOUT)
+          return NULL;
+
+        boost::posix_time::time_duration diff = timeout - boost::get_system_time();
+
+        remainingTime = diff.total_milliseconds();
+
+        if (remainingTime <= 0)
+          return NULL;
+      }
+    }
 
     CEvent* ret = signaled;
-    numWaits--;
     if (numWaits == 0)
       signaled = NULL;
 
index ff995e1..6e5f08f 100644 (file)
@@ -138,5 +138,13 @@ namespace XbmcThreads
      * returned.
      */
     CEvent* wait();
+
+    /**
+     * This will block until any one of the CEvents in the group are
+     * signaled or the timeout is reachec. If an event is signaled then
+     * it will return a pointer to that CEvent, otherwise it will return
+     * NULL.
+     */
+    CEvent* wait(unsigned int milliseconds);
   };
 }
diff --git a/xbmc/threads/test/Makefile b/xbmc/threads/test/Makefile
new file mode 100644 (file)
index 0000000..1534102
--- /dev/null
@@ -0,0 +1,13 @@
+SRCS=TestEvent.cpp
+
+LIB=threadTest.a
+
+bin : threadTest .PHONY
+
+include ../../../Makefile.include
+-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS)))
+
+threadTest: $(LIB)
+       $(CXX) $(CXXFLAGS) $(LDFLAGS) -o threadTest $(LIB) ../threads.a ../../utils/utils.a -lboost_unit_test_framework -lboost_thread
+
+
diff --git a/xbmc/threads/test/TestEvent.cpp b/xbmc/threads/test/TestEvent.cpp
new file mode 100644 (file)
index 0000000..74054ae
--- /dev/null
@@ -0,0 +1,283 @@
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE TestEvent
+#include <boost/test/unit_test.hpp>
+
+#include "threads/Event.h"
+
+#include <boost/thread/thread.hpp>
+#include <stdio.h>
+
+using namespace XbmcThreads;
+
+//=============================================================================
+// Helper classes
+//=============================================================================
+
+class waiter
+{
+  CEvent& event;
+public:
+  bool& result;
+
+  volatile bool waiting;
+
+  waiter(CEvent& o, bool& flag) : event(o), result(flag), waiting(false) {}
+  
+  void operator()()
+  {
+    waiting = true;
+    result = event.Wait();
+    waiting = false;
+  }
+};
+
+class timed_waiter
+{
+  CEvent& event;
+  unsigned int waitTime;
+public:
+  int& result;
+
+  volatile bool waiting;
+
+  timed_waiter(CEvent& o, int& flag, int waitTimeMillis) : event(o), waitTime(waitTimeMillis), result(flag), waiting(false) {}
+  
+  void operator()()
+  {
+    waiting = true;
+    result = 0;
+    result = event.WaitMSec(waitTime) ? 1 : -1;
+    waiting = false;
+  }
+};
+
+class group_wait
+{
+  CEventGroup& event;
+public:
+  CEvent* result;
+  bool waiting;
+
+  group_wait(CEventGroup& o) : event(o), result(NULL), waiting(false) {}
+
+  void operator()()
+  {
+    waiting = true;
+    result = event.wait();
+    waiting = false;
+  }
+};
+
+static void Sleep(unsigned int millis) { boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(millis)); }
+
+//=============================================================================
+
+BOOST_AUTO_TEST_CASE(TestEventCase)
+{
+  CEvent event;
+  bool result = false;
+  waiter w1(event,result);
+  boost::thread waitThread(w1);
+
+  Sleep(100);
+
+  BOOST_CHECK(!result);
+
+  event.Set();
+
+  Sleep(10);
+
+  BOOST_CHECK(result);
+}
+
+BOOST_AUTO_TEST_CASE(TestEvent2WaitsCase)
+{
+  CEvent event;
+  bool result1 = false;
+  bool result2 = false;
+  waiter w1(event,result1);
+  waiter w2(event,result2);
+  boost::thread waitThread1(w1);
+  boost::thread waitThread2(w2);
+
+  Sleep(100);
+
+  BOOST_CHECK(!result1);
+  BOOST_CHECK(!result2);
+
+  event.Set();
+
+  Sleep(10);
+
+  BOOST_CHECK(result1);
+  BOOST_CHECK(result2);
+}
+
+BOOST_AUTO_TEST_CASE(TestEventTimedWaitsCase)
+{
+  CEvent event;
+  int result1 = 10;
+  timed_waiter w1(event,result1,100);
+  boost::thread waitThread1(w1);
+
+  Sleep(10);
+
+  BOOST_CHECK(result1 == 0);
+
+  event.Set();
+
+  Sleep(10);
+
+  BOOST_CHECK(result1 == 1);
+}
+
+BOOST_AUTO_TEST_CASE(TestEventTimedWaitsTimeoutCase)
+{
+  CEvent event;
+  int result1 = 10;
+  timed_waiter w1(event,result1,100);
+  boost::thread waitThread1(w1);
+
+  Sleep(10);
+
+  BOOST_CHECK(result1 == 0);
+
+  Sleep(150);
+
+  BOOST_CHECK(result1 == -1);
+}
+
+BOOST_AUTO_TEST_CASE(TestEventGroupCase)
+{
+  CEvent event1;
+  CEvent event2;
+
+  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(100);
+
+  BOOST_CHECK(!result1);
+  BOOST_CHECK(!result2);
+
+  BOOST_CHECK(w3.waiting);
+  BOOST_CHECK(w3.result == NULL);
+
+  event1.Set();
+
+  Sleep(10);
+
+  BOOST_CHECK(result1);
+  BOOST_CHECK(!w1.waiting);
+  BOOST_CHECK(!result2);
+  BOOST_CHECK(w2.waiting);
+  BOOST_CHECK(!w3.waiting);
+  BOOST_CHECK(w3.result == &event1);
+
+  event2.Set();
+
+  Sleep(100);
+}
+
+BOOST_AUTO_TEST_CASE(TestEventGroupLimitedGroupScopeCase)
+{
+  CEvent event1;
+  CEvent event2;
+
+  {
+    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(100);
+
+    BOOST_CHECK(!result1);
+    BOOST_CHECK(!result2);
+
+    BOOST_CHECK(w3.waiting);
+    BOOST_CHECK(w3.result == NULL);
+
+    event1.Set();
+
+    Sleep(10);
+
+    BOOST_CHECK(result1);
+    BOOST_CHECK(!w1.waiting);
+    BOOST_CHECK(!result2);
+    BOOST_CHECK(w2.waiting);
+    BOOST_CHECK(!w3.waiting);
+    BOOST_CHECK(w3.result == &event1);
+  }
+
+  event2.Set();
+
+  Sleep(100);
+}
+
+BOOST_AUTO_TEST_CASE(TestEvent2GroupsCase)
+{
+  CEvent event1;
+  CEvent event2;
+
+  CEventGroup group1(2, &event1,&event2);
+  CEventGroup group2(&event1,&event2,NULL);
+
+  bool result1 = false;
+  bool result2 = false;
+
+  waiter w1(event1,result1);
+  waiter w2(event2,result2);
+  group_wait w3(group1);
+  group_wait w4(group2);
+
+  boost::thread waitThread1(boost::ref(w1));
+  boost::thread waitThread2(boost::ref(w2));
+  boost::thread waitThread3(boost::ref(w3));
+  boost::thread waitThread4(boost::ref(w4));
+
+  Sleep(100);
+
+  BOOST_CHECK(!result1);
+  BOOST_CHECK(!result2);
+
+  BOOST_CHECK(w3.waiting);
+  BOOST_CHECK(w3.result == NULL);
+  BOOST_CHECK(w4.waiting);
+  BOOST_CHECK(w4.result == NULL);
+
+  event1.Set();
+
+  Sleep(10);
+
+  BOOST_CHECK(result1);
+  BOOST_CHECK(!w1.waiting);
+  BOOST_CHECK(!result2);
+  BOOST_CHECK(w2.waiting);
+  BOOST_CHECK(!w3.waiting);
+  BOOST_CHECK(w3.result == &event1);
+  BOOST_CHECK(!w4.waiting);
+  BOOST_CHECK(w4.result == &event1);
+
+  event2.Set();
+
+  Sleep(100);
+}