Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

Synchronization.cpp

Go to the documentation of this file.
00001 #include "Synchronization.h"
00002 
00003 #ifdef LINUX
00004 #include <pthread.h>
00005 #include <sys/timeb.h>
00006 #include <errno.h>
00007 #endif
00008 #include <assert.h>
00009 namespace rwil {
00010 #ifdef LINUX
00011   void *StartThread(void * threadObject)
00012   {
00013     Thread * thread = (Thread *)threadObject;
00014     thread->Go();
00015     return NULL;
00016   }
00017 #endif
00018 
00019   Mutex::Mutex()
00020   {
00021 #ifdef _WIN32
00022     m_mutex = CreateMutex(NULL, TRUE, NULL);
00023     if(m_mutex = NULL)
00024       {
00025         throw "Unable to create mutex";
00026       }
00027 #endif
00028 #ifdef LINUX
00029     //m_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
00030     pthread_mutexattr_t attr;
00031     pthread_mutexattr_init(&attr);
00032     attr.__mutexkind= PTHREAD_MUTEX_RECURSIVE_NP;
00033     //  pthread_mutexattr_setkind(&attr, PTHREAD_MUTEX_RECURSIVE);
00034     pthread_mutex_init(&m_mutex, &attr);
00035 #endif
00036   }
00037   Mutex::~Mutex()
00038   {
00039 #ifdef _WIN32
00040     CloseHandle(m_mutex);
00041 #endif
00042 #ifdef LINUX
00043     //while(pthread_mutex_destroy(&m_mutex) == EBUSY)
00044     //          pthread_mutex_unlock(&m_mutex);
00045 #endif
00046   }
00047 #ifdef LINUX
00048   void Mutex::Wait()
00049   {
00050     pthread_mutex_lock(&m_mutex);       
00051   }
00052         
00053   bool Mutex::TryWait()
00054   {
00055     return pthread_mutex_trylock(&m_mutex) == 0;        
00056   }
00057         
00058   void Mutex::Release()
00059   {
00060     pthread_mutex_unlock(&m_mutex);     
00061   }
00062 #endif //LINUX
00063 
00064 #ifdef _WIN32
00065   static bool WaitWithTimeout(int milli)
00066   {
00067   
00068     DWORD dwRet = WaitForSingleObject(m_mutex, milli);
00069   
00070     switch (dwWaitResult) 
00071       {
00072       case WAIT_OBJECT_0: 
00073         break;
00074       
00075         // Cannot get mutex ownership due to time-out.
00076       case WAIT_TIMEOUT: 
00077         return FALSE; 
00078       
00079         // Got ownership of the abandoned mutex object.
00080       case WAIT_ABANDONED: 
00081         break; 
00082       
00083         // Wait Failed
00084       case WAIT_FAILED: 
00085         return FALSE; 
00086       }
00087                 
00088     return TRUE; 
00089 
00090   }
00091 
00092   void Mutex::Wait()
00093   {
00094     while(WaitWithTimeout(INFINITE) == FALSE) {}
00095   }
00096 
00097   bool Mutex::TryWait()
00098   {
00099     return WaitWithTmeout(0);
00100   }
00101 
00102   void Mutex::Release()
00103   {
00104     ReleaseMutex(m_mutex);
00105   }
00106 
00107 #endif // _WIN32
00108 
00109 
00110 
00111   ScopedMutex::ScopedMutex(Mutex & mutex) : m_mutex(mutex) 
00112   { 
00113     m_mutex.Wait();
00114   }
00115   ScopedMutex::~ScopedMutex() 
00116   { 
00117     m_mutex.Release();
00118   }
00119 
00120 
00121   Semaphore::Semaphore(int count) : m_count(count) {}
00122   Semaphore::Semaphore() : m_count(0) {}
00123 
00125   //  They then decrement the count
00126   void Semaphore::Wait()
00127   {
00128     m_mutex.Wait();
00129     while(m_count == 0)
00130       {
00131         m_mutex.Release();
00132 #ifdef _WIN32
00133         Sleep(0);
00134 #endif
00135 #ifdef LINUX
00136         sched_yield();
00137 #endif
00138         m_mutex.Wait();
00139       }
00140     m_count--;
00141     m_mutex.Release();
00142   }
00143 
00144   bool Semaphore::TryWait()
00145   {
00146     m_mutex.Wait();
00147     if(m_count == 0)
00148       {
00149         return false;
00150       }
00151     m_count--;
00152     m_mutex.Release();
00153     return true;
00154   }
00155 
00156   bool Semaphore::Wait(int millisecondTimeout)
00157   {
00158 #ifdef _WIN32
00159     int timeout = GetTickCount() + millisecondTimeout;
00160 #endif
00161 #ifdef LINUX
00162     timeb timeout;
00163     ftime(&timeout);
00164     int tempMilli = (int)timeout.millitm + millisecondTimeout;
00165     timeout.time = timeout.time + tempMilli/1000;
00166     timeout.millitm = tempMilli /1000;
00167 #endif
00168     m_mutex.Wait();
00169     while(m_count == 0)
00170       {
00171         m_mutex.Release();
00172 #ifdef _WIN32
00173         Sleep(0);
00174         if(GetTickCount() > timeout) return false;
00175 #endif
00176 #ifdef LINUX
00177         sched_yield();
00178         timeb curtime;
00179         ftime(&curtime);
00180         if((timeout.time <= curtime.time) && (timeout.millitm <= curtime.millitm))
00181           {
00182             return false;
00183           }
00184 #endif
00185         m_mutex.Wait();
00186       }
00187     m_count--;
00188     m_mutex.Release();
00189     return true;
00190   }
00191 
00192   void Semaphore::Signal()
00193   {
00194     m_mutex.Wait();
00195     m_count++;
00196     m_mutex.Release();
00197   }
00198 
00199   Thread::Thread() {}
00200   Thread::~Thread() 
00201   {
00202     m_mutex.Release();
00203   }
00204   void Thread::Start()
00205   {
00206     m_mutex.Wait();
00207 #ifdef _WIN32
00208     m_threadHandle = beginthread(StartThread, 0, this);
00209 #endif
00210 #ifdef LINUX
00211     pthread_create(&m_threadHandle, NULL, StartThread, this);
00212 #endif
00213   }
00214   void Thread::Go()
00215   {
00216     Function();
00217     m_mutex.Release();
00218   }
00219 
00220   void Thread::Yield()
00221   {
00222 #ifdef _WIN32
00223     Sleep(0);
00224 #endif
00225 #ifdef LINUX
00226     sched_yield();
00227 #endif  
00228   }
00229   void Thread::Join()
00230   {
00231     if(pthread_join(m_threadHandle, NULL))
00232       assert(0);
00233   }
00234 }

Generated on Tue Apr 9 13:53:08 2002 for RWIL - Real World Interface Library by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001