log4cplus
1.1.0
|
00001 // -*- C++ -*- 00002 // Copyright (C) 2010, Vaclav Haisman. All rights reserved. 00003 // 00004 // Redistribution and use in source and binary forms, with or without modifica- 00005 // tion, are permitted provided that the following conditions are met: 00006 // 00007 // 1. Redistributions of source code must retain the above copyright notice, 00008 // this list of conditions and the following disclaimer. 00009 // 00010 // 2. Redistributions in binary form must reproduce the above copyright notice, 00011 // this list of conditions and the following disclaimer in the documentation 00012 // and/or other materials provided with the distribution. 00013 // 00014 // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 00015 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 00016 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00017 // APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 00018 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- 00019 // DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 00020 // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00021 // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00022 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00023 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00024 00025 #ifndef LOG4CPLUS_THREAD_SYNCPRIMS_H 00026 #define LOG4CPLUS_THREAD_SYNCPRIMS_H 00027 00028 #include <log4cplus/config.hxx> 00029 00030 #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE) 00031 #pragma once 00032 #endif 00033 00034 00035 namespace log4cplus { namespace thread { 00036 00037 00038 template <typename SP> 00039 class SyncGuard 00040 { 00041 public: 00042 SyncGuard (); 00043 SyncGuard (SP const &); 00044 ~SyncGuard (); 00045 00046 void lock (); 00047 void unlock (); 00048 void attach (SP const &); 00049 void attach_and_lock (SP const &); 00050 void detach (); 00051 00052 private: 00053 SP const * sp; 00054 00055 SyncGuard (SyncGuard const &); 00056 SyncGuard & operator = (SyncGuard const &); 00057 }; 00058 00059 00060 class ManualResetEvent; 00061 00062 00063 class MutexImplBase 00064 { 00065 protected: 00066 ~MutexImplBase (); 00067 }; 00068 00069 00070 class LOG4CPLUS_EXPORT Mutex 00071 { 00072 public: 00073 enum Type 00074 { 00075 DEFAULT, 00076 RECURSIVE 00077 }; 00078 00079 explicit Mutex (Type = RECURSIVE); 00080 ~Mutex (); 00081 00082 void lock () const; 00083 void unlock () const; 00084 00085 private: 00086 MutexImplBase * mtx; 00087 00088 Mutex (Mutex const &); 00089 Mutex & operator = (Mutex &); 00090 }; 00091 00092 00093 typedef SyncGuard<Mutex> MutexGuard; 00094 00095 00096 class SemaphoreImplBase 00097 { 00098 protected: 00099 ~SemaphoreImplBase (); 00100 }; 00101 00102 00103 class LOG4CPLUS_EXPORT Semaphore 00104 { 00105 public: 00106 Semaphore (unsigned max, unsigned initial); 00107 ~Semaphore (); 00108 00109 void lock () const; 00110 void unlock () const; 00111 00112 private: 00113 SemaphoreImplBase * sem; 00114 00115 Semaphore (Semaphore const &); 00116 Semaphore & operator = (Semaphore const &); 00117 }; 00118 00119 00120 typedef SyncGuard<Semaphore> SemaphoreGuard; 00121 00122 00123 class FairMutexImplBase 00124 { 00125 protected: 00126 ~FairMutexImplBase (); 00127 }; 00128 00129 00130 class LOG4CPLUS_EXPORT FairMutex 00131 { 00132 public: 00133 FairMutex (); 00134 ~FairMutex (); 00135 00136 void lock () const; 00137 void unlock () const; 00138 00139 private: 00140 FairMutexImplBase * mtx; 00141 00142 FairMutex (FairMutex const &); 00143 FairMutex & operator = (FairMutex &); 00144 }; 00145 00146 00147 typedef SyncGuard<FairMutex> FairMutexGuard; 00148 00149 00150 class ManualResetEventImplBase 00151 { 00152 protected: 00153 ~ManualResetEventImplBase (); 00154 }; 00155 00156 00157 class LOG4CPLUS_EXPORT ManualResetEvent 00158 { 00159 public: 00160 ManualResetEvent (bool = false); 00161 ~ManualResetEvent (); 00162 00163 void signal () const; 00164 void wait () const; 00165 bool timed_wait (unsigned long msec) const; 00166 void reset () const; 00167 00168 private: 00169 ManualResetEventImplBase * ev; 00170 00171 ManualResetEvent (ManualResetEvent const &); 00172 ManualResetEvent & operator = (ManualResetEvent const &); 00173 }; 00174 00175 00176 class SharedMutexImplBase 00177 { 00178 protected: 00179 ~SharedMutexImplBase (); 00180 }; 00181 00182 00183 template <typename SP, void (SP:: * lock_func) () const, 00184 void (SP:: * unlock_func) () const> 00185 class SyncGuardFunc 00186 { 00187 public: 00188 SyncGuardFunc (SP const &); 00189 ~SyncGuardFunc (); 00190 00191 void lock (); 00192 void unlock (); 00193 void attach (SP const &); 00194 void detach (); 00195 00196 private: 00197 SP const * sp; 00198 00199 SyncGuardFunc (SyncGuardFunc const &); 00200 SyncGuardFunc & operator = (SyncGuardFunc const &); 00201 }; 00202 00203 00204 class LOG4CPLUS_EXPORT SharedMutex 00205 { 00206 public: 00207 SharedMutex (); 00208 ~SharedMutex (); 00209 00210 void rdlock () const; 00211 void rdunlock () const; 00212 00213 void wrlock () const; 00214 void wrunlock () const; 00215 00216 private: 00217 SharedMutexImplBase * sm; 00218 00219 SharedMutex (SharedMutex const &); 00220 SharedMutex & operator = (SharedMutex const &); 00221 }; 00222 00223 00224 typedef SyncGuardFunc<SharedMutex, &SharedMutex::rdlock, 00225 &SharedMutex::rdunlock> SharedMutexReaderGuard; 00226 00227 00228 typedef SyncGuardFunc<SharedMutex, &SharedMutex::wrlock, 00229 &SharedMutex::wrunlock> SharedMutexWriterGuard; 00230 00231 00232 // 00233 // 00234 // 00235 00236 template <typename SP> 00237 inline 00238 SyncGuard<SP>::SyncGuard () 00239 : sp (0) 00240 { } 00241 00242 00243 template <typename SP> 00244 inline 00245 SyncGuard<SP>::SyncGuard (SP const & m) 00246 : sp (&m) 00247 { 00248 sp->lock (); 00249 } 00250 00251 00252 template <typename SP> 00253 inline 00254 SyncGuard<SP>::~SyncGuard () 00255 { 00256 if (sp) 00257 sp->unlock (); 00258 } 00259 00260 00261 template <typename SP> 00262 inline 00263 void 00264 SyncGuard<SP>::lock () 00265 { 00266 sp->lock (); 00267 } 00268 00269 00270 template <typename SP> 00271 inline 00272 void 00273 SyncGuard<SP>::unlock () 00274 { 00275 sp->unlock (); 00276 } 00277 00278 00279 template <typename SP> 00280 inline 00281 void 00282 SyncGuard<SP>::attach (SP const & m) 00283 { 00284 sp = &m; 00285 } 00286 00287 00288 template <typename SP> 00289 inline 00290 void 00291 SyncGuard<SP>::attach_and_lock (SP const & m) 00292 { 00293 attach (m); 00294 try 00295 { 00296 lock(); 00297 } 00298 catch (...) 00299 { 00300 detach (); 00301 throw; 00302 } 00303 } 00304 00305 00306 template <typename SP> 00307 inline 00308 void 00309 SyncGuard<SP>::detach () 00310 { 00311 sp = 0; 00312 } 00313 00314 00315 // 00316 // 00317 // 00318 00319 template <typename SP, void (SP:: * lock_func) () const, 00320 void (SP:: * unlock_func) () const> 00321 inline 00322 SyncGuardFunc<SP, lock_func, unlock_func>::SyncGuardFunc (SP const & m) 00323 : sp (&m) 00324 { 00325 (sp->*lock_func) (); 00326 } 00327 00328 00329 template <typename SP, void (SP:: * lock_func) () const, 00330 void (SP:: * unlock_func) () const> 00331 inline 00332 SyncGuardFunc<SP, lock_func, unlock_func>::~SyncGuardFunc () 00333 { 00334 if (sp) 00335 (sp->*unlock_func) (); 00336 } 00337 00338 00339 template <typename SP, void (SP:: * lock_func) () const, 00340 void (SP:: * unlock_func) () const> 00341 inline 00342 void 00343 SyncGuardFunc<SP, lock_func, unlock_func>::lock () 00344 { 00345 (sp->*lock_func) (); 00346 } 00347 00348 00349 template <typename SP, void (SP:: * lock_func) () const, 00350 void (SP:: * unlock_func) () const> 00351 inline 00352 void 00353 SyncGuardFunc<SP, lock_func, unlock_func>::unlock () 00354 { 00355 (sp->*unlock_func) (); 00356 } 00357 00358 00359 template <typename SP, void (SP:: * lock_func) () const, 00360 void (SP:: * unlock_func) () const> 00361 inline 00362 void 00363 SyncGuardFunc<SP, lock_func, unlock_func>::attach (SP const & m) 00364 { 00365 sp = &m; 00366 } 00367 00368 00369 template <typename SP, void (SP:: * lock_func) () const, 00370 void (SP:: * unlock_func) () const> 00371 inline 00372 void 00373 SyncGuardFunc<SP, lock_func, unlock_func>::detach () 00374 { 00375 sp = 0; 00376 } 00377 00378 00379 } } // namespace log4cplus { namespace thread { 00380 00381 00382 #endif // LOG4CPLUS_THREAD_SYNCPRIMS_H