• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

SignaledEvent.cpp

Go to the documentation of this file.
00001 #include "SignaledEvent.h"
00002 #include "RakAssert.h"
00003 #include "RakSleep.h"
00004 
00005 #if defined(__GNUC__) 
00006 #include <sys/time.h>
00007 #include <unistd.h>
00008 #endif
00009 
00010 SignaledEvent::SignaledEvent()
00011 {
00012 #ifdef _WIN32
00013         eventList=INVALID_HANDLE_VALUE;
00014 #else
00015         isSignaled=false;
00016 #endif
00017 }
00018 SignaledEvent::~SignaledEvent()
00019 {
00020         // Intentionally do not close event, so it doesn't close twice on linux
00021 }
00022 
00023 void SignaledEvent::InitEvent(void)
00024 {
00025 #ifdef _WIN32
00026                 eventList=CreateEvent(0, false, false, 0);
00027 #else
00028                 pthread_condattr_init( &condAttr );
00029                 pthread_cond_init(&eventList, &condAttr);
00030                 pthread_mutexattr_init( &mutexAttr      );
00031                 pthread_mutex_init(&hMutex, &mutexAttr);
00032 #endif
00033 }
00034 
00035 void SignaledEvent::CloseEvent(void)
00036 {
00037 #ifdef _WIN32
00038         if (eventList!=INVALID_HANDLE_VALUE)
00039         {
00040                 CloseHandle(eventList);
00041                 eventList=INVALID_HANDLE_VALUE;
00042         }
00043 #else
00044         pthread_cond_destroy(&eventList);
00045         pthread_mutex_destroy(&hMutex);
00046         pthread_condattr_destroy( &condAttr );
00047         pthread_mutexattr_destroy( &mutexAttr );
00048 #endif
00049 }
00050 
00051 void SignaledEvent::SetEvent(void)
00052 {
00053 #ifdef _WIN32
00054 	::SetEvent(eventList);
00055 #else
00056         // Different from SetEvent which stays signaled.
00057         // We have to record manually that the event was signaled
00058         isSignaledMutex.Lock();
00059         isSignaled=true;
00060         isSignaledMutex.Unlock();
00061 
00062         // Unblock waiting threads
00063         pthread_cond_broadcast(&eventList);
00064 #endif
00065 }
00066 
00067 void SignaledEvent::WaitOnEvent(int timeoutMs)
00068 {
00069 #ifdef _WIN32
00070 //      WaitForMultipleObjects(
00071 //              2,
00072 //              eventList,
00073 //              false,
00074 //              timeoutMs);
00075         WaitForSingleObject(eventList,timeoutMs);
00076 #else
00077 
00078         // If was previously set signaled, just unset and return
00079         isSignaledMutex.Lock();
00080         if (isSignaled==true)
00081         {
00082                 isSignaled=false;
00083                 isSignaledMutex.Unlock();
00084                 return;
00085         }
00086         isSignaledMutex.Unlock();
00087 
00088         
00089         struct timespec   ts;
00090 
00091         // Else wait for SetEvent to be called
00092 #if defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3)
00093                                                                                                                                                                                                                                                                                                                                       
00094         #else
00095                 int rc;
00096                 struct timeval    tp;
00097                 rc =  gettimeofday(&tp, NULL);
00098                 ts.tv_sec  = tp.tv_sec;
00099                 ts.tv_nsec = tp.tv_usec * 1000;
00100         #endif
00101 
00102                 while (timeoutMs > 30)
00103                 {
00104                         // Wait 30 milliseconds for the signal, then check again.
00105                         // 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
00106                         ts.tv_nsec += 30*1000000;
00107                         if (ts.tv_nsec >= 1000000000)
00108                         {
00109                                 ts.tv_nsec -= 1000000000;
00110                                 ts.tv_sec++;
00111                         }
00112                         pthread_cond_timedwait(&eventList, &hMutex, &ts);
00113                         timeoutMs-=30;
00114 
00115                         isSignaledMutex.Lock();
00116                         if (isSignaled==true)
00117                         {
00118                                 isSignaled=false;
00119                                 isSignaledMutex.Unlock();
00120                                 return;
00121                         }
00122                         isSignaledMutex.Unlock();
00123                 }
00124 
00125                 // Wait the remaining time, and turn off the signal in case it was set
00126                 ts.tv_nsec += timeoutMs*1000000;
00127                 if (ts.tv_nsec >= 1000000000)
00128                 {
00129                         ts.tv_nsec -= 1000000000;
00130                         ts.tv_sec++;
00131                 }
00132                 pthread_cond_timedwait(&eventList, &hMutex, &ts);
00133 
00134                 isSignaledMutex.Lock();
00135                 isSignaled=false;
00136                 isSignaledMutex.Unlock();
00137 #endif
00138 }

Generated on Thu Sep 30 2010 01:27:28 for RakNet by  doxygen 1.7.1