log4cplus
1.1.0
|
00001 // -*- C++ -*- 00002 // Copyright (C) 2009-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_IMPL_H 00026 #define LOG4CPLUS_THREAD_SYNCPRIMS_IMPL_H 00027 00028 #include <log4cplus/config.hxx> 00029 00030 #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE) 00031 #pragma once 00032 #endif 00033 00034 #if ! defined (INSIDE_LOG4CPLUS) 00035 # error "This header must not be be used outside log4cplus' implementation files." 00036 #endif 00037 00038 #include <stdexcept> 00039 #include <log4cplus/thread/syncprims.h> 00040 #if defined (_WIN32) 00041 # include <log4cplus/config/windowsh-inc.h> 00042 00043 #elif defined (LOG4CPLUS_USE_PTHREADS) 00044 # include <errno.h> 00045 # include <pthread.h> 00046 # include <semaphore.h> 00047 # if defined (LOG4CPLUS_USE_NAMED_POSIX_SEMAPHORE) 00048 # include <sstream> 00049 # include <string> 00050 # if defined (LOG4CPLUS_HAVE_SYS_TYPES_H) 00051 # include <sys/types.h> 00052 # endif 00053 # if defined (LOG4CPLUS_HAVE_UNISTD_H) 00054 # include <unistd.h> 00055 # endif 00056 # endif 00057 # if defined (LOG4CPLUS_HAVE_FCNTL_H) 00058 # include <fcntl.h> 00059 # endif 00060 # include <log4cplus/helpers/timehelper.h> 00061 00062 #endif 00063 00064 00065 namespace log4cplus { namespace thread { namespace impl { 00066 00067 00068 LOG4CPLUS_EXPORT void LOG4CPLUS_ATTRIBUTE_NORETURN 00069 syncprims_throw_exception (char const * const msg, 00070 char const * const file, int line); 00071 00072 00073 #define LOG4CPLUS_THROW_RTE(msg) \ 00074 do { syncprims_throw_exception (msg, __FILE__, __LINE__); } while (0) 00075 00076 00077 class ManualResetEvent; 00078 00079 00080 class Mutex 00081 : public MutexImplBase 00082 { 00083 public: 00084 explicit Mutex (log4cplus::thread::Mutex::Type); 00085 ~Mutex (); 00086 00087 void lock () const; 00088 void unlock () const; 00089 00090 private: 00091 #if defined (LOG4CPLUS_USE_PTHREADS) 00092 mutable pthread_mutex_t mtx; 00093 friend class ManualResetEvent; 00094 #elif defined (LOG4CPLUS_USE_WIN32_THREADS) 00095 mutable CRITICAL_SECTION cs; 00096 #endif 00097 00098 Mutex (Mutex const &); 00099 Mutex & operator = (Mutex &); 00100 }; 00101 00102 00103 typedef SyncGuard<Mutex> MutexGuard; 00104 00105 00106 class Semaphore 00107 : public SemaphoreImplBase 00108 { 00109 public: 00110 Semaphore (unsigned max, unsigned initial); 00111 ~Semaphore (); 00112 00113 void lock () const; 00114 void unlock () const; 00115 00116 private: 00117 #if defined (LOG4CPLUS_USE_PTHREADS) 00118 # if defined (LOG4CPLUS_USE_NAMED_POSIX_SEMAPHORE) 00119 sem_t * sem; 00120 # else 00121 mutable sem_t sem; 00122 # endif 00123 #elif defined (LOG4CPLUS_USE_WIN32_THREADS) 00124 HANDLE sem; 00125 #endif 00126 00127 Semaphore (Semaphore const &); 00128 Semaphore & operator = (Semaphore const &); 00129 }; 00130 00131 00132 typedef SyncGuard<Semaphore> SemaphoreGuard; 00133 00134 00135 class FairMutex 00136 : public FairMutexImplBase 00137 { 00138 public: 00139 FairMutex (); 00140 ~FairMutex (); 00141 00142 void lock () const; 00143 void unlock () const; 00144 00145 private: 00146 #if defined (LOG4CPLUS_USE_PTHREADS) 00147 Semaphore sem; 00148 #elif defined (LOG4CPLUS_USE_WIN32_THREADS) 00149 HANDLE mtx; 00150 #endif 00151 00152 FairMutex (FairMutex const &); 00153 FairMutex & operator = (FairMutex &); 00154 }; 00155 00156 00157 typedef SyncGuard<FairMutex> FairMutexGuard; 00158 00159 00160 class ManualResetEvent 00161 : public ManualResetEventImplBase 00162 { 00163 public: 00164 ManualResetEvent (bool = false); 00165 ~ManualResetEvent (); 00166 00167 void signal () const; 00168 void wait () const; 00169 bool timed_wait (unsigned long msec) const; 00170 void reset () const; 00171 00172 private: 00173 #if defined (LOG4CPLUS_USE_PTHREADS) 00174 mutable pthread_cond_t cv; 00175 mutable Mutex mtx; 00176 mutable volatile unsigned sigcount; 00177 mutable volatile bool signaled; 00178 #elif defined (LOG4CPLUS_USE_WIN32_THREADS) 00179 HANDLE ev; 00180 #endif 00181 00182 ManualResetEvent (ManualResetEvent const &); 00183 ManualResetEvent & operator = (ManualResetEvent const &); 00184 }; 00185 00186 00187 class SharedMutex 00188 : public SharedMutexImplBase 00189 { 00190 public: 00191 SharedMutex (); 00192 ~SharedMutex (); 00193 00194 void rdlock () const; 00195 void wrlock () const; 00196 void rdunlock () const; 00197 void wrunlock () const; 00198 00199 private: 00200 #if defined (LOG4CPLUS_POOR_MANS_SHAREDMUTEX) 00201 Mutex m1; 00202 Mutex m2; 00203 Mutex m3; 00204 Semaphore w; 00205 mutable unsigned writer_count; 00206 Semaphore r; 00207 mutable unsigned reader_count; 00208 00209 #elif defined (LOG4CPLUS_USE_PTHREADS) 00210 void unlock () const; 00211 00212 mutable pthread_rwlock_t rwl; 00213 00214 #elif defined (LOG4CPLUS_USE_SRW_LOCK) 00215 mutable SRWLOCK srwl; 00216 00217 #endif 00218 00219 SharedMutex (SharedMutex const &); 00220 SharedMutex & operator = (SharedMutex const &); 00221 }; 00222 00223 00224 } } } // namespace log4cplus { namespace thread { namespace impl { 00225 00226 00227 // Include the appropriate implementations of the classes declared 00228 // above. 00229 00230 #if defined (LOG4CPLUS_USE_PTHREADS) 00231 # include <log4cplus/thread/impl/syncprims-pthreads.h> 00232 #elif defined (LOG4CPLUS_USE_WIN32_THREADS) 00233 # include <log4cplus/thread/impl/syncprims-win32.h> 00234 #endif 00235 00236 00237 #undef LOG4CPLUS_THROW_RTE 00238 00239 00240 #endif // LOG4CPLUS_THREAD_SYNCPRIMS_IMPL_H