the whole game
This commit is contained in:
245
project/lib_projects/raknet/jni/RaknetSources/SignaledEvent.cpp
Executable file
245
project/lib_projects/raknet/jni/RaknetSources/SignaledEvent.cpp
Executable file
@@ -0,0 +1,245 @@
|
||||
#include "SignaledEvent.h"
|
||||
#include "RakAssert.h"
|
||||
#include "RakSleep.h"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
using namespace RakNet;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SignaledEvent::SignaledEvent()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
eventList=INVALID_HANDLE_VALUE;
|
||||
|
||||
|
||||
#else
|
||||
isSignaled=false;
|
||||
#endif
|
||||
}
|
||||
SignaledEvent::~SignaledEvent()
|
||||
{
|
||||
// Intentionally do not close event, so it doesn't close twice on linux
|
||||
}
|
||||
|
||||
void SignaledEvent::InitEvent(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
eventList=CreateEvent(0, false, false, 0);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#if !defined(ANDROID)
|
||||
pthread_condattr_init( &condAttr );
|
||||
pthread_cond_init(&eventList, &condAttr);
|
||||
#else
|
||||
pthread_cond_init(&eventList, 0);
|
||||
#endif
|
||||
pthread_mutexattr_init( &mutexAttr );
|
||||
pthread_mutex_init(&hMutex, &mutexAttr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SignaledEvent::CloseEvent(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (eventList!=INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(eventList);
|
||||
eventList=INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#else
|
||||
pthread_cond_destroy(&eventList);
|
||||
pthread_mutex_destroy(&hMutex);
|
||||
#if !defined(ANDROID)
|
||||
pthread_condattr_destroy( &condAttr );
|
||||
#endif
|
||||
pthread_mutexattr_destroy( &mutexAttr );
|
||||
#endif
|
||||
}
|
||||
|
||||
void SignaledEvent::SetEvent(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
::SetEvent(eventList);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#else
|
||||
// Different from SetEvent which stays signaled.
|
||||
// We have to record manually that the event was signaled
|
||||
isSignaledMutex.Lock();
|
||||
isSignaled=true;
|
||||
isSignaledMutex.Unlock();
|
||||
|
||||
// Unblock waiting threads
|
||||
pthread_cond_broadcast(&eventList);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SignaledEvent::WaitOnEvent(int timeoutMs)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// WaitForMultipleObjects(
|
||||
// 2,
|
||||
// eventList,
|
||||
// false,
|
||||
// timeoutMs);
|
||||
WaitForSingleObject(eventList,timeoutMs);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#else
|
||||
|
||||
// If was previously set signaled, just unset and return
|
||||
isSignaledMutex.Lock();
|
||||
if (isSignaled==true)
|
||||
{
|
||||
isSignaled=false;
|
||||
isSignaledMutex.Unlock();
|
||||
return;
|
||||
}
|
||||
isSignaledMutex.Unlock();
|
||||
|
||||
|
||||
struct timespec ts;
|
||||
|
||||
// Else wait for SetEvent to be called
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int rc;
|
||||
struct timeval tp;
|
||||
rc = gettimeofday(&tp, NULL);
|
||||
ts.tv_sec = tp.tv_sec;
|
||||
ts.tv_nsec = tp.tv_usec * 1000;
|
||||
|
||||
|
||||
while (timeoutMs > 30)
|
||||
{
|
||||
// Wait 30 milliseconds for the signal, then check again.
|
||||
// This is in case we missed the signal between the top of this function and pthread_cond_timedwait, or after the end of the loop and pthread_cond_timedwait
|
||||
ts.tv_nsec += 30*1000000;
|
||||
if (ts.tv_nsec >= 1000000000)
|
||||
{
|
||||
ts.tv_nsec -= 1000000000;
|
||||
ts.tv_sec++;
|
||||
}
|
||||
|
||||
// [SBC] added mutex lock/unlock around cond_timedwait.
|
||||
// this prevents airplay from generating a whole much of errors.
|
||||
// not sure how this works on other platforms since according to
|
||||
// the docs you are suppost to hold the lock before you wait
|
||||
// on the cond.
|
||||
pthread_mutex_lock(&hMutex);
|
||||
pthread_cond_timedwait(&eventList, &hMutex, &ts);
|
||||
pthread_mutex_unlock(&hMutex);
|
||||
|
||||
timeoutMs-=30;
|
||||
|
||||
isSignaledMutex.Lock();
|
||||
if (isSignaled==true)
|
||||
{
|
||||
isSignaled=false;
|
||||
isSignaledMutex.Unlock();
|
||||
return;
|
||||
}
|
||||
isSignaledMutex.Unlock();
|
||||
}
|
||||
|
||||
// Wait the remaining time, and turn off the signal in case it was set
|
||||
ts.tv_nsec += timeoutMs*1000000;
|
||||
if (ts.tv_nsec >= 1000000000)
|
||||
{
|
||||
ts.tv_nsec -= 1000000000;
|
||||
ts.tv_sec++;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&hMutex);
|
||||
pthread_cond_timedwait(&eventList, &hMutex, &ts);
|
||||
pthread_mutex_unlock(&hMutex);
|
||||
|
||||
isSignaledMutex.Lock();
|
||||
isSignaled=false;
|
||||
isSignaledMutex.Unlock();
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user