00001 // Copyright (C) 2009, Vaclav Haisman. All rights reserved. 00002 // 00003 // Redistribution and use in source and binary forms, with or without modifica- 00004 // tion, are permitted provided that the following conditions are met: 00005 // 00006 // 1. Redistributions of source code must retain the above copyright notice, 00007 // this list of conditions and the following disclaimer. 00008 // 00009 // 2. Redistributions in binary form must reproduce the above copyright notice, 00010 // this list of conditions and the following disclaimer in the documentation 00011 // and/or other materials provided with the distribution. 00012 // 00013 // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 00014 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 00015 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00016 // APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 00017 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- 00018 // DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 00019 // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00020 // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00021 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00022 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00023 00024 #ifndef LOG4CPLUS_THREAD_SYNCPRIMS_H 00025 #define LOG4CPLUS_THREAD_SYNCPRIMS_H 00026 00027 //#include <stdexcept> 00028 #include "dcmtk/oflog/config.h" 00029 #if defined (LOG4CPLUS_USE_PTHREADS) 00030 # define INCLUDE_CERRNO 00031 # include "dcmtk/ofstd/ofstdinc.h" 00032 00033 # include <pthread.h> 00034 # include <semaphore.h> 00035 # include "dcmtk/oflog/helpers/timehelp.h" 00036 00037 #elif defined (LOG4CPLUS_USE_WIN32_THREADS) 00038 # undef WIN32_LEAN_AND_MEAN 00039 # define WIN32_LEAN_AND_MEAN 00040 # include <windows.h> 00041 00042 #endif 00043 00044 00045 namespace log4cplus { namespace thread { 00046 00047 00048 namespace detail 00049 { 00050 00051 LOG4CPLUS_EXPORT void syncprims_throw_exception (char const * const msg, 00052 char const * const file, int line); 00053 00054 } // namespace detail 00055 00056 00057 template <typename SP> 00058 class SyncGuard 00059 { 00060 public: 00061 SyncGuard (SP const &); 00062 ~SyncGuard (); 00063 00064 void lock (); 00065 void unlock (); 00066 void attach (SP const &); 00067 void detach (); 00068 00069 private: 00070 SP const * sp; 00071 00072 SyncGuard (SyncGuard const &); 00073 SyncGuard & operator = (SyncGuard const &); 00074 }; 00075 00076 00077 class ManualResetEvent; 00078 00079 00080 class Mutex 00081 { 00082 public: 00083 Mutex (); 00084 ~Mutex (); 00085 00086 void lock () const; 00087 void unlock () const; 00088 00089 private: 00090 #if defined (LOG4CPLUS_USE_PTHREADS) 00091 mutable pthread_mutex_t mtx; 00092 friend class ManualResetEvent; 00093 #elif defined (LOG4CPLUS_USE_WIN32_THREADS) 00094 mutable CRITICAL_SECTION cs; 00095 #endif 00096 00097 Mutex (Mutex const &); 00098 Mutex & operator = (Mutex &); 00099 }; 00100 00101 00102 typedef SyncGuard<Mutex> MutexGuard; 00103 00104 00105 class Semaphore 00106 { 00107 public: 00108 Semaphore (unsigned max, unsigned initial); 00109 ~Semaphore (); 00110 00111 void lock () const; 00112 void unlock () const; 00113 00114 private: 00115 #if defined (LOG4CPLUS_USE_PTHREADS) 00116 mutable sem_t sem; 00117 #elif defined (LOG4CPLUS_USE_WIN32_THREADS) 00118 HANDLE sem; 00119 #endif 00120 00121 Semaphore (Semaphore const &); 00122 Semaphore & operator = (Semaphore const &); 00123 }; 00124 00125 00126 typedef SyncGuard<Semaphore> SemaphoreGuard; 00127 00128 00129 class ManualResetEvent 00130 { 00131 public: 00132 ManualResetEvent (bool = false); 00133 ~ManualResetEvent (); 00134 00135 void signal () const; 00136 void wait () const; 00137 bool timed_wait (unsigned long msec) const; 00138 void reset () const; 00139 00140 private: 00141 #if defined (LOG4CPLUS_USE_PTHREADS) 00142 mutable pthread_cond_t cv; 00143 mutable Mutex mtx; 00144 mutable volatile unsigned sigcount; 00145 mutable volatile bool signaled; 00146 #elif defined (LOG4CPLUS_USE_WIN32_THREADS) 00147 HANDLE ev; 00148 #endif 00149 00150 ManualResetEvent (ManualResetEvent const &); 00151 ManualResetEvent & operator = (ManualResetEvent const &); 00152 }; 00153 00154 00155 } } // namespace log4cplus { namespace thread { 00156 00157 00158 // Include the appropriate implementations of the classes declared 00159 // above. 00160 00161 #if defined (LOG4CPLUS_USE_PTHREADS) 00162 # include "dcmtk/oflog/helpers/syncppth.h" 00163 #elif defined (LOG4CPLUS_USE_WIN32_THREADS) 00164 # include "dcmtk/oflog/helpers/syncpwin.h" 00165 #endif 00166 00167 00168 namespace log4cplus { namespace thread { 00169 00170 00171 // 00172 // 00173 // 00174 00175 template <typename SP> 00176 inline 00177 SyncGuard<SP>::SyncGuard (SP const & m) 00178 : sp (&m) 00179 { 00180 sp->lock (); 00181 } 00182 00183 00184 template <typename SP> 00185 inline 00186 SyncGuard<SP>::~SyncGuard () 00187 { 00188 if (sp) 00189 sp->unlock (); 00190 } 00191 00192 00193 template <typename SP> 00194 inline 00195 void 00196 SyncGuard<SP>::lock () 00197 { 00198 sp->lock (); 00199 } 00200 00201 00202 template <typename SP> 00203 inline 00204 void 00205 SyncGuard<SP>::unlock () 00206 { 00207 sp->unlock (); 00208 } 00209 00210 00211 template <typename SP> 00212 inline 00213 void 00214 SyncGuard<SP>::attach (SP const & m) 00215 { 00216 sp = &m; 00217 } 00218 00219 00220 template <typename SP> 00221 inline 00222 void 00223 SyncGuard<SP>::detach () 00224 { 00225 sp = 0; 00226 } 00227 00228 00229 } } // namespace log4cplus { namespace thread { 00230 00231 00232 00233 #endif // LOG4CPLUS_THREAD_SYNCPRIMS_H