00001 // 00002 // AtomicCounter.h 00003 // 00004 // $Id: //poco/1.3/Foundation/include/Poco/AtomicCounter.h#6 $ 00005 // 00006 // Library: Foundation 00007 // Package: Core 00008 // Module: AtomicCounter 00009 // 00010 // Definition of the AtomicCounter class. 00011 // 00012 // Copyright (c) 2009, Applied Informatics Software Engineering GmbH. 00013 // and Contributors. 00014 // 00015 // Permission is hereby granted, free of charge, to any person or organization 00016 // obtaining a copy of the software and accompanying documentation covered by 00017 // this license (the "Software") to use, reproduce, display, distribute, 00018 // execute, and transmit the Software, and to prepare derivative works of the 00019 // Software, and to permit third-parties to whom the Software is furnished to 00020 // do so, all subject to the following: 00021 // 00022 // The copyright notices in the Software and this entire statement, including 00023 // the above license grant, this restriction and the following disclaimer, 00024 // must be included in all copies of the Software, in whole or in part, and 00025 // all derivative works of the Software, unless such copies or derivative 00026 // works are solely in the form of machine-executable object code generated by 00027 // a source language processor. 00028 // 00029 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00030 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00031 // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 00032 // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 00033 // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 00034 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00035 // DEALINGS IN THE SOFTWARE. 00036 // 00037 00038 00039 #ifndef Foundation_AtomicCounter_INCLUDED 00040 #define Foundation_AtomicCounter_INCLUDED 00041 00042 00043 #include "Poco/Foundation.h" 00044 #if POCO_OS == POCO_OS_WINDOWS_NT 00045 #include "Poco/UnWindows.h" 00046 #elif POCO_OS == POCO_OS_MAC_OS_X 00047 #include <libkern/OSAtomic.h> 00048 #else 00049 #include "Poco/Mutex.h" 00050 #endif // POCO_OS 00051 00052 00053 namespace Poco { 00054 00055 00056 class Foundation_API AtomicCounter 00074 { 00075 public: 00076 typedef int ValueType; 00077 00078 AtomicCounter(); 00080 00081 explicit AtomicCounter(ValueType initialValue); 00084 00085 AtomicCounter(const AtomicCounter& counter); 00087 00088 ~AtomicCounter(); 00090 00091 AtomicCounter& operator = (const AtomicCounter& counter); 00093 00094 AtomicCounter& operator = (ValueType value); 00096 00097 operator ValueType () const; 00099 00100 ValueType value() const; 00102 00103 ValueType operator ++ (); // prefix 00105 00106 ValueType operator ++ (int); // postfix 00108 00109 ValueType operator -- (); // prefix 00111 00112 ValueType operator -- (int); // postfix 00114 00115 bool operator ! () const; 00117 00118 private: 00119 #if POCO_OS == POCO_OS_WINDOWS_NT 00120 typedef volatile LONG ImplType; 00121 #elif POCO_OS == POCO_OS_MAC_OS_X 00122 typedef int32_t ImplType; 00123 #else // generic implementation based on FastMutex 00124 struct ImplType 00125 { 00126 mutable FastMutex mutex; 00127 volatile int value; 00128 }; 00129 #endif // POCO_OS 00130 00131 ImplType _counter; 00132 }; 00133 00134 00135 // 00136 // inlines 00137 // 00138 00139 00140 #if POCO_OS == POCO_OS_WINDOWS_NT 00141 // 00142 // Windows 00143 // 00144 inline AtomicCounter::operator AtomicCounter::ValueType () const 00145 { 00146 return _counter; 00147 } 00148 00149 00150 inline AtomicCounter::ValueType AtomicCounter::value() const 00151 { 00152 return _counter; 00153 } 00154 00155 00156 inline AtomicCounter::ValueType AtomicCounter::operator ++ () // prefix 00157 { 00158 return InterlockedIncrement(&_counter); 00159 } 00160 00161 00162 inline AtomicCounter::ValueType AtomicCounter::operator ++ (int) // postfix 00163 { 00164 ValueType result(_counter); 00165 InterlockedIncrement(&_counter); 00166 return result; 00167 } 00168 00169 00170 inline AtomicCounter::ValueType AtomicCounter::operator -- () // prefix 00171 { 00172 return InterlockedDecrement(&_counter); 00173 } 00174 00175 00176 inline AtomicCounter::ValueType AtomicCounter::operator -- (int) // postfix 00177 { 00178 ValueType result(_counter); 00179 InterlockedDecrement(&_counter); 00180 return result; 00181 } 00182 00183 00184 inline bool AtomicCounter::operator ! () const 00185 { 00186 return _counter == 0; 00187 } 00188 00189 00190 #elif POCO_OS == POCO_OS_MAC_OS_X 00191 // 00192 // Mac OS X 00193 // 00194 inline AtomicCounter::operator AtomicCounter::ValueType () const 00195 { 00196 return _counter; 00197 } 00198 00199 00200 inline AtomicCounter::ValueType AtomicCounter::value() const 00201 { 00202 return _counter; 00203 } 00204 00205 00206 inline AtomicCounter::ValueType AtomicCounter::operator ++ () // prefix 00207 { 00208 return OSAtomicIncrement32(&_counter); 00209 } 00210 00211 00212 inline AtomicCounter::ValueType AtomicCounter::operator ++ (int) // postfix 00213 { 00214 ValueType result(_counter); 00215 OSAtomicIncrement32(&_counter); 00216 return result; 00217 } 00218 00219 00220 inline AtomicCounter::ValueType AtomicCounter::operator -- () // prefix 00221 { 00222 return OSAtomicDecrement32(&_counter); 00223 } 00224 00225 00226 inline AtomicCounter::ValueType AtomicCounter::operator -- (int) // postfix 00227 { 00228 ValueType result(_counter); 00229 OSAtomicDecrement32(&_counter); 00230 return result; 00231 } 00232 00233 00234 inline bool AtomicCounter::operator ! () const 00235 { 00236 return _counter == 0; 00237 } 00238 00239 00240 #else 00241 // 00242 // Generic implementation based on FastMutex 00243 // 00244 inline AtomicCounter::operator AtomicCounter::ValueType () const 00245 { 00246 ValueType result; 00247 { 00248 FastMutex::ScopedLock lock(_counter.mutex); 00249 result = _counter.value; 00250 } 00251 return result; 00252 } 00253 00254 00255 inline AtomicCounter::ValueType AtomicCounter::value() const 00256 { 00257 ValueType result; 00258 { 00259 FastMutex::ScopedLock lock(_counter.mutex); 00260 result = _counter.value; 00261 } 00262 return result; 00263 } 00264 00265 00266 inline AtomicCounter::ValueType AtomicCounter::operator ++ () // prefix 00267 { 00268 ValueType result; 00269 { 00270 FastMutex::ScopedLock lock(_counter.mutex); 00271 result = ++_counter.value; 00272 } 00273 return result; 00274 } 00275 00276 00277 inline AtomicCounter::ValueType AtomicCounter::operator ++ (int) // postfix 00278 { 00279 ValueType result; 00280 { 00281 FastMutex::ScopedLock lock(_counter.mutex); 00282 result = _counter.value++; 00283 } 00284 return result; 00285 } 00286 00287 00288 inline AtomicCounter::ValueType AtomicCounter::operator -- () // prefix 00289 { 00290 ValueType result; 00291 { 00292 FastMutex::ScopedLock lock(_counter.mutex); 00293 result = --_counter.value; 00294 } 00295 return result; 00296 } 00297 00298 00299 inline AtomicCounter::ValueType AtomicCounter::operator -- (int) // postfix 00300 { 00301 ValueType result; 00302 { 00303 FastMutex::ScopedLock lock(_counter.mutex); 00304 result = _counter.value--; 00305 } 00306 return result; 00307 } 00308 00309 00310 inline bool AtomicCounter::operator ! () const 00311 { 00312 bool result; 00313 { 00314 FastMutex::ScopedLock lock(_counter.mutex); 00315 result = _counter.value == 0; 00316 } 00317 return result; 00318 } 00319 00320 00321 #endif // POCO_OS 00322 00323 00324 } // namespace Poco 00325 00326 00327 #endif // Foundation_AtomicCounter_INCLUDED