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 if(rt == 0)
00125 {
00126
00127 _available -= n;
00128 }
00129 pthread_mutex_unlock(&_waitMutex);
00130 return rt == 0;
00131 }
00132 #endif
00133
00134
00135
00136
00137
00138 #ifdef _WIN32
00139 int acquireTry() const
00140 {
00141 return ((WaitForSingleObject((HANDLE)S,INFINITE)==WAIT_OBJECT_0)?0:EAGAIN);
00142 }
00143 #else
00144 int acquireTry(int n)
00145 {
00146 pthread_mutex_lock(&_waitMutex);
00147 if(n > _available)
00148 {
00149 pthread_mutex_unlock(&_waitMutex);
00150 return false;
00151 }
00152 _available -= n;
00153 pthread_mutex_unlock(&_waitMutex);
00154 return true;
00155 }
00156 #endif
00157
00162 #ifdef _WIN32
00163 int release(int n = 1) const
00164 {
00165 return (ReleaseSemaphore((HANDLE)S,n,0)?0:ERANGE);
00166 }
00167 #else
00168 void release(int n = 1)
00169 {
00170 pthread_mutex_lock(&_waitMutex);
00171 _available += n;
00172 pthread_cond_broadcast(&_cond);
00173 pthread_mutex_unlock(&_waitMutex);
00174 }
00175 #endif
00176
00181 #ifdef _WIN32
00182 int value() const
00183 {
00184 LONG V = -1; ReleaseSemaphore((HANDLE)S,0,&V); return V;
00185 }
00186 #else
00187 int value()
00188 {
00189 int value = 0;
00190 pthread_mutex_lock(&_waitMutex);
00191 value = _available;
00192 pthread_mutex_unlock(&_waitMutex);
00193 return value;
00194 }
00195 #endif
00196
00197 #ifdef _WIN32
00198
00199
00200
00201
00202
00203 void reset( int init = 0 )
00204 {
00205 CloseHandle(S);
00206 S = CreateSemaphore(0,init,SEM_VALUE_MAX,0);
00207 }
00208 #endif
00209
00210 private:
00211 void operator=(const USemaphore &S){}
00212 #ifdef _WIN32
00213 USemaphore(const USemaphore &S){}
00214 HANDLE S;
00215 #else
00216 USemaphore(const USemaphore &S):_available(0){}
00217 pthread_mutex_t _waitMutex;
00218 pthread_cond_t _cond;
00219 int _available;
00220 #endif
00221 };
00222
00223 #endif // USEMAPHORE_H