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.

240 lines
5.7 KiB

  1. // -*- C++ -*-
  2. // Copyright (C) 2009-2013, 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 LOG4CPLUS_ATTRIBUTE_NORETURN
  58. syncprims_throw_exception (char const * const msg,
  59. char const * const file, int line);
  60. #define LOG4CPLUS_THROW_RTE(msg) \
  61. do { syncprims_throw_exception (msg, __FILE__, __LINE__); } while (0)
  62. class ManualResetEvent;
  63. class Mutex
  64. : public MutexImplBase
  65. {
  66. public:
  67. explicit Mutex (log4cplus::thread::Mutex::Type);
  68. ~Mutex ();
  69. void lock () const;
  70. void unlock () const;
  71. private:
  72. #if defined (LOG4CPLUS_USE_PTHREADS)
  73. mutable pthread_mutex_t mtx;
  74. friend class ManualResetEvent;
  75. #elif defined (LOG4CPLUS_USE_WIN32_THREADS)
  76. mutable CRITICAL_SECTION cs;
  77. #endif
  78. Mutex (Mutex const &);
  79. Mutex & operator = (Mutex &);
  80. };
  81. typedef SyncGuard<Mutex> MutexGuard;
  82. class Semaphore
  83. : public SemaphoreImplBase
  84. {
  85. public:
  86. Semaphore (unsigned max, unsigned initial);
  87. ~Semaphore ();
  88. void lock () const;
  89. void unlock () const;
  90. private:
  91. #if defined (LOG4CPLUS_USE_PTHREADS)
  92. # if defined (LOG4CPLUS_USE_NAMED_POSIX_SEMAPHORE)
  93. sem_t * sem;
  94. # else
  95. mutable sem_t sem;
  96. # endif
  97. #elif defined (LOG4CPLUS_USE_WIN32_THREADS)
  98. HANDLE sem;
  99. #endif
  100. Semaphore (Semaphore const &);
  101. Semaphore & operator = (Semaphore const &);
  102. };
  103. typedef SyncGuard<Semaphore> SemaphoreGuard;
  104. class FairMutex
  105. : public FairMutexImplBase
  106. {
  107. public:
  108. FairMutex ();
  109. ~FairMutex ();
  110. void lock () const;
  111. void unlock () const;
  112. private:
  113. #if defined (LOG4CPLUS_USE_PTHREADS)
  114. Semaphore sem;
  115. #elif defined (LOG4CPLUS_USE_WIN32_THREADS)
  116. HANDLE mtx;
  117. #endif
  118. FairMutex (FairMutex const &);
  119. FairMutex & operator = (FairMutex &);
  120. };
  121. typedef SyncGuard<FairMutex> FairMutexGuard;
  122. class ManualResetEvent
  123. : public ManualResetEventImplBase
  124. {
  125. public:
  126. ManualResetEvent (bool = false);
  127. ~ManualResetEvent ();
  128. void signal () const;
  129. void wait () const;
  130. bool timed_wait (unsigned long msec) const;
  131. void reset () const;
  132. private:
  133. #if defined (LOG4CPLUS_USE_PTHREADS)
  134. mutable pthread_cond_t cv;
  135. mutable Mutex mtx;
  136. mutable volatile unsigned sigcount;
  137. mutable volatile bool signaled;
  138. #elif defined (LOG4CPLUS_USE_WIN32_THREADS)
  139. HANDLE ev;
  140. #endif
  141. ManualResetEvent (ManualResetEvent const &);
  142. ManualResetEvent & operator = (ManualResetEvent const &);
  143. };
  144. class SharedMutex
  145. : public SharedMutexImplBase
  146. {
  147. public:
  148. SharedMutex ();
  149. ~SharedMutex ();
  150. void rdlock () const;
  151. void wrlock () const;
  152. void rdunlock () const;
  153. void wrunlock () const;
  154. private:
  155. #if defined (LOG4CPLUS_POOR_MANS_SHAREDMUTEX)
  156. Mutex m1;
  157. Mutex m2;
  158. Mutex m3;
  159. Semaphore w;
  160. mutable unsigned writer_count;
  161. Semaphore r;
  162. mutable unsigned reader_count;
  163. #elif defined (LOG4CPLUS_USE_PTHREADS)
  164. void unlock () const;
  165. mutable pthread_rwlock_t rwl;
  166. #elif defined (LOG4CPLUS_USE_SRW_LOCK)
  167. mutable SRWLOCK srwl;
  168. #endif
  169. SharedMutex (SharedMutex const &);
  170. SharedMutex & operator = (SharedMutex const &);
  171. };
  172. } } } // namespace log4cplus { namespace thread { namespace impl {
  173. // Include the appropriate implementations of the classes declared
  174. // above.
  175. #if defined (LOG4CPLUS_USE_PTHREADS)
  176. # include <log4cplus/thread/impl/syncprims-pthreads.h>
  177. #elif defined (LOG4CPLUS_USE_WIN32_THREADS)
  178. # include <log4cplus/thread/impl/syncprims-win32.h>
  179. #endif
  180. #undef LOG4CPLUS_THROW_RTE
  181. #endif // LOG4CPLUS_THREAD_SYNCPRIMS_IMPL_H