}
if (DataIO.UnpackToMemorySize > -1)
- if (WaitForSingleObject(DataIO.hQuit,1) == WAIT_OBJECT_0)
+ if (DataIO.hQuit->WaitMSec(1))
{
return false;
}
{
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)
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;
}
}
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
{
CurUnpRead = CurUnpStart + iSeekTo - iStartOfFile;
CurUnpWrite = SrcFile->Tell() - iStartOfFile + CurUnpStart;
- ResetEvent(hSeek);
- SetEvent(hSeekDone);
+ hSeek->Reset();
+ hSeekDone->Set();
}
}
if (bRead)
{
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;
class Unpack;
#include "system.h"
+#include "threads/Event.h"
class CGUIDialogProgress;
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;
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;
}
}
while (DestUnpSize>=0)
{
- if (WaitForSingleObject(UnpIO->hQuit,1) == WAIT_OBJECT_0)
+ if (UnpIO->hQuit->WaitMSec(1))
return;
UnpPtr&=MAXWINMASK;
ThreadMessage* pMsg = m_vecMessages.front();
if (pMsg->hWaitEvent)
- SetEvent(pMsg->hWaitEvent);
+ pMsg->hWaitEvent->Set();
delete pMsg;
m_vecMessages.pop();
ThreadMessage* pMsg = m_vecWindowMessages.front();
if (pMsg->hWaitEvent)
- SetEvent(pMsg->hWaitEvent);
+ pMsg->hWaitEvent->Set();
delete pMsg;
m_vecWindowMessages.pop();
{ // 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");
{
if (message.hWaitEvent)
{
- CloseHandle(message.hWaitEvent);
+ delete message.hWaitEvent;
message.hWaitEvent = NULL;
}
return;
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;
}
}
ProcessMessage(pMsg);
if (pMsg->hWaitEvent)
- SetEvent(pMsg->hWaitEvent);
+ pMsg->hWaitEvent->Set();
delete pMsg;
lock.Enter();
ProcessMessage(pMsg);
if (pMsg->hWaitEvent)
- SetEvent(pMsg->hWaitEvent);
+ pMsg->hWaitEvent->Set();
delete pMsg;
lock.Enter();
#include "utils/StdString.h"
#include "guilib/Key.h"
#include "threads/Thread.h"
+#include "threads/Event.h"
#include <queue>
DWORD dwParam2;
CStdString strParam;
std::vector<CStdString> params;
- HANDLE hWaitEvent;
+ CEvent* hWaitEvent;
LPVOID lpVoid;
}
ThreadMessage;
m_sRipBuffer[1].pbtStream = NULL;
m_iCurrentBuffer = 0;
-
- m_hReadEvent = CreateEvent(NULL, false, false, NULL);
- m_hDataReadyEvent = CreateEvent(NULL, false, false, NULL);
}
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;
}
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();
}
}
}
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;
}
#include "FileItem.h"
#include "filesystem/File.h"
+#include "threads/Event.h"
struct RipBuffer
{
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;
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",
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);
{
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;
{
UnInit();
for (int i = 0; i < NUM_BUFFERS; i++)
- CloseHandle(m_eventTexturesDone[i]);
+ delete m_eventTexturesDone[i];
if (m_rgbPbo)
{
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;
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;
if (!(im->flags&IMAGE_FLAG_READY))
{
- SetEvent(m_eventTexturesDone[source]);
+ m_eventTexturesDone[source]->Set();
return;
}
, im->stride[2], im->plane[2] );
}
- SetEvent(m_eventTexturesDone[source]);
+ m_eventTexturesDone[source]->Set();
VerifyGLState();
/* 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();
}
}
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);
}
}
- SetEvent(m_eventTexturesDone[index]);
+ m_eventTexturesDone[index]->Set();
return 0;
}
}
}
glDisable(m_textureTarget);
- SetEvent(m_eventTexturesDone[index]);
+ m_eventTexturesDone[index]->Set();
return true;
}
if (!(im->flags & IMAGE_FLAG_READY))
{
- SetEvent(m_eventTexturesDone[source]);
+ m_eventTexturesDone[source]->Set();
return;
}
, im->stride[1]/2, im->plane[1] );
}
- SetEvent(m_eventTexturesDone[source]);
+ m_eventTexturesDone[source]->Set();
VerifyGLState();
}
}
glDisable(m_textureTarget);
- SetEvent(m_eventTexturesDone[index]);
+ m_eventTexturesDone[index]->Set();
return true;
}
glGenTextures(1, &plane.id);
- SetEvent(m_eventTexturesDone[index]);
+ m_eventTexturesDone[index]->Set();
#endif
return true;
}
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
}
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;
}
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
}
if (!(im->flags & IMAGE_FLAG_READY))
{
- SetEvent(m_eventTexturesDone[source]);
+ m_eventTexturesDone[source]->Set();
return;
}
, im->stride[0] / 4, im->plane[0] );
}
- SetEvent(m_eventTexturesDone[source]);
+ m_eventTexturesDone[source]->Set();
VerifyGLState();
VerifyGLState();
}
glDisable(m_textureTarget);
- SetEvent(m_eventTexturesDone[index]);
+ m_eventTexturesDone[index]->Set();
return true;
}
if (!(im->flags&IMAGE_FLAG_READY))
{
- SetEvent(m_eventTexturesDone[source]);
+ m_eventTexturesDone[source]->Set();
return;
}
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)
#include "guilib/GraphicContext.h"
#include "BaseRenderer.h"
+#include "threads/Event.h"
+
class CRenderCapture;
class CVDPAU;
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);
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
{
UnInit();
for (int i = 0; i < NUM_BUFFERS; i++)
- CloseHandle(m_eventTexturesDone[i]);
+ delete m_eventTexturesDone[i];
if (m_rgbBuffer != NULL) {
delete [] m_rgbBuffer;
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;
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;
/* 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();
}
}
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);
}
}
- SetEvent(m_eventTexturesDone[index]);
+ m_eventTexturesDone[index]->Set();
return 0;
}
if (!(im->flags&IMAGE_FLAG_READY))
#endif
{
- SetEvent(m_eventTexturesDone[source]);
+ m_eventTexturesDone[source]->Set();
return;
}
, im->stride[2], im->plane[2] );
}
}
- SetEvent(m_eventTexturesDone[source]);
+ m_eventTexturesDone[source]->Set();
CalculateTextureSourceRects(source, 3);
}
}
glDisable(m_textureTarget);
- SetEvent(m_eventTexturesDone[index]);
+ m_eventTexturesDone[index]->Set();
return true;
}
plane.flipindex = m_buffers[index].flipindex;
}
- SetEvent(m_eventTexturesDone[index]);
+ m_eventTexturesDone[index]->Set();
#endif
}
void CLinuxRendererGLES::DeleteCVRefTexture(int index)
glBindTexture(m_textureTarget, 0);
glDisable(m_textureTarget);
- SetEvent(m_eventTexturesDone[index]);
+ m_eventTexturesDone[index]->Set();
#endif
return true;
}
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];
};
using namespace std;
-CDVDMessageQueue::CDVDMessageQueue(const string &owner)
+CDVDMessageQueue::CDVDMessageQueue(const string &owner) : m_hEvent(true)
{
m_owner = owner;
m_iDataSize = 0;
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()
m_bAbortRequest = true;
- SetEvent(m_hEvent); // inform waiter for abort action
+ m_hEvent.Set(); // inform waiter for abort action
}
void CDVDMessageQueue::End()
pMsg->Release();
- SetEvent(m_hEvent); // inform waiter for new packet
+ m_hEvent.Set(); // inform waiter for new packet
return MSGQ_OK;
}
}
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();
#include <string>
#include <list>
#include "threads/CriticalSection.h"
+#include "threads/Event.h"
struct DVDMessageListItem
{
private:
- HANDLE m_hEvent;
+ CEvent m_hEvent;
mutable CCriticalSection m_section;
bool m_bAbortRequest;
{
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())
void CSimpleFileCache::Close()
{
if (m_hDataAvailEvent)
- CloseHandle(m_hDataAvailEvent);
+ delete m_hDataAvailEvent;
m_hDataAvailEvent = NULL;
}
// when reader waits for data it will wait on the event.
- SetEvent(m_hDataAvailEvent);
+ m_hDataAvailEvent->Set();
m_nWritePosition += iWritten;
return iWritten;
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;
}
void CSimpleFileCache::EndOfInput()
{
CCacheStrategy::EndOfInput();
- SetEvent(m_hDataAvailEvent);
+ m_hDataAvailEvent->Set();
}
}
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;
#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)
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()
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
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;
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;
}
}
- SetEvent(m_pExtract->GetDataIO().hBufferEmpty);
+ m_pExtract->GetDataIO().hBufferEmpty->Set();
return static_cast<unsigned int>(uiBufSize-uicBufSize);
#else
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)
{
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;
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;
#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)
{
#include "File.h"
#include "UnrarXLib/rar.hpp"
#include "threads/Thread.h"
+#include "threads/Event.h"
namespace XFILE
{
virtual void OnExit();
virtual void Process();
- HANDLE hRunning;
- HANDLE hRestart;
- HANDLE hQuit;
+ CEvent hRunning;
+ CEvent hRestart;
+ CEvent hQuit;
protected:
Archive* m_pArc;
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;
}
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
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)
{
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;
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;
*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)
#include "addons/IAddon.h"
#include "PlatformDefs.h"
+#include "threads/Event.h"
+
class CURL;
class CFileItemList;
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
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();
XBPython::~XBPython()
{
- CloseHandle(m_globalEvent);
}
// message all registered callbacks that xbmc stopped playing
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
void Process();
void PulseGlobalEvent();
- void WaitForEvent(HANDLE hEvent, unsigned int timeout);
+ void WaitForEvent(CEvent& hEvent, unsigned int timeout);
int ScriptsSize();
int GetPythonScriptId(int scriptPosition);
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;
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)
}
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)
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();
}
*/
#include "guilib/GUIWindow.h"
+#include "threads/Event.h"
class PyXBMCAction
{
protected:
void* pCallbackWindow;
void* m_threadState;
- HANDLE m_actionEvent;
+ CEvent m_actionEvent;
};
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)
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 */)
#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);
void SetupShares();
void* pCallbackWindow;
void* m_threadState;
- HANDLE m_actionEvent;
+ CEvent m_actionEvent;
bool m_bRunning;
CStdString m_scriptPath;
CStdString m_mediaDir;
#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
void GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer);
-DWORD WINAPI WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds );
-DWORD WINAPI WaitForMultipleObjects( DWORD nCount, HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds);
-
#endif
#endif
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;
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);
//get more tracks
if (ThreadHandle() != NULL)
{
- SetEvent(m_hWorkerEvent);
+ m_hWorkerEvent.Set();
}
}
}
while (!m_bStop)
{
- WaitForSingleObject(m_hWorkerEvent, INFINITE);
+ m_hWorkerEvent.Wait();
if (m_bStop)
break;
int iNrCachedTracks = m_RadioTrackQueue->size();
if (m_ThreadHandle)
{
m_bStop = true;
- SetEvent(m_hWorkerEvent);
+ m_hWorkerEvent.Set();
StopThread();
}
m_CurrentSong.CurrentSong = NULL;
#include "threads/CriticalSection.h"
#include "threads/Thread.h"
+#include "threads/Event.h"
#include "PlayListPlayer.h"
namespace PLAYLIST
LastFmManagerSong m_CurrentSong;
PLAYLIST::CPlayList* m_RadioTrackQueue;
- HANDLE m_hWorkerEvent;
+ CEvent m_hWorkerEvent;
CCriticalSection m_lockCache;
CCriticalSection m_lockPlaylist;
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()
CSingleLock lock(m_actionLock);
m_action = SCROBBLER_ACTION_NOWPLAYING;
}
- SetEvent(m_hEvent);
+ m_hEvent.Set();
return;
}
CSingleLock lock(m_actionLock);
m_action = SCROBBLER_ACTION_SUBMIT;
}
- SetEvent(m_hEvent);
+ m_hEvent.Set();
}
}
}
while (!m_bStop)
{
- WaitForSingleObject(m_hEvent, INFINITE);
- if (m_bStop)
+ m_hEvent.Wait();
+ if (m_bStop)
break;
if (m_strSessionID.IsEmpty())
#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
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;
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)
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)
{
m_maxWidth = maxWidth;
m_maxHeight = maxHeight;
m_isLoading = true;
- SetEvent(m_loadPic);
+ m_loadPic.Set();
}
CGUIWindowSlideShow::CGUIWindowSlideShow(void)
#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"
int m_maxWidth;
int m_maxHeight;
- HANDLE m_loadPic;
+ CEvent m_loadPic;
bool m_isLoading;
CGUIWindowSlideShow *m_pCallback;
#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);
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;
}
{
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;
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;
* 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);
};
}
--- /dev/null
+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
+
+
--- /dev/null
+#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);
+}