USemaphore.h
Go to the documentation of this file.
00001 /*
00002 *  utilite is a cross-platform library with
00003 *  useful utilities for fast and small developing.
00004 *  Copyright (C) 2010  Mathieu Labbe
00005 *
00006 *  utilite is free library: you can redistribute it and/or modify
00007 *  it under the terms of the GNU Lesser General Public License as published by
00008 *  the Free Software Foundation, either version 3 of the License, or
00009 *  (at your option) any later version.
00010 *
00011 *  utilite is distributed in the hope that it will be useful,
00012 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 *  GNU Lesser General Public License for more details.
00015 *
00016 *  You should have received a copy of the GNU Lesser General Public License
00017 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 
00020 /*
00021  * Originally written by Phillip Sitbon
00022  *  Copyright 2003
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          * Try to acquire the semaphore, not a blocking call.
00132          * @return false if the semaphore can't be taken without waiting (value <= 0), true otherwise
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          * Reset the semaphore count.
00196          * @param init the initial value
00197          * TODO implement on posix ?
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


rtabmap
Author(s): Mathieu Labbe
autogenerated on Fri Aug 28 2015 12:51:42