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                 if(rt == 0)
00125                 {
00126                         // only remove them if waiting did not fail
00127                         _available -= n;
00128                 }
00129                 pthread_mutex_unlock(&_waitMutex);
00130                 return rt == 0;
00131         }
00132 #endif
00133 
00134         /*
00135          * Try to acquire the semaphore, not a blocking call.
00136          * @return false if the semaphore can't be taken without waiting (value <= 0), true otherwise
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          * Reset the semaphore count.
00200          * @param init the initial value
00201          * TODO implement on posix ?
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


rtabmap
Author(s): Mathieu Labbe
autogenerated on Sat Jul 23 2016 11:44:28