You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
5.7 KiB

  1. // -*- C++ -*-
  2. // Copyright (C) 2009-2010, Vaclav Haisman. All rights reserved.
  3. //
  4. // Redistribution and use in source and binary forms, with or without modifica-
  5. // tion, are permitted provided that the following conditions are met:
  6. //
  7. // 1. Redistributions of source code must retain the above copyright notice,
  8. // this list of conditions and the following disclaimer.
  9. //
  10. // 2. Redistributions in binary form must reproduce the above copyright notice,
  11. // this list of conditions and the following disclaimer in the documentation
  12. // and/or other materials provided with the distribution.
  13. //
  14. // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  15. // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  16. // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  17. // APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  18. // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
  19. // DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  20. // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  21. // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. #ifndef LOG4CPLUS_THREAD_SYNCPRIMS_IMPL_H
  25. #define LOG4CPLUS_THREAD_SYNCPRIMS_IMPL_H
  26. #include <log4cplus/config.hxx>
  27. #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
  28. #pragma once
  29. #endif
  30. #if ! defined (INSIDE_LOG4CPLUS)
  31. # error "This header must not be be used outside log4cplus' implementation files."
  32. #endif
  33. #include <stdexcept>
  34. #include <log4cplus/thread/syncprims.h>
  35. #if defined (_WIN32)
  36. # include <log4cplus/config/windowsh-inc.h>
  37. #elif defined (LOG4CPLUS_USE_PTHREADS)
  38. # include <errno.h>
  39. # include <pthread.h>
  40. # include <semaphore.h>
  41. # if defined (LOG4CPLUS_USE_NAMED_POSIX_SEMAPHORE)
  42. # include <sstream>
  43. # include <string>
  44. # if defined (LOG4CPLUS_HAVE_SYS_TYPES_H)
  45. # include <sys/types.h>
  46. # endif
  47. # if defined (LOG4CPLUS_HAVE_UNISTD_H)
  48. # include <unistd.h>
  49. # endif
  50. # endif
  51. # if defined (LOG4CPLUS_HAVE_FCNTL_H)
  52. # include <fcntl.h>
  53. # endif
  54. # include <log4cplus/helpers/timehelper.h>
  55. #endif
  56. namespace log4cplus { namespace thread { namespace impl {
  57. LOG4CPLUS_EXPORT void syncprims_throw_exception (char const * const msg,
  58. char const * const file, int line) LOG4CPLUS_ATTRIBUTE_NORETURN;
  59. #define LOG4CPLUS_THROW_RTE(msg) \
  60. do { syncprims_throw_exception (msg, __FILE__, __LINE__); } while (0)
  61. class ManualResetEvent;
  62. class Mutex
  63. : public MutexImplBase
  64. {
  65. public:
  66. explicit Mutex (log4cplus::thread::Mutex::Type);
  67. ~Mutex ();
  68. void lock () const;
  69. void unlock () const;
  70. private:
  71. #if defined (LOG4CPLUS_USE_PTHREADS)
  72. mutable pthread_mutex_t mtx;
  73. friend class ManualResetEvent;
  74. #elif defined (LOG4CPLUS_USE_WIN32_THREADS)
  75. mutable CRITICAL_SECTION cs;
  76. #endif
  77. Mutex (Mutex const &);
  78. Mutex & operator = (Mutex &);
  79. };
  80. typedef SyncGuard<Mutex> MutexGuard;
  81. class Semaphore
  82. : public SemaphoreImplBase
  83. {
  84. public:
  85. Semaphore (unsigned max, unsigned initial);
  86. ~Semaphore ();
  87. void lock () const;
  88. void unlock () const;
  89. private:
  90. #if defined (LOG4CPLUS_USE_PTHREADS)
  91. # if defined (LOG4CPLUS_USE_NAMED_POSIX_SEMAPHORE)
  92. sem_t * sem;
  93. # else
  94. mutable sem_t sem;
  95. # endif
  96. #elif defined (LOG4CPLUS_USE_WIN32_THREADS)
  97. HANDLE sem;
  98. #endif
  99. Semaphore (Semaphore const &);
  100. Semaphore & operator = (Semaphore const &);
  101. };
  102. typedef SyncGuard<Semaphore> SemaphoreGuard;
  103. class FairMutex
  104. : public FairMutexImplBase
  105. {
  106. public:
  107. FairMutex ();
  108. ~FairMutex ();
  109. void lock () const;
  110. void unlock () const;
  111. private:
  112. #if defined (LOG4CPLUS_USE_PTHREADS)
  113. Semaphore sem;
  114. #elif defined (LOG4CPLUS_USE_WIN32_THREADS)
  115. HANDLE mtx;
  116. #endif
  117. FairMutex (FairMutex const &);
  118. FairMutex & operator = (FairMutex &);
  119. };
  120. typedef SyncGuard<FairMutex> FairMutexGuard;
  121. class ManualResetEvent
  122. : public ManualResetEventImplBase
  123. {
  124. public:
  125. ManualResetEvent (bool = false);
  126. ~ManualResetEvent ();
  127. void signal () const;
  128. void wait () const;
  129. bool timed_wait (unsigned long msec) const;
  130. void reset () const;
  131. private:
  132. #if defined (LOG4CPLUS_USE_PTHREADS)
  133. mutable pthread_cond_t cv;
  134. mutable Mutex mtx;
  135. mutable volatile unsigned sigcount;
  136. mutable volatile bool signaled;
  137. #elif defined (LOG4CPLUS_USE_WIN32_THREADS)
  138. HANDLE ev;
  139. #endif
  140. ManualResetEvent (ManualResetEvent const &);
  141. ManualResetEvent & operator = (ManualResetEvent const &);
  142. };
  143. class SharedMutex
  144. : public SharedMutexImplBase
  145. {
  146. public:
  147. SharedMutex ();
  148. ~SharedMutex ();
  149. void rdlock () const;
  150. void wrlock () const;
  151. void rdunlock () const;
  152. void wrunlock () const;
  153. private:
  154. #if defined (LOG4CPLUS_POOR_MANS_SHAREDMUTEX)
  155. Mutex m1;
  156. Mutex m2;
  157. Mutex m3;
  158. Semaphore w;
  159. mutable unsigned writer_count;
  160. Semaphore r;
  161. mutable unsigned reader_count;
  162. #elif defined (LOG4CPLUS_USE_PTHREADS)
  163. void unlock () const;
  164. mutable pthread_rwlock_t rwl;
  165. #elif defined (LOG4CPLUS_USE_SRW_LOCK)
  166. mutable SRWLOCK srwl;
  167. #endif
  168. SharedMutex (SharedMutex const &);
  169. SharedMutex & operator = (SharedMutex const &);
  170. };
  171. } } } // namespace log4cplus { namespace thread { namespace impl {
  172. // Include the appropriate implementations of the classes declared
  173. // above.
  174. #if defined (LOG4CPLUS_USE_PTHREADS)
  175. # include <log4cplus/thread/impl/syncprims-pthreads.h>
  176. #elif defined (LOG4CPLUS_USE_WIN32_THREADS)
  177. # include <log4cplus/thread/impl/syncprims-win32.h>
  178. #endif
  179. #undef LOG4CPLUS_THROW_RTE
  180. #endif // LOG4CPLUS_THREAD_SYNCPRIMS_IMPL_H