log4cplus  1.1.0
syncprims.h
Go to the documentation of this file.
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