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.

429 lines
15 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: winstl/synch/wait_functions.hpp
  3. *
  4. * Purpose: Synchronisation functions.
  5. *
  6. * Created: 30th May 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 winstl/synch/wait_functions.hpp
  40. *
  41. * \brief [C++ only] Definition of the winstl::wait_for_multiple_objects()
  42. * functions
  43. * (\ref group__library__synch "Synchronisation" Library).
  44. */
  45. #ifndef WINSTL_INCL_WINSTL_SYNCH_HPP_WAIT_FUNCTIONS
  46. #define WINSTL_INCL_WINSTL_SYNCH_HPP_WAIT_FUNCTIONS
  47. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  48. # define WINSTL_VER_WINSTL_SYNCH_HPP_WAIT_FUNCTIONS_MAJOR 2
  49. # define WINSTL_VER_WINSTL_SYNCH_HPP_WAIT_FUNCTIONS_MINOR 0
  50. # define WINSTL_VER_WINSTL_SYNCH_HPP_WAIT_FUNCTIONS_REVISION 3
  51. # define WINSTL_VER_WINSTL_SYNCH_HPP_WAIT_FUNCTIONS_EDIT 12
  52. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  53. /* /////////////////////////////////////////////////////////////////////////
  54. * Includes
  55. */
  56. #ifndef WINSTL_INCL_WINSTL_H_WINSTL
  57. # include <winstl/winstl.h>
  58. #endif /* !WINSTL_INCL_WINSTL_H_WINSTL */
  59. #ifndef STLSOFT_INCL_STLSOFT_SYNCH_HPP_CONCEPTS
  60. # include <stlsoft/synch/concepts.hpp>
  61. #endif /* !STLSOFT_INCL_STLSOFT_SYNCH_HPP_CONCEPTS */
  62. #ifndef WINSTL_INCL_WINSTL_SHIMS_ATTRIBUTE_HPP_GET_SYNCH_HANDLE
  63. # include <winstl/shims/attribute/get_synch_handle.hpp>
  64. #endif /* !WINSTL_INCL_WINSTL_SHIMS_ATTRIBUTE_HPP_GET_SYNCH_HANDLE */
  65. /* /////////////////////////////////////////////////////////////////////////
  66. * Namespace
  67. */
  68. #ifndef _WINSTL_NO_NAMESPACE
  69. # if defined(_STLSOFT_NO_NAMESPACE) || \
  70. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  71. /* There is no stlsoft namespace, so must define ::winstl */
  72. namespace winstl
  73. {
  74. # else
  75. /* Define stlsoft::winstl_project */
  76. namespace stlsoft
  77. {
  78. namespace winstl_project
  79. {
  80. # endif /* _STLSOFT_NO_NAMESPACE */
  81. #endif /* !_WINSTL_NO_NAMESPACE */
  82. /* /////////////////////////////////////////////////////////////////////////
  83. * Functions
  84. */
  85. #ifndef WINSTL_WAIT_FUNCTIONS_NO_USE_SHIM_VERIFIER
  86. # ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  87. template <ss_typename_param_k H>
  88. inline HANDLE w4mo_verify_and_get_discriminator(H &h, H const*)
  89. {
  90. // If the compiler balks here with a message complaining about being
  91. //
  92. // "unable to convert to HANDLE (*)(H &)",
  93. //
  94. // then it means that you're trying to pass an argument to
  95. // wait_for_multiple_object() for which an overload of the
  96. // winstl::get_synch_handle() attribute shim is not defined.
  97. //
  98. // This may confuse you if your type may be implicitly convertible to
  99. // HANDLE, but use of such types without shims is dangerous, and is
  100. // therefore disallowed.
  101. HANDLE (*pfn)(H &) = &winstl_ns_qual(get_synch_handle);
  102. return (*pfn)(h);
  103. }
  104. inline HANDLE w4mo_verify_and_get_discriminator(HANDLE h, HANDLE const*)
  105. {
  106. return h;
  107. }
  108. template <ss_typename_param_k H>
  109. inline HANDLE w4mo_verify_and_get(H &h)
  110. {
  111. return w4mo_verify_and_get_discriminator(h, &h);
  112. }
  113. # endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  114. #else /* ? WINSTL_WAIT_FUNCTIONS_NO_USE_SHIM_VERIFIER */
  115. template <ss_typename_param_k H>
  116. inline HANDLE w4mo_verify_and_get(H &h)
  117. {
  118. return winstl_ns_qual(get_synch_handle)(h);
  119. }
  120. #endif /* !WINSTL_WAIT_FUNCTIONS_NO_USE_SHIM_VERIFIER */
  121. /** \brief [IMPLEMENTATION]
  122. *
  123. * \ingroup group__library__synch
  124. */
  125. inline DWORD w4mo_helper_8( HANDLE h0
  126. , HANDLE h1
  127. , HANDLE h2
  128. , HANDLE h3
  129. , HANDLE h4
  130. , HANDLE h5
  131. , HANDLE h6
  132. , HANDLE h7
  133. , ws_bool_t bWaitAll
  134. , ws_dword_t timeout)
  135. {
  136. HANDLE handles[8];
  137. DWORD numHandles = 2;
  138. WINSTL_ASSERT(NULL != h0);
  139. WINSTL_ASSERT(NULL != h1);
  140. handles[0] = h0;
  141. handles[1] = h1;
  142. handles[2] = h2;
  143. handles[3] = h3;
  144. handles[4] = h4;
  145. handles[5] = h5;
  146. handles[6] = h6;
  147. handles[7] = h7;
  148. for(ws_size_t i = numHandles; i < STLSOFT_NUM_ELEMENTS(handles); ++i, ++numHandles)
  149. {
  150. if(NULL == handles[i])
  151. {
  152. break;
  153. }
  154. }
  155. return ::WaitForMultipleObjects(numHandles, &handles[0], bWaitAll, timeout);
  156. }
  157. /** \brief Execute wait for 8 synchronisation objects of heterogeneous types.
  158. *
  159. * \ingroup group__library__synch
  160. */
  161. template< ss_typename_param_k L0
  162. , ss_typename_param_k L1
  163. , ss_typename_param_k L2
  164. , ss_typename_param_k L3
  165. , ss_typename_param_k L4
  166. , ss_typename_param_k L5
  167. , ss_typename_param_k L6
  168. , ss_typename_param_k L7
  169. >
  170. inline DWORD wait_for_multiple_objects(L0 &l0, L1 &l1, L2 &l2, L3 &l3, L4 &l4, L5 &l5, L6 &l6, L7 &l7, ws_bool_t bWaitAll, ws_dword_t timeout)
  171. {
  172. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l0));
  173. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l1));
  174. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l2));
  175. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l3));
  176. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l4));
  177. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l5));
  178. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l6));
  179. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l7));
  180. return w4mo_helper_8(
  181. winstl_ns_qual(w4mo_verify_and_get)(l0)
  182. , winstl_ns_qual(w4mo_verify_and_get)(l1)
  183. , winstl_ns_qual(w4mo_verify_and_get)(l2)
  184. , winstl_ns_qual(w4mo_verify_and_get)(l3)
  185. , winstl_ns_qual(w4mo_verify_and_get)(l4)
  186. , winstl_ns_qual(w4mo_verify_and_get)(l5)
  187. , winstl_ns_qual(w4mo_verify_and_get)(l6)
  188. , winstl_ns_qual(w4mo_verify_and_get)(l7)
  189. , bWaitAll
  190. , timeout);
  191. }
  192. /** \brief Execute wait for 7 synchronisation objects of heterogeneous types.
  193. *
  194. * \ingroup group__library__synch
  195. */
  196. template< ss_typename_param_k L0
  197. , ss_typename_param_k L1
  198. , ss_typename_param_k L2
  199. , ss_typename_param_k L3
  200. , ss_typename_param_k L4
  201. , ss_typename_param_k L5
  202. , ss_typename_param_k L6
  203. >
  204. inline DWORD wait_for_multiple_objects(L0 &l0, L1 &l1, L2 &l2, L3 &l3, L4 &l4, L5 &l5, L6 &l6, ws_bool_t bWaitAll, ws_dword_t timeout)
  205. {
  206. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l0));
  207. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l1));
  208. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l2));
  209. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l3));
  210. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l4));
  211. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l5));
  212. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l6));
  213. return w4mo_helper_8(
  214. winstl_ns_qual(w4mo_verify_and_get)(l0)
  215. , winstl_ns_qual(w4mo_verify_and_get)(l1)
  216. , winstl_ns_qual(w4mo_verify_and_get)(l2)
  217. , winstl_ns_qual(w4mo_verify_and_get)(l3)
  218. , winstl_ns_qual(w4mo_verify_and_get)(l4)
  219. , winstl_ns_qual(w4mo_verify_and_get)(l5)
  220. , winstl_ns_qual(w4mo_verify_and_get)(l6)
  221. , NULL
  222. , bWaitAll
  223. , timeout);
  224. }
  225. /** \brief Execute wait for 6 synchronisation objects of heterogeneous types.
  226. *
  227. * \ingroup group__library__synch
  228. */
  229. template< ss_typename_param_k L0
  230. , ss_typename_param_k L1
  231. , ss_typename_param_k L2
  232. , ss_typename_param_k L3
  233. , ss_typename_param_k L4
  234. , ss_typename_param_k L5
  235. >
  236. inline DWORD wait_for_multiple_objects(L0 &l0, L1 &l1, L2 &l2, L3 &l3, L4 &l4, L5 &l5, ws_bool_t bWaitAll, ws_dword_t timeout)
  237. {
  238. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l0));
  239. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l1));
  240. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l2));
  241. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l3));
  242. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l4));
  243. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l5));
  244. return w4mo_helper_8(
  245. winstl_ns_qual(w4mo_verify_and_get)(l0)
  246. , winstl_ns_qual(w4mo_verify_and_get)(l1)
  247. , winstl_ns_qual(w4mo_verify_and_get)(l2)
  248. , winstl_ns_qual(w4mo_verify_and_get)(l3)
  249. , winstl_ns_qual(w4mo_verify_and_get)(l4)
  250. , winstl_ns_qual(w4mo_verify_and_get)(l5)
  251. , NULL
  252. , NULL
  253. , bWaitAll
  254. , timeout);
  255. }
  256. /** \brief Execute wait for 5 synchronisation objects of heterogeneous types.
  257. *
  258. * \ingroup group__library__synch
  259. */
  260. template< ss_typename_param_k L0
  261. , ss_typename_param_k L1
  262. , ss_typename_param_k L2
  263. , ss_typename_param_k L3
  264. , ss_typename_param_k L4
  265. >
  266. inline DWORD wait_for_multiple_objects(L0 &l0, L1 &l1, L2 &l2, L3 &l3, L4 &l4, ws_bool_t bWaitAll, ws_dword_t timeout)
  267. {
  268. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l0));
  269. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l1));
  270. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l2));
  271. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l3));
  272. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l4));
  273. return w4mo_helper_8(
  274. winstl_ns_qual(w4mo_verify_and_get)(l0)
  275. , winstl_ns_qual(w4mo_verify_and_get)(l1)
  276. , winstl_ns_qual(w4mo_verify_and_get)(l2)
  277. , winstl_ns_qual(w4mo_verify_and_get)(l3)
  278. , winstl_ns_qual(w4mo_verify_and_get)(l4)
  279. , NULL
  280. , NULL
  281. , NULL
  282. , bWaitAll
  283. , timeout);
  284. }
  285. /** \brief Execute wait for 4 synchronisation objects of heterogeneous types.
  286. *
  287. * \ingroup group__library__synch
  288. */
  289. template< ss_typename_param_k L0
  290. , ss_typename_param_k L1
  291. , ss_typename_param_k L2
  292. , ss_typename_param_k L3
  293. >
  294. inline DWORD wait_for_multiple_objects(L0 &l0, L1 &l1, L2 &l2, L3 &l3, ws_bool_t bWaitAll, ws_dword_t timeout)
  295. {
  296. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l0));
  297. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l1));
  298. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l2));
  299. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l3));
  300. return w4mo_helper_8(
  301. winstl_ns_qual(w4mo_verify_and_get)(l0)
  302. , winstl_ns_qual(w4mo_verify_and_get)(l1)
  303. , winstl_ns_qual(w4mo_verify_and_get)(l2)
  304. , winstl_ns_qual(w4mo_verify_and_get)(l3)
  305. , NULL
  306. , NULL
  307. , NULL
  308. , NULL
  309. , bWaitAll
  310. , timeout);
  311. }
  312. /** \brief Execute wait for 3 synchronisation objects of heterogeneous types.
  313. *
  314. * \ingroup group__library__synch
  315. */
  316. template< ss_typename_param_k L0
  317. , ss_typename_param_k L1
  318. , ss_typename_param_k L2
  319. >
  320. inline DWORD wait_for_multiple_objects(L0 &l0, L1 &l1, L2 &l2, ws_bool_t bWaitAll, ws_dword_t timeout)
  321. {
  322. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l0));
  323. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l1));
  324. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l2));
  325. return w4mo_helper_8(
  326. winstl_ns_qual(w4mo_verify_and_get)(l0)
  327. , winstl_ns_qual(w4mo_verify_and_get)(l1)
  328. , winstl_ns_qual(w4mo_verify_and_get)(l2)
  329. , NULL
  330. , NULL
  331. , NULL
  332. , NULL
  333. , NULL
  334. , bWaitAll
  335. , timeout);
  336. }
  337. /** \brief Execute wait for 2 synchronisation objects of heterogeneous types.
  338. *
  339. * \ingroup group__library__synch
  340. */
  341. template< ss_typename_param_k L0
  342. , ss_typename_param_k L1
  343. >
  344. inline DWORD wait_for_multiple_objects(L0 &l0, L1 &l1, ws_bool_t bWaitAll, ws_dword_t timeout)
  345. {
  346. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l0));
  347. WINSTL_ASSERT(NULL != winstl_ns_qual(get_synch_handle)(l1));
  348. return w4mo_helper_8(
  349. winstl_ns_qual(w4mo_verify_and_get)(l0)
  350. , winstl_ns_qual(w4mo_verify_and_get)(l1)
  351. , NULL
  352. , NULL
  353. , NULL
  354. , NULL
  355. , NULL
  356. , NULL
  357. , bWaitAll
  358. , timeout);
  359. }
  360. ////////////////////////////////////////////////////////////////////////////
  361. // Unit-testing
  362. #ifdef STLSOFT_UNITTEST
  363. # include "./unittest/wait_functions_unittest_.h"
  364. #endif /* STLSOFT_UNITTEST */
  365. /* ////////////////////////////////////////////////////////////////////// */
  366. #ifndef _WINSTL_NO_NAMESPACE
  367. # if defined(_STLSOFT_NO_NAMESPACE) || \
  368. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  369. } // namespace winstl
  370. # else
  371. } // namespace winstl_project
  372. } // namespace stlsoft
  373. # endif /* _STLSOFT_NO_NAMESPACE */
  374. #endif /* !_WINSTL_NO_NAMESPACE */
  375. /* ////////////////////////////////////////////////////////////////////// */
  376. #endif /* !WINSTL_INCL_WINSTL_SYNCH_HPP_WAIT_FUNCTIONS */
  377. /* ///////////////////////////// end of file //////////////////////////// */