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.

382 lines
6.7 KiB

  1. // -*- C++ -*-
  2. // Copyright (C) 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_H
  25. #define LOG4CPLUS_THREAD_SYNCPRIMS_H
  26. #include <log4cplus/config.hxx>
  27. #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
  28. #pragma once
  29. #endif
  30. namespace log4cplus { namespace thread {
  31. template <typename SP>
  32. class SyncGuard
  33. {
  34. public:
  35. SyncGuard ();
  36. SyncGuard (SP const &);
  37. ~SyncGuard ();
  38. void lock ();
  39. void unlock ();
  40. void attach (SP const &);
  41. void attach_and_lock (SP const &);
  42. void detach ();
  43. private:
  44. SP const * sp;
  45. SyncGuard (SyncGuard const &);
  46. SyncGuard & operator = (SyncGuard const &);
  47. };
  48. class ManualResetEvent;
  49. class MutexImplBase
  50. {
  51. protected:
  52. ~MutexImplBase ();
  53. };
  54. class LOG4CPLUS_EXPORT Mutex
  55. {
  56. public:
  57. enum Type
  58. {
  59. DEFAULT,
  60. RECURSIVE
  61. };
  62. explicit Mutex (Type = RECURSIVE);
  63. ~Mutex ();
  64. void lock () const;
  65. void unlock () const;
  66. private:
  67. MutexImplBase * mtx;
  68. Mutex (Mutex const &);
  69. Mutex & operator = (Mutex &);
  70. };
  71. typedef SyncGuard<Mutex> MutexGuard;
  72. class SemaphoreImplBase
  73. {
  74. protected:
  75. ~SemaphoreImplBase ();
  76. };
  77. class LOG4CPLUS_EXPORT Semaphore
  78. {
  79. public:
  80. Semaphore (unsigned max, unsigned initial);
  81. ~Semaphore ();
  82. void lock () const;
  83. void unlock () const;
  84. private:
  85. SemaphoreImplBase * sem;
  86. Semaphore (Semaphore const &);
  87. Semaphore & operator = (Semaphore const &);
  88. };
  89. typedef SyncGuard<Semaphore> SemaphoreGuard;
  90. class FairMutexImplBase
  91. {
  92. protected:
  93. ~FairMutexImplBase ();
  94. };
  95. class LOG4CPLUS_EXPORT FairMutex
  96. {
  97. public:
  98. FairMutex ();
  99. ~FairMutex ();
  100. void lock () const;
  101. void unlock () const;
  102. private:
  103. FairMutexImplBase * mtx;
  104. FairMutex (FairMutex const &);
  105. FairMutex & operator = (FairMutex &);
  106. };
  107. typedef SyncGuard<FairMutex> FairMutexGuard;
  108. class ManualResetEventImplBase
  109. {
  110. protected:
  111. ~ManualResetEventImplBase ();
  112. };
  113. class LOG4CPLUS_EXPORT ManualResetEvent
  114. {
  115. public:
  116. ManualResetEvent (bool = false);
  117. ~ManualResetEvent ();
  118. void signal () const;
  119. void wait () const;
  120. bool timed_wait (unsigned long msec) const;
  121. void reset () const;
  122. private:
  123. ManualResetEventImplBase * ev;
  124. ManualResetEvent (ManualResetEvent const &);
  125. ManualResetEvent & operator = (ManualResetEvent const &);
  126. };
  127. class SharedMutexImplBase
  128. {
  129. protected:
  130. ~SharedMutexImplBase ();
  131. };
  132. template <typename SP, void (SP:: * lock_func) () const,
  133. void (SP:: * unlock_func) () const>
  134. class SyncGuardFunc
  135. {
  136. public:
  137. SyncGuardFunc (SP const &);
  138. ~SyncGuardFunc ();
  139. void lock ();
  140. void unlock ();
  141. void attach (SP const &);
  142. void detach ();
  143. private:
  144. SP const * sp;
  145. SyncGuardFunc (SyncGuardFunc const &);
  146. SyncGuardFunc & operator = (SyncGuardFunc const &);
  147. };
  148. class LOG4CPLUS_EXPORT SharedMutex
  149. {
  150. public:
  151. SharedMutex ();
  152. ~SharedMutex ();
  153. void rdlock () const;
  154. void rdunlock () const;
  155. void wrlock () const;
  156. void wrunlock () const;
  157. private:
  158. SharedMutexImplBase * sm;
  159. SharedMutex (SharedMutex const &);
  160. SharedMutex & operator = (SharedMutex const &);
  161. };
  162. typedef SyncGuardFunc<SharedMutex, &SharedMutex::rdlock,
  163. &SharedMutex::rdunlock> SharedMutexReaderGuard;
  164. typedef SyncGuardFunc<SharedMutex, &SharedMutex::wrlock,
  165. &SharedMutex::wrunlock> SharedMutexWriterGuard;
  166. //
  167. //
  168. //
  169. template <typename SP>
  170. inline
  171. SyncGuard<SP>::SyncGuard ()
  172. : sp (0)
  173. { }
  174. template <typename SP>
  175. inline
  176. SyncGuard<SP>::SyncGuard (SP const & m)
  177. : sp (&m)
  178. {
  179. sp->lock ();
  180. }
  181. template <typename SP>
  182. inline
  183. SyncGuard<SP>::~SyncGuard ()
  184. {
  185. if (sp)
  186. sp->unlock ();
  187. }
  188. template <typename SP>
  189. inline
  190. void
  191. SyncGuard<SP>::lock ()
  192. {
  193. sp->lock ();
  194. }
  195. template <typename SP>
  196. inline
  197. void
  198. SyncGuard<SP>::unlock ()
  199. {
  200. sp->unlock ();
  201. }
  202. template <typename SP>
  203. inline
  204. void
  205. SyncGuard<SP>::attach (SP const & m)
  206. {
  207. sp = &m;
  208. }
  209. template <typename SP>
  210. inline
  211. void
  212. SyncGuard<SP>::attach_and_lock (SP const & m)
  213. {
  214. attach (m);
  215. try
  216. {
  217. lock();
  218. }
  219. catch (...)
  220. {
  221. detach ();
  222. throw;
  223. }
  224. }
  225. template <typename SP>
  226. inline
  227. void
  228. SyncGuard<SP>::detach ()
  229. {
  230. sp = 0;
  231. }
  232. //
  233. //
  234. //
  235. template <typename SP, void (SP:: * lock_func) () const,
  236. void (SP:: * unlock_func) () const>
  237. inline
  238. SyncGuardFunc<SP, lock_func, unlock_func>::SyncGuardFunc (SP const & m)
  239. : sp (&m)
  240. {
  241. (sp->*lock_func) ();
  242. }
  243. template <typename SP, void (SP:: * lock_func) () const,
  244. void (SP:: * unlock_func) () const>
  245. inline
  246. SyncGuardFunc<SP, lock_func, unlock_func>::~SyncGuardFunc ()
  247. {
  248. if (sp)
  249. (sp->*unlock_func) ();
  250. }
  251. template <typename SP, void (SP:: * lock_func) () const,
  252. void (SP:: * unlock_func) () const>
  253. inline
  254. void
  255. SyncGuardFunc<SP, lock_func, unlock_func>::lock ()
  256. {
  257. (sp->*lock_func) ();
  258. }
  259. template <typename SP, void (SP:: * lock_func) () const,
  260. void (SP:: * unlock_func) () const>
  261. inline
  262. void
  263. SyncGuardFunc<SP, lock_func, unlock_func>::unlock ()
  264. {
  265. (sp->*unlock_func) ();
  266. }
  267. template <typename SP, void (SP:: * lock_func) () const,
  268. void (SP:: * unlock_func) () const>
  269. inline
  270. void
  271. SyncGuardFunc<SP, lock_func, unlock_func>::attach (SP const & m)
  272. {
  273. sp = &m;
  274. }
  275. template <typename SP, void (SP:: * lock_func) () const,
  276. void (SP:: * unlock_func) () const>
  277. inline
  278. void
  279. SyncGuardFunc<SP, lock_func, unlock_func>::detach ()
  280. {
  281. sp = 0;
  282. }
  283. } } // namespace log4cplus { namespace thread {
  284. #endif // LOG4CPLUS_THREAD_SYNCPRIMS_H