Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef USEMAPHORE_H
00026 #define USEMAPHORE_H
00027
00028 #include <errno.h>
00029
00030 #ifdef _WIN32
00031 #include "rtabmap/utilite/Win32/UWin32.h"
00032 #define SEM_VALUE_MAX ((int) ((~0u) >> 1))
00033 #else
00034 #include <pthread.h>
00035 #include <sys/time.h>
00036 #endif
00037
00054 class USemaphore
00055 {
00056 public:
00061 USemaphore( int initValue = 0 )
00062 {
00063 #ifdef _WIN32
00064 S = CreateSemaphore(0,initValue,SEM_VALUE_MAX,0);
00065 #else
00066 _available = initValue;
00067 pthread_mutex_init(&_waitMutex, NULL);
00068 pthread_cond_init(&_cond, NULL);
00069 #endif
00070 }
00071
00072 virtual ~USemaphore()
00073 {
00074 #ifdef _WIN32
00075 CloseHandle(S);
00076 #else
00077 pthread_cond_destroy(&_cond);
00078 pthread_mutex_destroy(&_waitMutex);
00079 #endif
00080 }
00081
00090 #ifdef _WIN32
00091 bool acquire(int n = 1, int ms = 0) const
00092 {
00093 int rt = 0;
00094 while(n-- > 0 && rt==0)
00095 {
00096 rt = WaitForSingleObject((HANDLE)S, ms<=0?INFINITE:ms);
00097 }
00098 return rt == 0;
00099 }
00100 #else
00101 bool acquire(int n = 1, int ms = 0)
00102 {
00103 int rt = 0;
00104 pthread_mutex_lock(&_waitMutex);
00105 while (n > _available && rt == 0)
00106 {
00107 if(ms > 0)
00108 {
00109 struct timespec timeToWait;
00110 struct timeval now;
00111
00112 gettimeofday(&now,NULL);
00113
00114 timeToWait.tv_sec = now.tv_sec + ms/1000;
00115 timeToWait.tv_nsec = (now.tv_usec+1000UL*(ms%1000))*1000UL;
00116
00117 rt = pthread_cond_timedwait(&_cond, &_waitMutex, &timeToWait);
00118 }
00119 else
00120 {
00121 rt = pthread_cond_wait(&_cond, &_waitMutex);
00122 }
00123 }
00124 _available -= n;
00125 pthread_mutex_unlock(&_waitMutex);
00126 return rt == 0;
00127 }
00128 #endif
00129
00130
00131
00132
00133
00134 #ifdef _WIN32
00135 int acquireTry() const
00136 {
00137 return ((WaitForSingleObject((HANDLE)S,INFINITE)==WAIT_OBJECT_0)?0:EAGAIN);
00138 }
00139 #else
00140 int acquireTry(int n)
00141 {
00142 pthread_mutex_lock(&_waitMutex);
00143 if(n > _available)
00144 {
00145 pthread_mutex_unlock(&_waitMutex);
00146 return false;
00147 }
00148 _available -= n;
00149 pthread_mutex_unlock(&_waitMutex);
00150 return true;
00151 }
00152 #endif
00153
00158 #ifdef _WIN32
00159 int release(int n = 1) const
00160 {
00161 return (ReleaseSemaphore((HANDLE)S,n,0)?0:ERANGE);
00162 }
00163 #else
00164 void release(int n = 1)
00165 {
00166 pthread_mutex_lock(&_waitMutex);
00167 _available += n;
00168 pthread_cond_broadcast(&_cond);
00169 pthread_mutex_unlock(&_waitMutex);
00170 }
00171 #endif
00172
00177 #ifdef _WIN32
00178 int value() const
00179 {
00180 LONG V = -1; ReleaseSemaphore((HANDLE)S,0,&V); return V;
00181 }
00182 #else
00183 int value()
00184 {
00185 int value = 0;
00186 pthread_mutex_lock(&_waitMutex);
00187 value = _available;
00188 pthread_mutex_unlock(&_waitMutex);
00189 return value;
00190 }
00191 #endif
00192
00193 #ifdef _WIN32
00194
00195
00196
00197
00198
00199 void reset( int init = 0 )
00200 {
00201 CloseHandle(S);
00202 S = CreateSemaphore(0,init,SEM_VALUE_MAX,0);
00203 }
00204 #endif
00205
00206 private:
00207 void operator=(const USemaphore &S){}
00208 #ifdef _WIN32
00209 USemaphore(const USemaphore &S){}
00210 HANDLE S;
00211 #else
00212 USemaphore(const USemaphore &S):_available(0){}
00213 pthread_mutex_t _waitMutex;
00214 pthread_cond_t _cond;
00215 int _available;
00216 #endif
00217 };
00218
00219 #endif // USEMAPHORE_H