UtiLite
0.3.1
A lite utilities library
|
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 "utilite/Win32/UWin32.h" 00032 #define SEM_VALUE_MAX ((int) ((~0u) >> 1)) 00033 #else 00034 #include <pthread.h> 00035 #endif 00036 00053 class USemaphore 00054 { 00055 public: 00060 USemaphore( int initValue = 0 ) 00061 { 00062 #ifdef WIN32 00063 S = CreateSemaphore(0,initValue,SEM_VALUE_MAX,0); 00064 #else 00065 _available = initValue; 00066 pthread_mutex_init(&_waitMutex, NULL); 00067 pthread_cond_init(&_cond, NULL); 00068 #endif 00069 } 00070 00071 virtual ~USemaphore() 00072 { 00073 #ifdef WIN32 00074 CloseHandle(S); 00075 #else 00076 pthread_cond_destroy(&_cond); 00077 pthread_mutex_destroy(&_waitMutex); 00078 #endif 00079 } 00080 00087 #ifdef WIN32 00088 void acquire(int n = 1) const 00089 { 00090 while(n-- > 0) 00091 { 00092 WaitForSingleObject((HANDLE)S,INFINITE); 00093 } 00094 #else 00095 void acquire(int n = 1) 00096 { 00097 pthread_mutex_lock(&_waitMutex); 00098 while (n > _available) 00099 { 00100 while(1) 00101 { 00102 pthread_cond_wait(&_cond, &_waitMutex); 00103 break; 00104 } 00105 } 00106 _available -= n; 00107 pthread_mutex_unlock(&_waitMutex); 00108 #endif 00109 } 00110 00111 /* 00112 * Try to acquire the semaphore, not a blocking call. 00113 * @return false if the semaphore can't be taken without waiting (value <= 0), true otherwise 00114 */ 00115 #ifdef WIN32 00116 int acquireTry() const 00117 { 00118 return ((WaitForSingleObject((HANDLE)S,INFINITE)==WAIT_OBJECT_0)?0:EAGAIN); 00119 #else 00120 int acquireTry(int n) 00121 { 00122 pthread_mutex_lock(&_waitMutex); 00123 if(n > _available) 00124 { 00125 pthread_mutex_unlock(&_waitMutex); 00126 return false; 00127 } 00128 _available -= n; 00129 pthread_mutex_unlock(&_waitMutex); 00130 return true; 00131 #endif 00132 } 00133 00138 #ifdef WIN32 00139 int release(int n = 1) const 00140 { 00141 return (ReleaseSemaphore((HANDLE)S,n,0)?0:ERANGE); 00142 #else 00143 void release(int n = 1) 00144 { 00145 pthread_mutex_lock(&_waitMutex); 00146 _available += n; 00147 pthread_cond_broadcast(&_cond); 00148 pthread_mutex_unlock(&_waitMutex); 00149 #endif 00150 } 00151 00156 #ifdef WIN32 00157 int value() const 00158 { 00159 LONG V = -1; ReleaseSemaphore((HANDLE)S,0,&V); return V; 00160 #else 00161 int value() 00162 { 00163 int value = 0; 00164 pthread_mutex_lock(&_waitMutex); 00165 value = _available; 00166 pthread_mutex_unlock(&_waitMutex); 00167 return value; 00168 #endif 00169 } 00170 00171 #ifdef WIN32 00172 /* 00173 * Reset the semaphore count. 00174 * @param init the initial value 00175 * TODO implement on posix ? 00176 */ 00177 void reset( int init = 0 ) 00178 { 00179 CloseHandle(S); 00180 S = CreateSemaphore(0,init,SEM_VALUE_MAX,0); 00181 } 00182 #endif 00183 00184 private: 00185 #ifdef WIN32 00186 HANDLE S; 00187 #else 00188 pthread_mutex_t _waitMutex; 00189 pthread_cond_t _cond; 00190 int _available; 00191 #endif 00192 void operator=(const USemaphore &S){} 00193 USemaphore(const USemaphore &S){} 00194 }; 00195 00196 #endif // USEMAPHORE_H