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.

260 lines
8.0 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: stlsoft/synch/concepts.hpp
  3. *
  4. * Purpose: Synchronisation concept tags.
  5. *
  6. * Created: 16th January 2006
  7. * Updated: 10th August 2009
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 2006-2009, Matthew Wilson and Synesis Software
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions are met:
  16. *
  17. * - Redistributions of source code must retain the above copyright notice, this
  18. * list of conditions and the following disclaimer.
  19. * - Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  23. * any contributors may be used to endorse or promote products derived from
  24. * this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  30. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  34. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  35. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. * POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. * ////////////////////////////////////////////////////////////////////// */
  39. /** \file stlsoft/synch/concepts.hpp
  40. *
  41. * \brief [C++ only] Synchronisation concept tags
  42. * (\ref group__library__synch "Synchronisation" Library).
  43. */
  44. #ifndef STLSOFT_INCL_STLSOFT_SYNCH_HPP_CONCEPTS
  45. #define STLSOFT_INCL_STLSOFT_SYNCH_HPP_CONCEPTS
  46. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  47. # define STLSOFT_VER_STLSOFT_HPP_SYNCH_HPP_CONCEPTS_FWD_MAJOR 1
  48. # define STLSOFT_VER_STLSOFT_HPP_SYNCH_HPP_CONCEPTS_FWD_MINOR 0
  49. # define STLSOFT_VER_STLSOFT_HPP_SYNCH_HPP_CONCEPTS_FWD_REVISION 3
  50. # define STLSOFT_VER_STLSOFT_HPP_SYNCH_HPP_CONCEPTS_FWD_EDIT 11
  51. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  52. /* /////////////////////////////////////////////////////////////////////////
  53. * Includes
  54. */
  55. #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
  56. # include <stlsoft/stlsoft.h>
  57. #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
  58. #ifndef STLSOFT_INCL_STLSOFT_META_HPP_YESNO
  59. # include <stlsoft/meta/yesno.hpp>
  60. #endif /* !STLSOFT_INCL_STLSOFT_META_HPP_YESNO */
  61. /* /////////////////////////////////////////////////////////////////////////
  62. * Namespace
  63. */
  64. #ifndef _STLSOFT_NO_NAMESPACE
  65. namespace stlsoft
  66. {
  67. #endif /* _STLSOFT_NO_NAMESPACE */
  68. /* /////////////////////////////////////////////////////////////////////////
  69. * Classes
  70. */
  71. /** \brief Denotes that a deriving class is a synchronisation type
  72. *
  73. * \ingroup group__library__synch
  74. */
  75. #if 0
  76. struct synchronisation_type_tag
  77. {};
  78. #endif /* 0 */
  79. /** \brief Denotes that a deriving class is a wrapper for a native
  80. * synchronisation object, and that the underlying object is available via a
  81. * <code>get()</code> method.
  82. *
  83. * \ingroup group__library__synch
  84. */
  85. struct synchronisable_object_tag
  86. // : public synchronisation_type_tag
  87. {};
  88. /** \brief Denotes that a deriving class can be used as a critical section,
  89. * i.e. it has methods lock() and unlock() for entering and exiting the
  90. * critical sections.
  91. *
  92. * \ingroup group__library__synch
  93. */
  94. struct critical_section_tag
  95. // : public synchronisation_type_tag
  96. {};
  97. #if 0
  98. /** \brief Denotes that a deriving class can be used as a critical section
  99. * (see critical_section_tag), and that it can be recursively entered without
  100. * deadlock, i.e. the following call sequence is well defined:
  101. *
  102. * \ingroup group__library__synch
  103. *
  104. * obj.lock();
  105. * obj.lock();
  106. * obj.unlock();
  107. * obj.unlock();
  108. */
  109. struct recursive_critical_section_tag
  110. // : public critical_section_tag
  111. {};
  112. /** \brief Denotes that a deriving class can be used as a critical section
  113. * (see critical_section_tag), and that it has a try_lock() method, which returns
  114. * an integral result, where non-0 indicates that the lock() can be acquired <b>and</b>
  115. * has been acquired.
  116. *
  117. * \ingroup group__library__synch
  118. */
  119. struct tryable_critical_section_tag
  120. // : public critical_section_tag
  121. {};
  122. #endif /* 0 */
  123. /** \brief Concept tag class that denotes that an object may be utilised to
  124. * serialise access to a critical section of code.
  125. *
  126. * \ingroup group__library__synch
  127. *
  128. * \param R Integral value indicating whether the object is recursive
  129. * \param T Integral value indicating whether the object supports the
  130. * <code>try_lock()</code> operation.
  131. */
  132. template< int R
  133. , int T
  134. >
  135. struct critical_section
  136. : public critical_section_tag
  137. {
  138. enum { is_recursive = R };
  139. enum { is_tryable = T };
  140. /// \brief Type the indicates whether the deriving type
  141. ///
  142. ///
  143. typedef ss_typename_type_k value_to_yesno_type<is_recursive>::type is_recursive_type;
  144. typedef ss_typename_type_k value_to_yesno_type<is_tryable>::type is_tryable_type;
  145. };
  146. #define STLSOFT_CRITICAL_SECTION_IS_RECURSIVE (1)
  147. #define STLSOFT_CRITICAL_SECTION_ISNOT_RECURSIVE (0)
  148. #define STLSOFT_CRITICAL_SECTION_IS_TRYABLE (1)
  149. #define STLSOFT_CRITICAL_SECTION_ISNOT_TRYABLE (0)
  150. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  151. //typedef synchronisation_type_tag synchronization_type_tag;
  152. typedef synchronisable_object_tag synchronizable_object_tag;
  153. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  154. /* /////////////////////////////////////////////////////////////////////////
  155. * Concept checks
  156. */
  157. namespace concept_check
  158. {
  159. template <ss_typename_param_k S>
  160. void synch_conformance_synch_obj(S &s, synchronisable_object_tag const*)
  161. {
  162. s.handle();
  163. s.is_signalled();
  164. static_cast<int>(s.is_signalled()); // Checks that return type evaluatable as truth
  165. }
  166. template <ss_typename_param_k S>
  167. void synch_conformance_synch_obj(S &s, ...)
  168. {}
  169. template <ss_typename_param_k S>
  170. void synch_conformance_try_lock(S &s, yes_type)
  171. {
  172. if(s.try_lock())
  173. {
  174. s.unlock();
  175. }
  176. }
  177. template <ss_typename_param_k S>
  178. void synch_conformance_try_lock(S &s, no_type)
  179. {}
  180. template <ss_typename_param_k S>
  181. void synch_conformance_recursive_lock(S &s, yes_type)
  182. {
  183. s.lock();
  184. s.lock();
  185. s.unlock();
  186. s.unlock();
  187. }
  188. template <ss_typename_param_k S>
  189. void synch_conformance_recursive_lock(S &s, no_type)
  190. {}
  191. template <ss_typename_param_k S>
  192. void synch_conformance_lock(S &s, critical_section_tag const*)
  193. {
  194. s.lock();
  195. s.unlock();
  196. typedef ss_typename_type_k value_to_yesno_type<S::is_tryable>::type is_tryable_type;
  197. synch_conformance_try_lock(s, is_tryable_type());
  198. typedef ss_typename_type_k value_to_yesno_type<S::is_recursive>::type is_recursive_type;
  199. synch_conformance_recursive_lock(s, is_recursive_type());
  200. }
  201. template <ss_typename_param_k S>
  202. void synch_conformance_lock(S &s, ...)
  203. {}
  204. template <ss_typename_param_k S>
  205. void synch_conformance(S &s)
  206. {
  207. synch_conformance_synch_obj(s,&s);
  208. synch_conformance_lock(s, &s);
  209. }
  210. } // namespace concept_check
  211. /* ////////////////////////////////////////////////////////////////////// */
  212. #ifndef _STLSOFT_NO_NAMESPACE
  213. } // namespace stlsoft
  214. #endif /* _STLSOFT_NO_NAMESPACE */
  215. /* ////////////////////////////////////////////////////////////////////// */
  216. #endif /* !STLSOFT_INCL_STLSOFT_SYNCH_HPP_CONCEPTS */
  217. /* ///////////////////////////// end of file //////////////////////////// */