passenger 4.0.20 → 4.0.21

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (496) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/.gitignore +1 -0
  5. data/.travis.yml +1 -1
  6. data/NEWS +15 -0
  7. data/README.md +5 -3
  8. data/Rakefile +1 -0
  9. data/bin/passenger-config +1 -5
  10. data/bin/passenger-install-apache2-module +53 -5
  11. data/bin/passenger-install-nginx-module +19 -6
  12. data/bin/passenger-memory-stats +3 -3
  13. data/build/agents.rb +11 -8
  14. data/build/apache2.rb +9 -5
  15. data/build/basics.rb +15 -21
  16. data/build/common_library.rb +16 -6
  17. data/build/cplusplus_support.rb +5 -5
  18. data/build/cxx_tests.rb +3 -3
  19. data/build/documentation.rb +1 -1
  20. data/build/misc.rb +4 -37
  21. data/build/node_tests.rb +29 -0
  22. data/build/oxt_tests.rb +1 -1
  23. data/build/packaging.rb +29 -10
  24. data/build/preprocessor.rb +2 -1
  25. data/build/test_basics.rb +15 -6
  26. data/debian.template/locations.ini.template +1 -0
  27. data/debian.template/passenger.install.template +1 -0
  28. data/dev/copy_boost_headers.rb +7 -3
  29. data/dev/run_travis.sh +32 -16
  30. data/doc/Users guide Apache.idmap.txt +22 -34
  31. data/doc/Users guide Apache.txt +20 -234
  32. data/doc/Users guide Nginx.idmap.txt +84 -66
  33. data/doc/Users guide Nginx.txt +50 -1
  34. data/doc/Users guide Standalone.idmap.txt +74 -0
  35. data/doc/Users guide Standalone.txt +22 -9
  36. data/doc/Users guide.txt +51 -0
  37. data/doc/users_guide_snippets/environment_variables.txt +0 -3
  38. data/doc/users_guide_snippets/installation.txt +337 -380
  39. data/doc/users_guide_snippets/installation/run_installer.txt +58 -0
  40. data/doc/users_guide_snippets/installation/verify_running_epilogue.txt +6 -0
  41. data/doc/users_guide_snippets/support_information.txt +2 -9
  42. data/doc/users_guide_snippets/troubleshooting/default.txt +112 -0
  43. data/doc/users_guide_snippets/troubleshooting/rails.txt +56 -0
  44. data/doc/users_guide_snippets/where_to_get_support.txt +9 -0
  45. data/ext/apache2/Bucket.h +1 -1
  46. data/ext/apache2/Configuration.hpp +0 -44
  47. data/ext/apache2/CreateDirConfig.cpp +1 -1
  48. data/ext/apache2/CreateDirConfig.cpp.erb +1 -1
  49. data/ext/apache2/Hooks.cpp +28 -21
  50. data/ext/apache2/MergeDirConfig.cpp +1 -0
  51. data/ext/apache2/MergeDirConfig.cpp.erb +1 -1
  52. data/ext/apache2/SetHeaders.cpp +73 -0
  53. data/ext/apache2/SetHeaders.cpp.erb +88 -0
  54. data/ext/boost/algorithm/string/detail/find_format.hpp +5 -5
  55. data/ext/boost/algorithm/string/detail/find_format_all.hpp +5 -5
  56. data/ext/boost/algorithm/string/detail/finder.hpp +1 -1
  57. data/ext/boost/algorithm/string/formatter.hpp +2 -2
  58. data/ext/boost/assert.hpp +6 -1
  59. data/ext/boost/atomic.hpp +18 -0
  60. data/ext/boost/atomic/atomic.hpp +241 -0
  61. data/ext/boost/atomic/detail/base.hpp +585 -0
  62. data/ext/boost/atomic/detail/cas32strong.hpp +885 -0
  63. data/ext/boost/atomic/detail/cas32weak.hpp +947 -0
  64. data/ext/boost/atomic/detail/cas64strong.hpp +443 -0
  65. data/ext/boost/atomic/detail/config.hpp +54 -0
  66. data/ext/boost/atomic/detail/gcc-alpha.hpp +368 -0
  67. data/ext/boost/atomic/detail/gcc-armv6plus.hpp +252 -0
  68. data/ext/boost/atomic/detail/gcc-cas.hpp +157 -0
  69. data/ext/boost/atomic/detail/gcc-ppc.hpp +2850 -0
  70. data/ext/boost/atomic/detail/gcc-sparcv9.hpp +1259 -0
  71. data/ext/boost/atomic/detail/gcc-x86.hpp +1766 -0
  72. data/ext/boost/atomic/detail/generic-cas.hpp +206 -0
  73. data/ext/boost/atomic/detail/interlocked.hpp +200 -0
  74. data/ext/boost/atomic/detail/linux-arm.hpp +189 -0
  75. data/ext/boost/atomic/detail/lockpool.hpp +97 -0
  76. data/ext/boost/atomic/detail/platform.hpp +62 -0
  77. data/ext/boost/atomic/detail/type-classification.hpp +45 -0
  78. data/ext/boost/chrono/config.hpp +8 -3
  79. data/ext/boost/chrono/duration.hpp +9 -10
  80. data/ext/boost/chrono/system_clocks.hpp +1 -1
  81. data/ext/boost/chrono/time_point.hpp +4 -3
  82. data/ext/boost/config/auto_link.hpp +53 -52
  83. data/ext/boost/config/compiler/borland.hpp +1 -0
  84. data/ext/boost/config/compiler/clang.hpp +24 -1
  85. data/ext/boost/config/compiler/codegear.hpp +1 -0
  86. data/ext/boost/config/compiler/common_edg.hpp +1 -0
  87. data/ext/boost/config/compiler/cray.hpp +1 -0
  88. data/ext/boost/config/compiler/digitalmars.hpp +1 -0
  89. data/ext/boost/config/compiler/gcc.hpp +29 -3
  90. data/ext/boost/config/compiler/gcc_xml.hpp +2 -1
  91. data/ext/boost/config/compiler/hp_acc.hpp +1 -0
  92. data/ext/boost/config/compiler/intel.hpp +1 -1
  93. data/ext/boost/config/compiler/metrowerks.hpp +1 -0
  94. data/ext/boost/config/compiler/mpw.hpp +1 -0
  95. data/ext/boost/config/compiler/pathscale.hpp +1 -0
  96. data/ext/boost/config/compiler/pgi.hpp +1 -0
  97. data/ext/boost/config/compiler/sunpro_cc.hpp +1 -0
  98. data/ext/boost/config/compiler/vacpp.hpp +3 -2
  99. data/ext/boost/config/compiler/visualc.hpp +25 -11
  100. data/ext/boost/config/platform/vxworks.hpp +353 -15
  101. data/ext/boost/config/select_compiler_config.hpp +4 -4
  102. data/ext/boost/config/stdlib/dinkumware.hpp +10 -3
  103. data/ext/boost/config/stdlib/libstdcpp3.hpp +2 -1
  104. data/ext/boost/config/suffix.hpp +45 -19
  105. data/ext/boost/date_time/format_date_parser.hpp +1 -11
  106. data/ext/boost/date_time/strings_from_facet.hpp +5 -3
  107. data/ext/boost/detail/atomic_redef_macros.hpp +19 -0
  108. data/ext/boost/detail/atomic_undef_macros.hpp +39 -0
  109. data/ext/boost/detail/endian.hpp +52 -4
  110. data/ext/boost/detail/scoped_enum_emulation.hpp +10 -10
  111. data/ext/boost/detail/select_type.hpp +36 -0
  112. data/ext/boost/exception/current_exception_cast.hpp +1 -1
  113. data/ext/boost/exception/detail/error_info_impl.hpp +3 -5
  114. data/ext/boost/exception/detail/exception_ptr.hpp +3 -3
  115. data/ext/boost/exception/detail/is_output_streamable.hpp +1 -1
  116. data/ext/boost/exception/detail/object_hex_dump.hpp +1 -1
  117. data/ext/boost/exception/detail/type_info.hpp +1 -1
  118. data/ext/boost/exception/diagnostic_information.hpp +15 -14
  119. data/ext/boost/exception/exception.hpp +1 -1
  120. data/ext/boost/exception/get_error_info.hpp +1 -1
  121. data/ext/boost/exception/info.hpp +12 -13
  122. data/ext/boost/exception/to_string.hpp +6 -1
  123. data/ext/boost/exception/to_string_stub.hpp +9 -1
  124. data/ext/boost/foreach.hpp +5 -5
  125. data/ext/boost/function/function_template.hpp +6 -6
  126. data/ext/boost/functional/hash/detail/float_functions.hpp +90 -0
  127. data/ext/boost/functional/hash/detail/hash_float.hpp +11 -2
  128. data/ext/boost/functional/hash/extensions.hpp +14 -2
  129. data/ext/boost/functional/hash/hash.hpp +26 -5
  130. data/ext/boost/get_pointer.hpp +17 -2
  131. data/ext/boost/integer_traits.hpp +1 -1
  132. data/ext/boost/lexical_cast.hpp +615 -395
  133. data/ext/boost/libs/atomic/lockpool.cpp +24 -0
  134. data/ext/boost/libs/system/src/error_code.cpp +25 -18
  135. data/ext/boost/libs/thread/src/future.cpp +7 -5
  136. data/ext/boost/libs/thread/src/pthread/once.cpp +9 -3
  137. data/ext/boost/libs/thread/src/pthread/once_atomic.cpp +90 -0
  138. data/ext/boost/libs/thread/src/pthread/thread.cpp +129 -95
  139. data/ext/boost/libs/thread/src/pthread/timeconv.inl +20 -1
  140. data/ext/boost/limits.hpp +1 -1
  141. data/ext/boost/math/policies/policy.hpp +10 -0
  142. data/ext/boost/math/special_functions/detail/round_fwd.hpp +17 -4
  143. data/ext/boost/math/special_functions/fpclassify.hpp +114 -45
  144. data/ext/boost/math/special_functions/math_fwd.hpp +195 -83
  145. data/ext/boost/math/special_functions/sign.hpp +13 -8
  146. data/ext/boost/math/tools/config.hpp +38 -16
  147. data/ext/boost/move/algorithm.hpp +275 -0
  148. data/ext/boost/move/core.hpp +332 -0
  149. data/ext/boost/move/detail/config_begin.hpp +23 -0
  150. data/ext/boost/move/detail/config_end.hpp +20 -0
  151. data/ext/boost/move/detail/meta_utils.hpp +158 -0
  152. data/ext/boost/move/iterator.hpp +298 -0
  153. data/ext/boost/move/move.hpp +10 -1256
  154. data/ext/boost/move/traits.hpp +142 -0
  155. data/ext/boost/move/utility.hpp +194 -0
  156. data/ext/boost/mpl/assert.hpp +72 -4
  157. data/ext/boost/noncopyable.hpp +15 -3
  158. data/ext/boost/pointer_to_other.hpp +55 -0
  159. data/ext/boost/range/concepts.hpp +4 -4
  160. data/ext/boost/range/detail/extract_optional_type.hpp +1 -1
  161. data/ext/boost/range/empty.hpp +1 -1
  162. data/ext/boost/range/iterator_range_core.hpp +4 -1
  163. data/ext/boost/range/iterator_range_io.hpp +2 -2
  164. data/ext/boost/ratio/config.hpp +6 -0
  165. data/ext/boost/ratio/detail/overflow_helpers.hpp +2 -2
  166. data/ext/boost/smart_ptr/allocate_shared_array.hpp +250 -0
  167. data/ext/boost/smart_ptr/detail/allocate_array_helper.hpp +169 -0
  168. data/ext/boost/smart_ptr/detail/array_deleter.hpp +124 -0
  169. data/ext/boost/smart_ptr/detail/array_traits.hpp +53 -0
  170. data/ext/boost/smart_ptr/detail/array_utility.hpp +178 -0
  171. data/ext/boost/smart_ptr/detail/make_array_helper.hpp +157 -0
  172. data/ext/boost/smart_ptr/detail/operator_bool.hpp +16 -9
  173. data/ext/boost/smart_ptr/detail/shared_count.hpp +78 -7
  174. data/ext/boost/smart_ptr/detail/sp_convertible.hpp +15 -0
  175. data/ext/boost/smart_ptr/detail/sp_counted_base.hpp +12 -6
  176. data/ext/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp +1 -0
  177. data/ext/boost/smart_ptr/detail/sp_counted_base_aix.hpp +1 -0
  178. data/ext/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp +1 -0
  179. data/ext/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp +1 -0
  180. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp +1 -0
  181. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +1 -0
  182. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp +1 -0
  183. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp +1 -0
  184. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp +1 -0
  185. data/ext/boost/smart_ptr/detail/sp_counted_base_nt.hpp +1 -0
  186. data/ext/boost/smart_ptr/detail/sp_counted_base_pt.hpp +1 -0
  187. data/ext/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp +162 -0
  188. data/ext/boost/smart_ptr/detail/sp_counted_base_solaris.hpp +1 -0
  189. data/ext/boost/smart_ptr/detail/sp_counted_base_spin.hpp +1 -0
  190. data/ext/boost/smart_ptr/detail/sp_counted_base_sync.hpp +1 -0
  191. data/ext/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp +1 -0
  192. data/ext/boost/smart_ptr/detail/sp_counted_impl.hpp +15 -0
  193. data/ext/boost/smart_ptr/detail/sp_forward.hpp +39 -0
  194. data/ext/boost/smart_ptr/detail/sp_has_sync.hpp +19 -3
  195. data/ext/boost/smart_ptr/detail/sp_if_array.hpp +31 -0
  196. data/ext/boost/smart_ptr/detail/sp_nullptr_t.hpp +45 -0
  197. data/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +5 -12
  198. data/ext/boost/smart_ptr/enable_shared_from_this.hpp +4 -4
  199. data/ext/boost/smart_ptr/make_shared.hpp +5 -1060
  200. data/ext/boost/smart_ptr/make_shared_array.hpp +247 -0
  201. data/ext/boost/smart_ptr/make_shared_object.hpp +1128 -0
  202. data/ext/boost/smart_ptr/scoped_array.hpp +32 -7
  203. data/ext/boost/smart_ptr/scoped_ptr.hpp +31 -5
  204. data/ext/boost/smart_ptr/shared_array.hpp +135 -20
  205. data/ext/boost/smart_ptr/shared_ptr.hpp +444 -126
  206. data/ext/boost/smart_ptr/weak_ptr.hpp +39 -28
  207. data/ext/boost/static_assert.hpp +74 -17
  208. data/ext/boost/system/error_code.hpp +76 -68
  209. data/ext/boost/system/system_error.hpp +5 -1
  210. data/ext/boost/thread/barrier.hpp +6 -2
  211. data/ext/boost/thread/completion_latch.hpp +233 -0
  212. data/ext/boost/thread/condition.hpp +6 -1
  213. data/ext/boost/thread/detail/async_func.hpp +571 -0
  214. data/ext/boost/thread/detail/config.hpp +248 -40
  215. data/ext/boost/thread/detail/counter.hpp +93 -0
  216. data/ext/boost/thread/detail/delete.hpp +12 -0
  217. data/ext/boost/thread/detail/invoke.hpp +1351 -0
  218. data/ext/boost/thread/detail/is_convertible.hpp +48 -0
  219. data/ext/boost/thread/detail/lockable_wrapper.hpp +45 -0
  220. data/ext/boost/thread/detail/log.hpp +83 -0
  221. data/ext/boost/thread/detail/make_tuple_indices.hpp +224 -0
  222. data/ext/boost/thread/detail/move.hpp +32 -16
  223. data/ext/boost/thread/detail/thread.hpp +236 -41
  224. data/ext/boost/thread/detail/thread_group.hpp +55 -9
  225. data/ext/boost/thread/detail/thread_interruption.hpp +4 -1
  226. data/ext/boost/thread/exceptions.hpp +2 -0
  227. data/ext/boost/thread/externally_locked.hpp +351 -0
  228. data/ext/boost/thread/externally_locked_stream.hpp +170 -0
  229. data/ext/boost/thread/future.hpp +2517 -455
  230. data/ext/boost/thread/future_error_code.hpp +61 -0
  231. data/ext/boost/thread/is_locked_by_this_thread.hpp +39 -0
  232. data/ext/boost/thread/latch.hpp +142 -0
  233. data/ext/boost/thread/lock_algorithms.hpp +468 -0
  234. data/ext/boost/thread/lock_concepts.hpp +197 -0
  235. data/ext/boost/thread/lock_factories.hpp +78 -0
  236. data/ext/boost/thread/lock_guard.hpp +88 -0
  237. data/ext/boost/thread/lock_options.hpp +31 -0
  238. data/ext/boost/thread/lock_traits.hpp +45 -0
  239. data/ext/boost/thread/lock_types.hpp +1226 -0
  240. data/ext/boost/thread/lockable_adapter.hpp +226 -0
  241. data/ext/boost/thread/lockable_concepts.hpp +157 -0
  242. data/ext/boost/thread/lockable_traits.hpp +207 -0
  243. data/ext/boost/thread/locks.hpp +5 -1816
  244. data/ext/boost/thread/mutex.hpp +33 -1
  245. data/ext/boost/thread/null_mutex.hpp +243 -0
  246. data/ext/boost/thread/once.hpp +10 -1
  247. data/ext/boost/thread/poly_lockable.hpp +68 -0
  248. data/ext/boost/thread/poly_lockable_adapter.hpp +89 -0
  249. data/ext/boost/thread/poly_shared_lockable.hpp +135 -0
  250. data/ext/boost/thread/poly_shared_lockable_adapter.hpp +170 -0
  251. data/ext/boost/thread/pthread/condition_variable.hpp +74 -26
  252. data/ext/boost/thread/pthread/condition_variable_fwd.hpp +54 -27
  253. data/ext/boost/thread/pthread/mutex.hpp +101 -38
  254. data/ext/boost/thread/pthread/once.hpp +459 -44
  255. data/ext/boost/thread/pthread/once_atomic.hpp +313 -0
  256. data/ext/boost/thread/pthread/recursive_mutex.hpp +19 -10
  257. data/ext/boost/thread/pthread/shared_mutex.hpp +226 -61
  258. data/ext/boost/thread/pthread/shared_mutex_assert.hpp +724 -0
  259. data/ext/boost/thread/pthread/thread_data.hpp +53 -50
  260. data/ext/boost/thread/pthread/timespec.hpp +96 -12
  261. data/ext/boost/thread/recursive_mutex.hpp +44 -1
  262. data/ext/boost/thread/reverse_lock.hpp +3 -2
  263. data/ext/boost/thread/scoped_thread.hpp +285 -0
  264. data/ext/boost/thread/shared_lock_guard.hpp +2 -1
  265. data/ext/boost/thread/shared_mutex.hpp +23 -0
  266. data/ext/boost/thread/strict_lock.hpp +235 -0
  267. data/ext/boost/thread/sync_bounded_queue.hpp +594 -0
  268. data/ext/boost/thread/sync_queue.hpp +516 -0
  269. data/ext/boost/thread/synchronized_value.hpp +1001 -0
  270. data/ext/boost/thread/testable_mutex.hpp +148 -0
  271. data/ext/boost/thread/thread.hpp +1 -13
  272. data/ext/boost/thread/thread_functors.hpp +57 -0
  273. data/ext/boost/thread/thread_guard.hpp +46 -0
  274. data/ext/boost/thread/thread_only.hpp +29 -0
  275. data/ext/boost/thread/v2/shared_mutex.hpp +1062 -0
  276. data/ext/boost/thread/v2/thread.hpp +37 -10
  277. data/ext/boost/thread/xtime.hpp +2 -1
  278. data/ext/boost/token_functions.hpp +16 -16
  279. data/ext/boost/type_traits/add_lvalue_reference.hpp +26 -0
  280. data/ext/boost/type_traits/add_reference.hpp +1 -1
  281. data/ext/boost/type_traits/add_rvalue_reference.hpp +4 -4
  282. data/ext/boost/type_traits/aligned_storage.hpp +13 -0
  283. data/ext/boost/type_traits/common_type.hpp +11 -12
  284. data/ext/boost/type_traits/config.hpp +1 -1
  285. data/ext/boost/type_traits/detail/common_type_imp.hpp +1 -1
  286. data/ext/boost/type_traits/detail/has_binary_operator.hpp +1 -1
  287. data/ext/boost/type_traits/detail/is_function_ptr_tester.hpp +1 -1
  288. data/ext/boost/type_traits/has_left_shift.hpp +49 -0
  289. data/ext/boost/type_traits/has_right_shift.hpp +49 -0
  290. data/ext/boost/type_traits/has_trivial_move_assign.hpp +57 -0
  291. data/ext/boost/type_traits/has_trivial_move_constructor.hpp +57 -0
  292. data/ext/boost/type_traits/intrinsics.hpp +18 -2
  293. data/ext/boost/type_traits/is_abstract.hpp +1 -1
  294. data/ext/boost/type_traits/is_array.hpp +1 -1
  295. data/ext/boost/type_traits/is_const.hpp +1 -1
  296. data/ext/boost/type_traits/is_convertible.hpp +78 -17
  297. data/ext/boost/type_traits/is_function.hpp +6 -1
  298. data/ext/boost/type_traits/is_integral.hpp +6 -1
  299. data/ext/boost/type_traits/is_nothrow_move_assignable.hpp +84 -0
  300. data/ext/boost/type_traits/is_nothrow_move_constructible.hpp +84 -0
  301. data/ext/boost/type_traits/is_pod.hpp +3 -1
  302. data/ext/boost/type_traits/is_rvalue_reference.hpp +1 -1
  303. data/ext/boost/type_traits/is_volatile.hpp +1 -1
  304. data/ext/boost/type_traits/make_signed.hpp +153 -0
  305. data/ext/boost/type_traits/make_unsigned.hpp +16 -0
  306. data/ext/boost/type_traits/remove_const.hpp +1 -1
  307. data/ext/boost/type_traits/remove_cv.hpp +1 -1
  308. data/ext/boost/type_traits/remove_reference.hpp +1 -1
  309. data/ext/boost/type_traits/remove_volatile.hpp +1 -1
  310. data/ext/boost/unordered/detail/allocate.hpp +1120 -0
  311. data/ext/boost/unordered/detail/buckets.hpp +876 -0
  312. data/ext/boost/unordered/detail/equivalent.hpp +680 -0
  313. data/ext/boost/unordered/detail/extract_key.hpp +183 -0
  314. data/ext/boost/unordered/detail/fwd.hpp +23 -0
  315. data/ext/boost/unordered/detail/table.hpp +861 -0
  316. data/ext/boost/unordered/detail/unique.hpp +622 -0
  317. data/ext/boost/unordered/detail/util.hpp +260 -0
  318. data/ext/boost/unordered/unordered_map.hpp +1652 -0
  319. data/ext/boost/unordered/unordered_map_fwd.hpp +65 -0
  320. data/ext/boost/unordered/unordered_set.hpp +1549 -0
  321. data/ext/boost/unordered/unordered_set_fwd.hpp +63 -0
  322. data/ext/boost/unordered_map.hpp +18 -0
  323. data/ext/boost/unordered_set.hpp +18 -0
  324. data/ext/boost/utility/addressof.hpp +2 -2
  325. data/ext/boost/utility/result_of.hpp +8 -1
  326. data/ext/boost/version.hpp +2 -2
  327. data/ext/common/Account.h +1 -1
  328. data/ext/common/AccountsDatabase.h +1 -1
  329. data/ext/common/AgentsStarter.cpp +3 -1
  330. data/ext/common/AgentsStarter.h +2 -2
  331. data/ext/common/ApplicationPool2/AppTypes.cpp +24 -6
  332. data/ext/common/ApplicationPool2/AppTypes.h +17 -8
  333. data/ext/common/ApplicationPool2/Common.h +12 -12
  334. data/ext/common/ApplicationPool2/DirectSpawner.h +2 -2
  335. data/ext/common/ApplicationPool2/DummySpawner.h +3 -3
  336. data/ext/common/ApplicationPool2/Group.h +6 -6
  337. data/ext/common/ApplicationPool2/Implementation.cpp +19 -19
  338. data/ext/common/ApplicationPool2/PipeWatcher.h +5 -5
  339. data/ext/common/ApplicationPool2/Pool.h +21 -21
  340. data/ext/common/ApplicationPool2/Process.h +6 -6
  341. data/ext/common/ApplicationPool2/Session.h +1 -1
  342. data/ext/common/ApplicationPool2/SmartSpawner.h +24 -12
  343. data/ext/common/ApplicationPool2/Socket.h +2 -2
  344. data/ext/common/ApplicationPool2/Spawner.h +64 -14
  345. data/ext/common/ApplicationPool2/SpawnerFactory.h +7 -7
  346. data/ext/common/ApplicationPool2/SuperGroup.h +5 -5
  347. data/ext/common/BackgroundEventLoop.cpp +4 -4
  348. data/ext/common/BackgroundEventLoop.h +1 -1
  349. data/ext/common/Constants.h +13 -1
  350. data/ext/common/EventedBufferedInput.h +8 -8
  351. data/ext/common/Exceptions.cpp +71 -0
  352. data/ext/common/Exceptions.h +60 -7
  353. data/ext/common/FileDescriptor.h +4 -4
  354. data/ext/common/MessageClient.h +1 -1
  355. data/ext/common/MessageServer.h +5 -5
  356. data/ext/common/MultiLibeio.cpp +3 -3
  357. data/ext/common/MultiLibeio.h +2 -2
  358. data/ext/common/RandomGenerator.h +11 -11
  359. data/ext/common/ResourceLocator.h +8 -1
  360. data/ext/common/SafeLibev.h +12 -12
  361. data/ext/common/ServerInstanceDir.h +11 -3
  362. data/ext/common/UnionStation.h +10 -10
  363. data/ext/common/Utils.cpp +11 -13
  364. data/ext/common/Utils.h +9 -9
  365. data/ext/common/Utils/BlockingQueue.h +10 -10
  366. data/ext/common/Utils/BufferedIO.h +1 -1
  367. data/ext/common/Utils/CachedFileStat.hpp +2 -2
  368. data/ext/common/Utils/FileChangeChecker.h +1 -1
  369. data/ext/common/Utils/HashMap.h +13 -4
  370. data/ext/common/Utils/IOUtils.cpp +33 -10
  371. data/ext/common/Utils/IniFile.h +3 -3
  372. data/ext/common/Utils/Lock.h +2 -2
  373. data/ext/common/Utils/MessagePassing.h +10 -10
  374. data/ext/common/Utils/ProcessMetricsCollector.h +24 -6
  375. data/ext/common/Utils/ScopeGuard.h +5 -5
  376. data/ext/common/Utils/jsoncpp.cpp +2 -0
  377. data/ext/common/agents/HelperAgent/FileBackedPipe.h +26 -26
  378. data/ext/common/agents/HelperAgent/Main.cpp +18 -18
  379. data/ext/common/agents/HelperAgent/RequestHandler.cpp +4 -4
  380. data/ext/common/agents/HelperAgent/RequestHandler.h +30 -21
  381. data/ext/common/agents/LoggingAgent/AdminController.h +1 -1
  382. data/ext/common/agents/LoggingAgent/FilterSupport.h +13 -11
  383. data/ext/common/agents/LoggingAgent/LoggingServer.h +11 -11
  384. data/ext/common/agents/LoggingAgent/Main.cpp +9 -9
  385. data/ext/common/agents/LoggingAgent/RemoteSender.h +3 -3
  386. data/ext/common/agents/SpawnPreparer.cpp +1 -0
  387. data/ext/common/agents/Watchdog/AgentWatcher.cpp +8 -7
  388. data/ext/common/agents/Watchdog/Main.cpp +81 -73
  389. data/ext/common/agents/Watchdog/ServerInstanceDirToucher.cpp +1 -1
  390. data/ext/libev/Changes +57 -0
  391. data/ext/libev/LICENSE +2 -1
  392. data/ext/libev/Makefile.in +110 -50
  393. data/ext/libev/README +8 -8
  394. data/ext/libev/aclocal.m4 +1503 -861
  395. data/ext/libev/config.guess +290 -304
  396. data/ext/libev/config.sub +77 -198
  397. data/ext/libev/configure +1735 -890
  398. data/ext/libev/configure.ac +3 -2
  399. data/ext/libev/ev++.h +6 -6
  400. data/ext/libev/ev.c +541 -214
  401. data/ext/libev/ev.h +106 -100
  402. data/ext/libev/ev_epoll.c +1 -1
  403. data/ext/libev/ev_kqueue.c +20 -4
  404. data/ext/libev/ev_vars.h +15 -16
  405. data/ext/libev/ev_win32.c +12 -2
  406. data/ext/libev/ev_wrap.h +162 -160
  407. data/ext/libev/event.c +29 -6
  408. data/ext/libev/event.h +9 -2
  409. data/ext/libev/ltmain.sh +2632 -1384
  410. data/ext/nginx/ConfigurationCommands.c +1 -1
  411. data/ext/nginx/ConfigurationCommands.c.erb +3 -1
  412. data/ext/nginx/ContentHandler.c +25 -2
  413. data/ext/nginx/CreateLocationConfig.c +1 -0
  414. data/ext/nginx/CreateLocationConfig.c.erb +1 -1
  415. data/ext/nginx/MergeLocationConfig.c +1 -0
  416. data/ext/nginx/MergeLocationConfig.c.erb +1 -1
  417. data/ext/nginx/config +12 -0
  418. data/ext/oxt/dynamic_thread_group.hpp +7 -4
  419. data/ext/oxt/system_calls.cpp +5 -1
  420. data/ext/oxt/system_calls.hpp +3 -0
  421. data/helper-scripts/node-loader.js +117 -249
  422. data/lib/phusion_passenger.rb +27 -5
  423. data/lib/phusion_passenger/abstract_installer.rb +104 -9
  424. data/lib/phusion_passenger/admin_tools/memory_stats.rb +10 -9
  425. data/lib/phusion_passenger/apache2/config_options.rb +6 -3
  426. data/lib/phusion_passenger/common_library.rb +7 -1
  427. data/lib/phusion_passenger/constants.rb +6 -0
  428. data/lib/phusion_passenger/loader_shared_helpers.rb +7 -4
  429. data/lib/phusion_passenger/nginx/config_options.rb +2 -1
  430. data/lib/phusion_passenger/packaging.rb +3 -0
  431. data/lib/phusion_passenger/platform_info/apache.rb +43 -6
  432. data/lib/phusion_passenger/platform_info/apache_detector.rb +15 -5
  433. data/lib/phusion_passenger/platform_info/compiler.rb +167 -32
  434. data/lib/phusion_passenger/platform_info/cxx_portability.rb +133 -77
  435. data/lib/phusion_passenger/platform_info/depcheck.rb +17 -7
  436. data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +3 -3
  437. data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
  438. data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +5 -6
  439. data/lib/phusion_passenger/platform_info/linux.rb +2 -1
  440. data/lib/phusion_passenger/platform_info/operating_system.rb +1 -1
  441. data/lib/phusion_passenger/platform_info/ruby.rb +18 -3
  442. data/lib/phusion_passenger/standalone/runtime_installer.rb +6 -2
  443. data/lib/phusion_passenger/standalone/start_command.rb +8 -2
  444. data/lib/phusion_passenger/utils/ansi_colors.rb +9 -0
  445. data/lib/phusion_passenger/utils/hosts_file_parser.rb +4 -2
  446. data/node_lib/phusion_passenger/httplib_emulation.js +141 -0
  447. data/node_lib/phusion_passenger/line_reader.js +154 -0
  448. data/node_lib/phusion_passenger/request_handler.js +65 -0
  449. data/node_lib/phusion_passenger/session_protocol_parser.js +113 -0
  450. data/resources/templates/apache2/deployment_example.txt.erb +2 -1
  451. data/resources/templates/apache2/installing_against_a_different_apache.txt.erb +14 -0
  452. data/resources/templates/apache2/multiple_apache_installations_detected.txt.erb +15 -0
  453. data/resources/templates/apache2/possible_solutions_for_compilation_and_installation_problems.txt.erb +4 -5
  454. data/resources/templates/general_error_with_html.html.template +1 -1
  455. data/resources/templates/installer_common/gem_install_permission_problems.txt.erb +17 -0
  456. data/resources/templates/installer_common/low_amount_of_memory_warning.txt.erb +6 -4
  457. data/resources/templates/installer_common/world_inaccessible_directories.txt.erb +16 -0
  458. data/resources/templates/nginx/deployment_example.txt.erb +2 -1
  459. data/resources/templates/nginx/possible_solutions_for_compilation_and_installation_problems.txt.erb +4 -5
  460. data/resources/templates/standalone/config.erb +1 -0
  461. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +3 -3
  462. data/test/cxx/ApplicationPool2/PoolTest.cpp +4 -4
  463. data/test/cxx/ApplicationPool2/ProcessTest.cpp +5 -5
  464. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +5 -5
  465. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +1 -1
  466. data/test/cxx/EventedBufferedInputTest.cpp +6 -6
  467. data/test/cxx/FileBackedPipeTest.cpp +1 -1
  468. data/test/cxx/MessagePassingTest.cpp +1 -1
  469. data/test/cxx/MessageServerTest.cpp +4 -4
  470. data/test/cxx/RequestHandlerTest.cpp +7 -7
  471. data/test/cxx/UnionStationTest.cpp +2 -2
  472. data/test/node/line_reader_spec.js +338 -0
  473. data/test/node/spec_helper.js +27 -0
  474. data/test/ruby/standalone/runtime_installer_spec.rb +2 -1
  475. metadata +131 -22
  476. metadata.gz.asc +7 -7
  477. data/ext/boost/functional/hash/detail/container_fwd_0x.hpp +0 -29
  478. data/ext/boost/lambda/core.hpp +0 -79
  479. data/ext/boost/lambda/detail/actions.hpp +0 -174
  480. data/ext/boost/lambda/detail/arity_code.hpp +0 -110
  481. data/ext/boost/lambda/detail/function_adaptors.hpp +0 -789
  482. data/ext/boost/lambda/detail/is_instance_of.hpp +0 -104
  483. data/ext/boost/lambda/detail/lambda_config.hpp +0 -48
  484. data/ext/boost/lambda/detail/lambda_functor_base.hpp +0 -615
  485. data/ext/boost/lambda/detail/lambda_functors.hpp +0 -324
  486. data/ext/boost/lambda/detail/lambda_fwd.hpp +0 -74
  487. data/ext/boost/lambda/detail/lambda_traits.hpp +0 -578
  488. data/ext/boost/lambda/detail/member_ptr.hpp +0 -737
  489. data/ext/boost/lambda/detail/operator_actions.hpp +0 -139
  490. data/ext/boost/lambda/detail/operator_lambda_func_base.hpp +0 -271
  491. data/ext/boost/lambda/detail/operator_return_type_traits.hpp +0 -917
  492. data/ext/boost/lambda/detail/operators.hpp +0 -370
  493. data/ext/boost/lambda/detail/ret.hpp +0 -325
  494. data/ext/boost/lambda/detail/return_type_traits.hpp +0 -282
  495. data/ext/boost/lambda/detail/select_functions.hpp +0 -74
  496. data/ext/boost/lambda/lambda.hpp +0 -34
@@ -0,0 +1,197 @@
1
+ // (C) Copyright 2012 Vicente Botet
2
+ //
3
+ // Distributed under the Boost Software License, Version 1.0. (See accompanying
4
+ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
+
6
+ #ifndef BOOST_THREAD_LOCK_CONCEPTS_HPP
7
+ #define BOOST_THREAD_LOCK_CONCEPTS_HPP
8
+
9
+ #include <boost/thread/lock_traits.hpp>
10
+ #include <boost/thread/lock_options.hpp>
11
+ #include <boost/thread/lockable_concepts.hpp>
12
+ #include <boost/thread/exceptions.hpp>
13
+ #include <boost/thread/detail/move.hpp>
14
+
15
+ #include <boost/chrono/chrono.hpp>
16
+ #include <boost/concept_check.hpp>
17
+ #include <boost/static_assert.hpp>
18
+
19
+ namespace boost
20
+ {
21
+
22
+ /**
23
+ * BasicLock object supports the basic features
24
+ * required to delimit a critical region
25
+ * Supports the basic lock, unlock and try_lock functions and
26
+ * defines the lock traits
27
+ */
28
+
29
+ template <typename Lk>
30
+ struct BasicLock
31
+ {
32
+ typedef typename Lk::mutex_type mutex_type;
33
+ void cvt_mutex_ptr(mutex_type*) {}
34
+ BOOST_CONCEPT_ASSERT(( BasicLockable<mutex_type> ));
35
+
36
+ BOOST_CONCEPT_USAGE(BasicLock)
37
+ {
38
+ const Lk l1(mtx);
39
+ Lk l2(mtx, defer_lock);
40
+ Lk l3(mtx, adopt_lock);
41
+ Lk l4(( Lk()));
42
+ Lk l5(( boost::move(l2)));
43
+ cvt_mutex_ptr(l1.mutex());
44
+ if (l1.owns_lock()) return;
45
+ if (l1) return;
46
+ if (!l1) return;
47
+
48
+ l2.lock();
49
+ l2.unlock();
50
+ l2.release();
51
+
52
+ }
53
+ BasicLock() :
54
+ mtx(*static_cast<mutex_type*>(0))
55
+ {}
56
+ private:
57
+ BasicLock operator=(BasicLock const&);
58
+ mutex_type& mtx;
59
+ }
60
+ ;
61
+
62
+ template <typename Lk>
63
+ struct Lock
64
+ {
65
+ BOOST_CONCEPT_ASSERT(( BasicLock<Lk> ));
66
+ typedef typename Lk::mutex_type mutex_type;
67
+ BOOST_CONCEPT_ASSERT(( Lockable<mutex_type> ));
68
+
69
+ BOOST_CONCEPT_USAGE(Lock)
70
+ {
71
+ Lk l1(mtx, try_to_lock);
72
+ if (l1.try_lock()) return;
73
+ }
74
+ Lock() :
75
+ mtx(*static_cast<mutex_type*>(0))
76
+ {}
77
+ private:
78
+ Lock operator=(Lock const&);
79
+ mutex_type& mtx;
80
+ };
81
+
82
+ template <typename Lk>
83
+ struct TimedLock
84
+ {
85
+ BOOST_CONCEPT_ASSERT(( Lock<Lk> ));
86
+ typedef typename Lk::mutex_type mutex_type;
87
+ BOOST_CONCEPT_ASSERT(( TimedLockable<mutex_type> ));
88
+
89
+ BOOST_CONCEPT_USAGE(TimedLock)
90
+ {
91
+ const Lk l1(mtx, t);
92
+ Lk l2(mtx, d);
93
+ if (l1.try_lock_until(t)) return;
94
+ if (l1.try_lock_for(d)) return;
95
+ }
96
+ TimedLock() :
97
+ mtx(*static_cast<mutex_type*>(0))
98
+ {}
99
+ private:
100
+ TimedLock operator=(TimedLock const&);
101
+ mutex_type& mtx;
102
+ boost::chrono::system_clock::time_point t;
103
+ boost::chrono::system_clock::duration d;
104
+ };
105
+
106
+ template <typename Lk>
107
+ struct UniqueLock
108
+ {
109
+ BOOST_CONCEPT_ASSERT(( TimedLock<Lk> ));
110
+ typedef typename Lk::mutex_type mutex_type;
111
+
112
+ BOOST_CONCEPT_USAGE(UniqueLock)
113
+ {
114
+
115
+ }
116
+ UniqueLock() :
117
+ mtx(*static_cast<mutex_type*>(0))
118
+ {}
119
+ private:
120
+ UniqueLock operator=(UniqueLock const&);
121
+ mutex_type& mtx;
122
+ };
123
+
124
+ template <typename Lk>
125
+ struct SharedLock
126
+ {
127
+ BOOST_CONCEPT_ASSERT(( TimedLock<Lk> ));
128
+ typedef typename Lk::mutex_type mutex_type;
129
+
130
+ BOOST_CONCEPT_USAGE(SharedLock)
131
+ {
132
+ }
133
+ SharedLock() :
134
+ mtx(*static_cast<mutex_type*>(0))
135
+ {}
136
+ private:
137
+ SharedLock operator=(SharedLock const&);
138
+ mutex_type& mtx;
139
+
140
+ };
141
+
142
+ template <typename Lk>
143
+ struct UpgradeLock
144
+ {
145
+ BOOST_CONCEPT_ASSERT(( SharedLock<Lk> ));
146
+ typedef typename Lk::mutex_type mutex_type;
147
+
148
+ BOOST_CONCEPT_USAGE(UpgradeLock)
149
+ {
150
+ }
151
+ UpgradeLock() :
152
+ mtx(*static_cast<mutex_type*>(0))
153
+ {}
154
+ private:
155
+ UpgradeLock operator=(UpgradeLock const&);
156
+ mutex_type& mtx;
157
+ };
158
+
159
+ /**
160
+ * An StrictLock is a scoped lock guard ensuring the mutex is locked on the
161
+ * scope of the lock, by locking the mutex on construction and unlocking it on
162
+ * destruction.
163
+ *
164
+ * Essentially, a StrictLock's role is only to live on the stack as an
165
+ * automatic variable. strict_lock must adhere to a non-copy and non-alias
166
+ * policy. StrictLock disables copying by making the copy constructor and the
167
+ * assignment operator private. While we're at it, let's disable operator new
168
+ * and operator delete; strict locks are not intended to be allocated on the
169
+ * heap. StrictLock avoids aliasing by using a slightly less orthodox and
170
+ * less well-known technique: disable address taking.
171
+ */
172
+
173
+ template <typename Lk>
174
+ struct StrictLock
175
+ {
176
+ typedef typename Lk::mutex_type mutex_type;
177
+ BOOST_CONCEPT_ASSERT(( BasicLockable<mutex_type> ));
178
+ BOOST_STATIC_ASSERT(( is_strict_lock<Lk>::value ));
179
+
180
+ BOOST_CONCEPT_USAGE( StrictLock)
181
+ {
182
+ if (l1.owns_lock(&mtx)) return;
183
+ }
184
+ StrictLock() :
185
+ l1(*static_cast<Lk*>(0)),
186
+ mtx(*static_cast<mutex_type*>(0))
187
+ {}
188
+ private:
189
+ StrictLock operator=(StrictLock const&);
190
+
191
+ Lk const& l1;
192
+ mutex_type const& mtx;
193
+
194
+ };
195
+
196
+ }
197
+ #endif
@@ -0,0 +1,78 @@
1
+ // Distributed under the Boost Software License, Version 1.0. (See
2
+ // accompanying file LICENSE_1_0.txt or copy at
3
+ // http://www.boost.org/LICENSE_1_0.txt)
4
+ // (C) Copyright 2012 Vicente J. Botet Escriba
5
+
6
+ #ifndef BOOST_THREAD_LOCK_FACTORIES_HPP
7
+ #define BOOST_THREAD_LOCK_FACTORIES_HPP
8
+
9
+ #include <boost/thread/lock_types.hpp>
10
+ #include <boost/thread/lock_algorithms.hpp>
11
+ #if ! defined(BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS)
12
+ #include <tuple> // todo change to <boost/tuple.hpp> once Boost.Tuple or Boost.Fusion provides Move semantics.
13
+ #endif
14
+ #include <boost/config/abi_prefix.hpp>
15
+
16
+ namespace boost
17
+ {
18
+
19
+ template <typename Lockable>
20
+ unique_lock<Lockable> make_unique_lock(Lockable& mtx)
21
+ {
22
+ return unique_lock<Lockable> (mtx);
23
+ }
24
+
25
+ template <typename Lockable>
26
+ unique_lock<Lockable> make_unique_lock(Lockable& mtx, adopt_lock_t)
27
+ {
28
+ return unique_lock<Lockable> (mtx, adopt_lock);
29
+ }
30
+
31
+ template <typename Lockable>
32
+ unique_lock<Lockable> make_unique_lock(Lockable& mtx, defer_lock_t)
33
+ {
34
+ return unique_lock<Lockable> (mtx, defer_lock);
35
+ }
36
+
37
+ template <typename Lockable>
38
+ unique_lock<Lockable> make_unique_lock(Lockable& mtx, try_to_lock_t)
39
+ {
40
+ return unique_lock<Lockable> (mtx, try_to_lock);
41
+ }
42
+ #if ! defined(BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS)
43
+
44
+ #if ! defined BOOST_NO_CXX11_VARIADIC_TEMPLATES
45
+ template <typename ...Lockable>
46
+ std::tuple<unique_lock<Lockable> ...> make_unique_locks(Lockable& ...mtx)
47
+ {
48
+ boost::lock(mtx...);
49
+ return std::tuple<unique_lock<Lockable> ...>(unique_lock<Lockable>(mtx, adopt_lock)...);
50
+ }
51
+ #else
52
+ template <typename L1, typename L2>
53
+ std::tuple<unique_lock<L1>, unique_lock<L2> > make_unique_locks(L1& m1, L2& m2)
54
+ {
55
+ boost::lock(m1, m2);
56
+ return std::tuple<unique_lock<L1>,unique_lock<L2> >(
57
+ unique_lock<L1>(m1, adopt_lock),
58
+ unique_lock<L2>(m2, adopt_lock)
59
+ );
60
+ }
61
+ template <typename L1, typename L2, typename L3>
62
+ std::tuple<unique_lock<L1>, unique_lock<L2>, unique_lock<L3> > make_unique_locks(L1& m1, L2& m2, L3& m3)
63
+ {
64
+ boost::lock(m1, m2, m3);
65
+ return std::tuple<unique_lock<L1>,unique_lock<L2>,unique_lock<L3> >(
66
+ unique_lock<L1>(m1, adopt_lock),
67
+ unique_lock<L2>(m2, adopt_lock),
68
+ unique_lock<L3>(m3, adopt_lock)
69
+ );
70
+ }
71
+
72
+ #endif
73
+ #endif
74
+
75
+ }
76
+
77
+ #include <boost/config/abi_suffix.hpp>
78
+ #endif
@@ -0,0 +1,88 @@
1
+ // Distributed under the Boost Software License, Version 1.0. (See
2
+ // accompanying file LICENSE_1_0.txt or copy at
3
+ // http://www.boost.org/LICENSE_1_0.txt)
4
+ // (C) Copyright 2007 Anthony Williams
5
+ // (C) Copyright 2011-2012 Vicente J. Botet Escriba
6
+
7
+ #ifndef BOOST_THREAD_LOCK_GUARD_HPP
8
+ #define BOOST_THREAD_LOCK_GUARD_HPP
9
+
10
+ #include <boost/thread/detail/config.hpp>
11
+ #include <boost/thread/detail/delete.hpp>
12
+ #include <boost/thread/detail/move.hpp>
13
+ #include <boost/thread/detail/lockable_wrapper.hpp>
14
+ #include <boost/thread/lock_options.hpp>
15
+ #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
16
+ #include <boost/thread/is_locked_by_this_thread.hpp>
17
+ #include <boost/assert.hpp>
18
+ #endif
19
+
20
+ #include <boost/config/abi_prefix.hpp>
21
+
22
+ namespace boost
23
+ {
24
+
25
+ template <typename Mutex>
26
+ class lock_guard
27
+ {
28
+ private:
29
+ Mutex& m;
30
+
31
+ public:
32
+ typedef Mutex mutex_type;
33
+ BOOST_THREAD_NO_COPYABLE( lock_guard )
34
+
35
+ explicit lock_guard(Mutex& m_) :
36
+ m(m_)
37
+ {
38
+ m.lock();
39
+ }
40
+
41
+ lock_guard(Mutex& m_, adopt_lock_t) :
42
+ m(m_)
43
+ {
44
+ #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
45
+ BOOST_ASSERT(is_locked_by_this_thread(m));
46
+ #endif
47
+ }
48
+
49
+ #if ! defined BOOST_THREAD_NO_CXX11_HDR_INITIALIZER_LIST
50
+ lock_guard(std::initializer_list<thread_detail::lockable_wrapper<Mutex> > l_) :
51
+ m(*(const_cast<thread_detail::lockable_wrapper<Mutex>*>(l_.begin())->m))
52
+ {
53
+ m.lock();
54
+ }
55
+
56
+ lock_guard(std::initializer_list<thread_detail::lockable_adopt_wrapper<Mutex> > l_) :
57
+ m(*(const_cast<thread_detail::lockable_adopt_wrapper<Mutex>*>(l_.begin())->m))
58
+ {
59
+ #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
60
+ BOOST_ASSERT(is_locked_by_this_thread(m));
61
+ #endif
62
+ }
63
+
64
+ #endif
65
+ ~lock_guard()
66
+ {
67
+ m.unlock();
68
+ }
69
+ };
70
+
71
+
72
+ #if ! defined BOOST_THREAD_NO_MAKE_LOCK_GUARD
73
+ template <typename Lockable>
74
+ lock_guard<Lockable> make_lock_guard(Lockable& mtx)
75
+ {
76
+ return { thread_detail::lockable_wrapper<Lockable>(mtx) };
77
+ }
78
+ template <typename Lockable>
79
+ lock_guard<Lockable> make_lock_guard(Lockable& mtx, adopt_lock_t)
80
+ {
81
+ return { thread_detail::lockable_adopt_wrapper<Lockable>(mtx) };
82
+ }
83
+ #endif
84
+ }
85
+
86
+ #include <boost/config/abi_suffix.hpp>
87
+
88
+ #endif
@@ -0,0 +1,31 @@
1
+ // Distributed under the Boost Software License, Version 1.0. (See
2
+ // accompanying file LICENSE_1_0.txt or copy at
3
+ // http://www.boost.org/LICENSE_1_0.txt)
4
+ // (C) Copyright 2007 Anthony Williams
5
+ // (C) Copyright 2011-2012 Vicente J. Botet Escriba
6
+
7
+ #ifndef BOOST_THREAD_LOCK_OPTIONS_HPP
8
+ #define BOOST_THREAD_LOCK_OPTIONS_HPP
9
+
10
+ #include <boost/config/abi_prefix.hpp>
11
+
12
+ namespace boost
13
+ {
14
+ struct defer_lock_t
15
+ {
16
+ };
17
+ struct try_to_lock_t
18
+ {
19
+ };
20
+ struct adopt_lock_t
21
+ {
22
+ };
23
+
24
+ BOOST_CONSTEXPR_OR_CONST defer_lock_t defer_lock = {};
25
+ BOOST_CONSTEXPR_OR_CONST try_to_lock_t try_to_lock = {};
26
+ BOOST_CONSTEXPR_OR_CONST adopt_lock_t adopt_lock = {};
27
+
28
+ }
29
+ #include <boost/config/abi_suffix.hpp>
30
+
31
+ #endif
@@ -0,0 +1,45 @@
1
+ // Distributed under the Boost Software License, Version 1.0. (See
2
+ // accompanying file LICENSE_1_0.txt or copy at
3
+ // http://www.boost.org/LICENSE_1_0.txt)
4
+ // (C) Copyright 2009-2012 Vicente J. Botet Escriba
5
+
6
+ #ifndef BOOST_THREAD_LOCK_TRAITS_HPP
7
+ #define BOOST_THREAD_LOCK_TRAITS_HPP
8
+
9
+ #include <boost/thread/detail/config.hpp>
10
+ //#include <boost/thread/detail/move.hpp>
11
+ //#include <boost/thread/exceptions.hpp>
12
+ //
13
+ //#ifdef BOOST_THREAD_USES_CHRONO
14
+ //#include <boost/chrono/time_point.hpp>
15
+ //#include <boost/chrono/duration.hpp>
16
+ //#endif
17
+
18
+ #include <boost/type_traits/integral_constant.hpp>
19
+
20
+ #include <boost/config/abi_prefix.hpp>
21
+
22
+ namespace boost
23
+ {
24
+
25
+ /**
26
+ * An strict lock is a lock ensuring the mutex is locked on the scope of the lock
27
+ * There is no single way to define a strict lock as the strict_lock and
28
+ * nesteed_strict_lock shows. So we need a metafunction that states if a
29
+ * lock is a strict lock "sur parole".
30
+ */
31
+
32
+ template <typename Lock>
33
+ struct is_strict_lock_sur_parolle : false_type {};
34
+
35
+
36
+ template <typename Lock>
37
+ struct is_strict_lock_sur_parole : is_strict_lock_sur_parolle<Lock> {};
38
+
39
+ template <typename Lock>
40
+ struct is_strict_lock : is_strict_lock_sur_parole<Lock> {};
41
+
42
+ }
43
+ #include <boost/config/abi_suffix.hpp>
44
+
45
+ #endif
@@ -0,0 +1,1226 @@
1
+ // Distributed under the Boost Software License, Version 1.0. (See
2
+ // accompanying file LICENSE_1_0.txt or copy at
3
+ // http://www.boost.org/LICENSE_1_0.txt)
4
+ // (C) Copyright 2007 Anthony Williams
5
+ // (C) Copyright 2011-2012 Vicente J. Botet Escriba
6
+
7
+ #ifndef BOOST_THREAD_LOCK_TYPES_HPP
8
+ #define BOOST_THREAD_LOCK_TYPES_HPP
9
+
10
+ #include <boost/thread/detail/config.hpp>
11
+ #include <boost/thread/detail/move.hpp>
12
+ #include <boost/thread/exceptions.hpp>
13
+ #include <boost/thread/lock_options.hpp>
14
+ #include <boost/thread/lockable_traits.hpp>
15
+ #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
16
+ #include <boost/thread/is_locked_by_this_thread.hpp>
17
+ #endif
18
+ #include <boost/thread/thread_time.hpp>
19
+
20
+ #include <boost/assert.hpp>
21
+ #ifdef BOOST_THREAD_USES_CHRONO
22
+ #include <boost/chrono/time_point.hpp>
23
+ #include <boost/chrono/duration.hpp>
24
+ #endif
25
+ #include <boost/detail/workaround.hpp>
26
+
27
+ #include <boost/config/abi_prefix.hpp>
28
+
29
+ namespace boost
30
+ {
31
+ struct xtime;
32
+
33
+ template <typename Mutex>
34
+ class shared_lock;
35
+
36
+ template <typename Mutex>
37
+ class upgrade_lock;
38
+
39
+ template <typename Mutex>
40
+ class unique_lock;
41
+
42
+ namespace detail
43
+ {
44
+ template <typename Mutex>
45
+ class try_lock_wrapper;
46
+ }
47
+
48
+ #ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
49
+ namespace sync
50
+ {
51
+ template<typename T>
52
+ struct is_basic_lockable<unique_lock<T> >
53
+ {
54
+ BOOST_STATIC_CONSTANT(bool, value = true);
55
+ };
56
+ template<typename T>
57
+ struct is_lockable<unique_lock<T> >
58
+ {
59
+ BOOST_STATIC_CONSTANT(bool, value = true);
60
+ };
61
+
62
+ template<typename T>
63
+ struct is_basic_lockable<shared_lock<T> >
64
+ {
65
+ BOOST_STATIC_CONSTANT(bool, value = true);
66
+ };
67
+ template<typename T>
68
+ struct is_lockable<shared_lock<T> >
69
+ {
70
+ BOOST_STATIC_CONSTANT(bool, value = true);
71
+ };
72
+
73
+ template<typename T>
74
+ struct is_basic_lockable<upgrade_lock<T> >
75
+ {
76
+ BOOST_STATIC_CONSTANT(bool, value = true);
77
+ };
78
+ template<typename T>
79
+ struct is_lockable<upgrade_lock<T> >
80
+ {
81
+ BOOST_STATIC_CONSTANT(bool, value = true);
82
+ };
83
+
84
+ template<typename T>
85
+ struct is_basic_lockable<detail::try_lock_wrapper<T> >
86
+ {
87
+ BOOST_STATIC_CONSTANT(bool, value = true);
88
+ };
89
+ template<typename T>
90
+ struct is_lockable<detail::try_lock_wrapper<T> >
91
+ {
92
+ BOOST_STATIC_CONSTANT(bool, value = true);
93
+ };
94
+ }
95
+ #endif
96
+
97
+
98
+ template <typename Mutex>
99
+ class unique_lock
100
+ {
101
+ private:
102
+ Mutex* m;
103
+ bool is_locked;
104
+
105
+ private:
106
+ explicit unique_lock(upgrade_lock<Mutex>&);
107
+ unique_lock& operator=(upgrade_lock<Mutex>& other);
108
+ public:
109
+ typedef Mutex mutex_type;
110
+ BOOST_THREAD_MOVABLE_ONLY( unique_lock)
111
+
112
+ #if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
113
+ #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
114
+ unique_lock(const volatile unique_lock&);
115
+ #endif
116
+ #endif
117
+ unique_lock()BOOST_NOEXCEPT :
118
+ m(0),is_locked(false)
119
+ {}
120
+
121
+ explicit unique_lock(Mutex& m_) :
122
+ m(&m_), is_locked(false)
123
+ {
124
+ lock();
125
+ }
126
+ unique_lock(Mutex& m_, adopt_lock_t) :
127
+ m(&m_), is_locked(true)
128
+ {
129
+ #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
130
+ BOOST_ASSERT(is_locked_by_this_thread(m));
131
+ #endif
132
+ }
133
+ unique_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT:
134
+ m(&m_),is_locked(false)
135
+ {}
136
+ unique_lock(Mutex& m_, try_to_lock_t) :
137
+ m(&m_), is_locked(false)
138
+ {
139
+ try_lock();
140
+ }
141
+ #if defined BOOST_THREAD_USES_DATETIME
142
+ template<typename TimeDuration>
143
+ unique_lock(Mutex& m_,TimeDuration const& target_time):
144
+ m(&m_),is_locked(false)
145
+ {
146
+ timed_lock(target_time);
147
+ }
148
+ unique_lock(Mutex& m_,system_time const& target_time):
149
+ m(&m_),is_locked(false)
150
+ {
151
+ timed_lock(target_time);
152
+ }
153
+ #endif
154
+ #ifdef BOOST_THREAD_USES_CHRONO
155
+ template <class Clock, class Duration>
156
+ unique_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
157
+ : m(&mtx), is_locked(mtx.try_lock_until(t))
158
+ {
159
+ }
160
+ template <class Rep, class Period>
161
+ unique_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
162
+ : m(&mtx), is_locked(mtx.try_lock_for(d))
163
+ {
164
+ }
165
+ #endif
166
+
167
+ unique_lock(BOOST_THREAD_RV_REF(unique_lock) other) BOOST_NOEXCEPT:
168
+ m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
169
+ {
170
+ BOOST_THREAD_RV(other).is_locked=false;
171
+ BOOST_THREAD_RV(other).m=0;
172
+ }
173
+
174
+ BOOST_THREAD_EXPLICIT_LOCK_CONVERSION unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other);
175
+
176
+ #ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
177
+ //std-2104 unique_lock move-assignment should not be noexcept
178
+ unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
179
+ {
180
+ unique_lock temp(::boost::move(other));
181
+ swap(temp);
182
+ return *this;
183
+ }
184
+ #endif
185
+
186
+ //std-2104 unique_lock move-assignment should not be noexcept
187
+ unique_lock& operator=(BOOST_THREAD_RV_REF(unique_lock) other) //BOOST_NOEXCEPT
188
+ {
189
+ unique_lock temp(::boost::move(other));
190
+ swap(temp);
191
+ return *this;
192
+ }
193
+ #if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
194
+ #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
195
+ unique_lock& operator=(unique_lock<Mutex> other)
196
+ {
197
+ swap(other);
198
+ return *this;
199
+ }
200
+ #endif // BOOST_WORKAROUND
201
+ #endif
202
+
203
+ // Conversion from upgrade locking
204
+ unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul, try_to_lock_t)
205
+ : m(0),is_locked(false)
206
+ {
207
+ if (BOOST_THREAD_RV(ul).owns_lock())
208
+ {
209
+ if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock())
210
+ {
211
+ m = BOOST_THREAD_RV(ul).release();
212
+ is_locked = true;
213
+ }
214
+ }
215
+ else
216
+ {
217
+ m = BOOST_THREAD_RV(ul).release();
218
+ }
219
+ }
220
+
221
+ #ifdef BOOST_THREAD_USES_CHRONO
222
+ template <class Clock, class Duration>
223
+ unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,
224
+ const chrono::time_point<Clock, Duration>& abs_time)
225
+ : m(0),is_locked(false)
226
+ {
227
+ if (BOOST_THREAD_RV(ul).owns_lock())
228
+ {
229
+ if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_until(abs_time))
230
+ {
231
+ m = BOOST_THREAD_RV(ul).release();
232
+ is_locked = true;
233
+ }
234
+ }
235
+ else
236
+ {
237
+ m = BOOST_THREAD_RV(ul).release();
238
+ }
239
+ }
240
+
241
+ template <class Rep, class Period>
242
+ unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,
243
+ const chrono::duration<Rep, Period>& rel_time)
244
+ : m(0),is_locked(false)
245
+ {
246
+ if (BOOST_THREAD_RV(ul).owns_lock())
247
+ {
248
+ if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_for(rel_time))
249
+ {
250
+ m = BOOST_THREAD_RV(ul).release();
251
+ is_locked = true;
252
+ }
253
+ }
254
+ else
255
+ {
256
+ m = BOOST_THREAD_RV(ul).release();
257
+ }
258
+ }
259
+ #endif
260
+
261
+ #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
262
+ // Conversion from shared locking
263
+ unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t)
264
+ : m(0),is_locked(false)
265
+ {
266
+ if (BOOST_THREAD_RV(sl).owns_lock())
267
+ {
268
+ if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock())
269
+ {
270
+ m = BOOST_THREAD_RV(sl).release();
271
+ is_locked = true;
272
+ }
273
+ }
274
+ else
275
+ {
276
+ m = BOOST_THREAD_RV(sl).release();
277
+ }
278
+ }
279
+
280
+ #ifdef BOOST_THREAD_USES_CHRONO
281
+ template <class Clock, class Duration>
282
+ unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
283
+ const chrono::time_point<Clock, Duration>& abs_time)
284
+ : m(0),is_locked(false)
285
+ {
286
+ if (BOOST_THREAD_RV(sl).owns_lock())
287
+ {
288
+ if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_until(abs_time))
289
+ {
290
+ m = BOOST_THREAD_RV(sl).release();
291
+ is_locked = true;
292
+ }
293
+ }
294
+ else
295
+ {
296
+ m = BOOST_THREAD_RV(sl).release();
297
+ }
298
+ }
299
+
300
+ template <class Rep, class Period>
301
+ unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
302
+ const chrono::duration<Rep, Period>& rel_time)
303
+ : m(0),is_locked(false)
304
+ {
305
+ if (BOOST_THREAD_RV(sl).owns_lock())
306
+ {
307
+ if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_for(rel_time))
308
+ {
309
+ m = BOOST_THREAD_RV(sl).release();
310
+ is_locked = true;
311
+ }
312
+ }
313
+ else
314
+ {
315
+ m = BOOST_THREAD_RV(sl).release();
316
+ }
317
+ }
318
+ #endif // BOOST_THREAD_USES_CHRONO
319
+ #endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
320
+
321
+ void swap(unique_lock& other)BOOST_NOEXCEPT
322
+ {
323
+ std::swap(m,other.m);
324
+ std::swap(is_locked,other.is_locked);
325
+ }
326
+
327
+ ~unique_lock()
328
+ {
329
+ if (owns_lock())
330
+ {
331
+ m->unlock();
332
+ }
333
+ }
334
+ void lock()
335
+ {
336
+ if (m == 0)
337
+ {
338
+ boost::throw_exception(
339
+ boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
340
+ }
341
+ if (owns_lock())
342
+ {
343
+ boost::throw_exception(
344
+ boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
345
+ }
346
+ m->lock();
347
+ is_locked = true;
348
+ }
349
+ bool try_lock()
350
+ {
351
+ if (m == 0)
352
+ {
353
+ boost::throw_exception(
354
+ boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
355
+ }
356
+ if (owns_lock())
357
+ {
358
+ boost::throw_exception(
359
+ boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
360
+ }
361
+ is_locked = m->try_lock();
362
+ return is_locked;
363
+ }
364
+ #if defined BOOST_THREAD_USES_DATETIME
365
+ template<typename TimeDuration>
366
+ bool timed_lock(TimeDuration const& relative_time)
367
+ {
368
+ if(m==0)
369
+ {
370
+ boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
371
+ }
372
+ if(owns_lock())
373
+ {
374
+ boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
375
+ }
376
+ is_locked=m->timed_lock(relative_time);
377
+ return is_locked;
378
+ }
379
+
380
+ bool timed_lock(::boost::system_time const& absolute_time)
381
+ {
382
+ if(m==0)
383
+ {
384
+ boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
385
+ }
386
+ if(owns_lock())
387
+ {
388
+ boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
389
+ }
390
+ is_locked=m->timed_lock(absolute_time);
391
+ return is_locked;
392
+ }
393
+ bool timed_lock(::boost::xtime const& absolute_time)
394
+ {
395
+ if(m==0)
396
+ {
397
+ boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
398
+ }
399
+ if(owns_lock())
400
+ {
401
+ boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
402
+ }
403
+ is_locked=m->timed_lock(absolute_time);
404
+ return is_locked;
405
+ }
406
+ #endif
407
+ #ifdef BOOST_THREAD_USES_CHRONO
408
+
409
+ template <class Rep, class Period>
410
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
411
+ {
412
+ if(m==0)
413
+ {
414
+ boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
415
+ }
416
+ if(owns_lock())
417
+ {
418
+ boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
419
+ }
420
+ is_locked=m->try_lock_for(rel_time);
421
+ return is_locked;
422
+ }
423
+ template <class Clock, class Duration>
424
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
425
+ {
426
+ if(m==0)
427
+ {
428
+ boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
429
+ }
430
+ if(owns_lock())
431
+ {
432
+ boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
433
+ }
434
+ is_locked=m->try_lock_until(abs_time);
435
+ return is_locked;
436
+ }
437
+ #endif
438
+
439
+ void unlock()
440
+ {
441
+ if (m == 0)
442
+ {
443
+ boost::throw_exception(
444
+ boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
445
+ }
446
+ if (!owns_lock())
447
+ {
448
+ boost::throw_exception(
449
+ boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock doesn't own the mutex"));
450
+ }
451
+ m->unlock();
452
+ is_locked = false;
453
+ }
454
+
455
+ #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
456
+ typedef void (unique_lock::*bool_type)();
457
+ operator bool_type() const BOOST_NOEXCEPT
458
+ {
459
+ return is_locked?&unique_lock::lock:0;
460
+ }
461
+ bool operator!() const BOOST_NOEXCEPT
462
+ {
463
+ return !owns_lock();
464
+ }
465
+ #else
466
+ explicit operator bool() const BOOST_NOEXCEPT
467
+ {
468
+ return owns_lock();
469
+ }
470
+ #endif
471
+ bool owns_lock() const BOOST_NOEXCEPT
472
+ {
473
+ return is_locked;
474
+ }
475
+
476
+ Mutex* mutex() const BOOST_NOEXCEPT
477
+ {
478
+ return m;
479
+ }
480
+
481
+ Mutex* release()BOOST_NOEXCEPT
482
+ {
483
+ Mutex* const res=m;
484
+ m=0;
485
+ is_locked=false;
486
+ return res;
487
+ }
488
+
489
+ friend class shared_lock<Mutex> ;
490
+ friend class upgrade_lock<Mutex> ;
491
+ };
492
+
493
+ template<typename Mutex>
494
+ void swap(unique_lock<Mutex>& lhs, unique_lock<Mutex>& rhs)
495
+ BOOST_NOEXCEPT
496
+ {
497
+ lhs.swap(rhs);
498
+ }
499
+
500
+ BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
501
+
502
+ template<typename Mutex>
503
+ class shared_lock
504
+ {
505
+ protected:
506
+ Mutex* m;
507
+ bool is_locked;
508
+
509
+ public:
510
+ typedef Mutex mutex_type;
511
+ BOOST_THREAD_MOVABLE_ONLY(shared_lock)
512
+
513
+ shared_lock() BOOST_NOEXCEPT:
514
+ m(0),is_locked(false)
515
+ {}
516
+
517
+ explicit shared_lock(Mutex& m_):
518
+ m(&m_),is_locked(false)
519
+ {
520
+ lock();
521
+ }
522
+ shared_lock(Mutex& m_,adopt_lock_t):
523
+ m(&m_),is_locked(true)
524
+ {
525
+ #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
526
+ BOOST_ASSERT(is_locked_by_this_thread(m));
527
+ #endif
528
+ }
529
+ shared_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT:
530
+ m(&m_),is_locked(false)
531
+ {}
532
+ shared_lock(Mutex& m_,try_to_lock_t):
533
+ m(&m_),is_locked(false)
534
+ {
535
+ try_lock();
536
+ }
537
+ #if defined BOOST_THREAD_USES_DATETIME
538
+ shared_lock(Mutex& m_,system_time const& target_time):
539
+ m(&m_),is_locked(false)
540
+ {
541
+ timed_lock(target_time);
542
+ }
543
+ #endif
544
+ #ifdef BOOST_THREAD_USES_CHRONO
545
+ template <class Clock, class Duration>
546
+ shared_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
547
+ : m(&mtx), is_locked(mtx.try_lock_shared_until(t))
548
+ {
549
+ }
550
+ template <class Rep, class Period>
551
+ shared_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
552
+ : m(&mtx), is_locked(mtx.try_lock_shared_for(d))
553
+ {
554
+ }
555
+ #endif
556
+
557
+ shared_lock(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT:
558
+ m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
559
+ {
560
+ BOOST_THREAD_RV(other).is_locked=false;
561
+ BOOST_THREAD_RV(other).m=0;
562
+ }
563
+
564
+ BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other):
565
+ m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
566
+ {
567
+ if(is_locked)
568
+ {
569
+ m->unlock_and_lock_shared();
570
+ }
571
+ BOOST_THREAD_RV(other).is_locked=false;
572
+ BOOST_THREAD_RV(other).m=0;
573
+ }
574
+
575
+ BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other):
576
+ m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
577
+ {
578
+ if(is_locked)
579
+ {
580
+ m->unlock_upgrade_and_lock_shared();
581
+ }
582
+ BOOST_THREAD_RV(other).is_locked=false;
583
+ BOOST_THREAD_RV(other).m=0;
584
+ }
585
+
586
+ //std-2104 unique_lock move-assignment should not be noexcept
587
+ shared_lock& operator=(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
588
+ {
589
+ shared_lock temp(::boost::move(other));
590
+ swap(temp);
591
+ return *this;
592
+ }
593
+ #ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
594
+ shared_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)
595
+ {
596
+ shared_lock temp(::boost::move(other));
597
+ swap(temp);
598
+ return *this;
599
+ }
600
+
601
+ shared_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)
602
+ {
603
+ shared_lock temp(::boost::move(other));
604
+ swap(temp);
605
+ return *this;
606
+ }
607
+ #endif
608
+
609
+ void swap(shared_lock& other) BOOST_NOEXCEPT
610
+ {
611
+ std::swap(m,other.m);
612
+ std::swap(is_locked,other.is_locked);
613
+ }
614
+
615
+ Mutex* mutex() const BOOST_NOEXCEPT
616
+ {
617
+ return m;
618
+ }
619
+
620
+ Mutex* release() BOOST_NOEXCEPT
621
+ {
622
+ Mutex* const res=m;
623
+ m=0;
624
+ is_locked=false;
625
+ return res;
626
+ }
627
+
628
+ ~shared_lock()
629
+ {
630
+ if(owns_lock())
631
+ {
632
+ m->unlock_shared();
633
+ }
634
+ }
635
+ void lock()
636
+ {
637
+ if(m==0)
638
+ {
639
+ boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
640
+ }
641
+ if(owns_lock())
642
+ {
643
+ boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
644
+ }
645
+ m->lock_shared();
646
+ is_locked=true;
647
+ }
648
+ bool try_lock()
649
+ {
650
+ if(m==0)
651
+ {
652
+ boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
653
+ }
654
+ if(owns_lock())
655
+ {
656
+ boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
657
+ }
658
+ is_locked=m->try_lock_shared();
659
+ return is_locked;
660
+ }
661
+ #if defined BOOST_THREAD_USES_DATETIME
662
+ bool timed_lock(boost::system_time const& target_time)
663
+ {
664
+ if(m==0)
665
+ {
666
+ boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
667
+ }
668
+ if(owns_lock())
669
+ {
670
+ boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
671
+ }
672
+ is_locked=m->timed_lock_shared(target_time);
673
+ return is_locked;
674
+ }
675
+ template<typename Duration>
676
+ bool timed_lock(Duration const& target_time)
677
+ {
678
+ if(m==0)
679
+ {
680
+ boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
681
+ }
682
+ if(owns_lock())
683
+ {
684
+ boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
685
+ }
686
+ is_locked=m->timed_lock_shared(target_time);
687
+ return is_locked;
688
+ }
689
+ #endif
690
+ #ifdef BOOST_THREAD_USES_CHRONO
691
+ template <class Rep, class Period>
692
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
693
+ {
694
+ if(m==0)
695
+ {
696
+ boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
697
+ }
698
+ if(owns_lock())
699
+ {
700
+ boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
701
+ }
702
+ is_locked=m->try_lock_shared_for(rel_time);
703
+ return is_locked;
704
+ }
705
+ template <class Clock, class Duration>
706
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
707
+ {
708
+ if(m==0)
709
+ {
710
+ boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
711
+ }
712
+ if(owns_lock())
713
+ {
714
+ boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
715
+ }
716
+ is_locked=m->try_lock_shared_until(abs_time);
717
+ return is_locked;
718
+ }
719
+ #endif
720
+ void unlock()
721
+ {
722
+ if(m==0)
723
+ {
724
+ boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
725
+ }
726
+ if(!owns_lock())
727
+ {
728
+ boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock doesn't own the mutex"));
729
+ }
730
+ m->unlock_shared();
731
+ is_locked=false;
732
+ }
733
+
734
+ #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
735
+ typedef void (shared_lock<Mutex>::*bool_type)();
736
+ operator bool_type() const BOOST_NOEXCEPT
737
+ {
738
+ return is_locked?&shared_lock::lock:0;
739
+ }
740
+ bool operator!() const BOOST_NOEXCEPT
741
+ {
742
+ return !owns_lock();
743
+ }
744
+ #else
745
+ explicit operator bool() const BOOST_NOEXCEPT
746
+ {
747
+ return owns_lock();
748
+ }
749
+ #endif
750
+ bool owns_lock() const BOOST_NOEXCEPT
751
+ {
752
+ return is_locked;
753
+ }
754
+
755
+ };
756
+
757
+ BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) shared_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
758
+
759
+ template<typename Mutex>
760
+ void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs) BOOST_NOEXCEPT
761
+ {
762
+ lhs.swap(rhs);
763
+ }
764
+
765
+ template <typename Mutex>
766
+ class upgrade_lock
767
+ {
768
+ protected:
769
+ Mutex* m;
770
+ bool is_locked;
771
+
772
+ public:
773
+ typedef Mutex mutex_type;
774
+ BOOST_THREAD_MOVABLE_ONLY( upgrade_lock)
775
+
776
+ upgrade_lock()BOOST_NOEXCEPT:
777
+ m(0),is_locked(false)
778
+ {}
779
+
780
+ explicit upgrade_lock(Mutex& m_) :
781
+ m(&m_), is_locked(false)
782
+ {
783
+ lock();
784
+ }
785
+ upgrade_lock(Mutex& m_, adopt_lock_t) :
786
+ m(&m_), is_locked(true)
787
+ {
788
+ #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
789
+ BOOST_ASSERT(is_locked_by_this_thread(m));
790
+ #endif
791
+ }
792
+ upgrade_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT:
793
+ m(&m_),is_locked(false)
794
+ {}
795
+ upgrade_lock(Mutex& m_, try_to_lock_t) :
796
+ m(&m_), is_locked(false)
797
+ {
798
+ try_lock();
799
+ }
800
+
801
+ #ifdef BOOST_THREAD_USES_CHRONO
802
+ template <class Clock, class Duration>
803
+ upgrade_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
804
+ : m(&mtx), is_locked(mtx.try_lock_upgrade_until(t))
805
+ {
806
+ }
807
+ template <class Rep, class Period>
808
+ upgrade_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
809
+ : m(&mtx), is_locked(mtx.try_lock_upgrade_for(d))
810
+ {
811
+ }
812
+ #endif
813
+
814
+ upgrade_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT:
815
+ m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
816
+ {
817
+ BOOST_THREAD_RV(other).is_locked=false;
818
+ BOOST_THREAD_RV(other).m=0;
819
+ }
820
+
821
+ BOOST_THREAD_EXPLICIT_LOCK_CONVERSION upgrade_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other):
822
+ m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
823
+ {
824
+ if(is_locked)
825
+ {
826
+ m->unlock_and_lock_upgrade();
827
+ }
828
+ BOOST_THREAD_RV(other).is_locked=false;
829
+ BOOST_THREAD_RV(other).m=0;
830
+ }
831
+
832
+ //std-2104 unique_lock move-assignment should not be noexcept
833
+ upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
834
+ {
835
+ upgrade_lock temp(::boost::move(other));
836
+ swap(temp);
837
+ return *this;
838
+ }
839
+
840
+ #ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
841
+ upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)
842
+ {
843
+ upgrade_lock temp(::boost::move(other));
844
+ swap(temp);
845
+ return *this;
846
+ }
847
+ #endif
848
+
849
+ #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
850
+ // Conversion from shared locking
851
+ upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t)
852
+ : m(0),is_locked(false)
853
+ {
854
+ if (BOOST_THREAD_RV(sl).owns_lock())
855
+ {
856
+ if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade())
857
+ {
858
+ m = BOOST_THREAD_RV(sl).release();
859
+ is_locked = true;
860
+ }
861
+ }
862
+ else
863
+ {
864
+ m = BOOST_THREAD_RV(sl).release();
865
+ }
866
+ }
867
+
868
+ #ifdef BOOST_THREAD_USES_CHRONO
869
+ template <class Clock, class Duration>
870
+ upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
871
+ const chrono::time_point<Clock, Duration>& abs_time)
872
+ : m(0),is_locked(false)
873
+ {
874
+ if (BOOST_THREAD_RV(sl).owns_lock())
875
+ {
876
+ if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time))
877
+ {
878
+ m = BOOST_THREAD_RV(sl).release();
879
+ is_locked = true;
880
+ }
881
+ }
882
+ else
883
+ {
884
+ m = BOOST_THREAD_RV(sl).release();
885
+ }
886
+ }
887
+
888
+ template <class Rep, class Period>
889
+ upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
890
+ const chrono::duration<Rep, Period>& rel_time)
891
+ : m(0),is_locked(false)
892
+ {
893
+ if (BOOST_THREAD_RV(sl).owns_lock())
894
+ {
895
+ if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time))
896
+ {
897
+ m = BOOST_THREAD_RV(sl).release();
898
+ is_locked = true;
899
+ }
900
+ }
901
+ else
902
+ {
903
+ m = BOOST_THREAD_RV(sl).release();
904
+ }
905
+ }
906
+ #endif // BOOST_THREAD_USES_CHRONO
907
+ #endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
908
+ void swap(upgrade_lock& other)BOOST_NOEXCEPT
909
+ {
910
+ std::swap(m,other.m);
911
+ std::swap(is_locked,other.is_locked);
912
+ }
913
+ Mutex* mutex() const BOOST_NOEXCEPT
914
+ {
915
+ return m;
916
+ }
917
+
918
+ Mutex* release()BOOST_NOEXCEPT
919
+ {
920
+ Mutex* const res=m;
921
+ m=0;
922
+ is_locked=false;
923
+ return res;
924
+ }
925
+ ~upgrade_lock()
926
+ {
927
+ if (owns_lock())
928
+ {
929
+ m->unlock_upgrade();
930
+ }
931
+ }
932
+ void lock()
933
+ {
934
+ if (m == 0)
935
+ {
936
+ boost::throw_exception(
937
+ boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
938
+ }
939
+ if (owns_lock())
940
+ {
941
+ boost::throw_exception(
942
+ boost::lock_error(system::errc::resource_deadlock_would_occur, "boost upgrade_lock owns already the mutex"));
943
+ }
944
+ m->lock_upgrade();
945
+ is_locked = true;
946
+ }
947
+ bool try_lock()
948
+ {
949
+ if (m == 0)
950
+ {
951
+ boost::throw_exception(
952
+ boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
953
+ }
954
+ if (owns_lock())
955
+ {
956
+ boost::throw_exception(
957
+ boost::lock_error(system::errc::resource_deadlock_would_occur, "boost upgrade_lock owns already the mutex"));
958
+ }
959
+ is_locked = m->try_lock_upgrade();
960
+ return is_locked;
961
+ }
962
+ void unlock()
963
+ {
964
+ if (m == 0)
965
+ {
966
+ boost::throw_exception(
967
+ boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
968
+ }
969
+ if (!owns_lock())
970
+ {
971
+ boost::throw_exception(
972
+ boost::lock_error(system::errc::operation_not_permitted, "boost upgrade_lock doesn't own the mutex"));
973
+ }
974
+ m->unlock_upgrade();
975
+ is_locked = false;
976
+ }
977
+ #ifdef BOOST_THREAD_USES_CHRONO
978
+ template <class Rep, class Period>
979
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
980
+ {
981
+ if(m==0)
982
+ {
983
+ boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
984
+ }
985
+ if(owns_lock())
986
+ {
987
+ boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
988
+ }
989
+ is_locked=m->try_lock_upgrade_for(rel_time);
990
+ return is_locked;
991
+ }
992
+ template <class Clock, class Duration>
993
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
994
+ {
995
+ if(m==0)
996
+ {
997
+ boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
998
+ }
999
+ if(owns_lock())
1000
+ {
1001
+ boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
1002
+ }
1003
+ is_locked=m->try_lock_upgrade_until(abs_time);
1004
+ return is_locked;
1005
+ }
1006
+ #endif
1007
+ #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
1008
+ typedef void (upgrade_lock::*bool_type)();
1009
+ operator bool_type() const BOOST_NOEXCEPT
1010
+ {
1011
+ return is_locked?&upgrade_lock::lock:0;
1012
+ }
1013
+ bool operator!() const BOOST_NOEXCEPT
1014
+ {
1015
+ return !owns_lock();
1016
+ }
1017
+ #else
1018
+ explicit operator bool() const BOOST_NOEXCEPT
1019
+ {
1020
+ return owns_lock();
1021
+ }
1022
+ #endif
1023
+ bool owns_lock() const BOOST_NOEXCEPT
1024
+ {
1025
+ return is_locked;
1026
+ }
1027
+ friend class shared_lock<Mutex> ;
1028
+ friend class unique_lock<Mutex> ;
1029
+ };
1030
+
1031
+ template<typename Mutex>
1032
+ void swap(upgrade_lock<Mutex>& lhs, upgrade_lock<Mutex>& rhs)
1033
+ BOOST_NOEXCEPT
1034
+ {
1035
+ lhs.swap(rhs);
1036
+ }
1037
+
1038
+ BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
1039
+
1040
+ template<typename Mutex>
1041
+ unique_lock<Mutex>::unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other):
1042
+ m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
1043
+ {
1044
+ if(is_locked)
1045
+ {
1046
+ m->unlock_upgrade_and_lock();
1047
+ }
1048
+ BOOST_THREAD_RV(other).release();
1049
+ }
1050
+
1051
+ template <class Mutex>
1052
+ class upgrade_to_unique_lock
1053
+ {
1054
+ private:
1055
+ upgrade_lock<Mutex>* source;
1056
+ unique_lock<Mutex> exclusive;
1057
+
1058
+ public:
1059
+ typedef Mutex mutex_type;
1060
+ BOOST_THREAD_MOVABLE_ONLY( upgrade_to_unique_lock)
1061
+
1062
+ explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_) :
1063
+ source(&m_), exclusive(::boost::move(*source))
1064
+ {
1065
+ }
1066
+ ~upgrade_to_unique_lock()
1067
+ {
1068
+ if (source)
1069
+ {
1070
+ *source = BOOST_THREAD_MAKE_RV_REF(upgrade_lock<Mutex> (::boost::move(exclusive)));
1071
+ }
1072
+ }
1073
+
1074
+ upgrade_to_unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT:
1075
+ source(BOOST_THREAD_RV(other).source),exclusive(::boost::move(BOOST_THREAD_RV(other).exclusive))
1076
+ {
1077
+ BOOST_THREAD_RV(other).source=0;
1078
+ }
1079
+
1080
+ //std-2104 unique_lock move-assignment should not be noexcept
1081
+ upgrade_to_unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
1082
+ {
1083
+ upgrade_to_unique_lock temp(other);
1084
+ swap(temp);
1085
+ return *this;
1086
+ }
1087
+
1088
+ void swap(upgrade_to_unique_lock& other)BOOST_NOEXCEPT
1089
+ {
1090
+ std::swap(source,other.source);
1091
+ exclusive.swap(other.exclusive);
1092
+ }
1093
+
1094
+ #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
1095
+ typedef void (upgrade_to_unique_lock::*bool_type)(upgrade_to_unique_lock&);
1096
+ operator bool_type() const BOOST_NOEXCEPT
1097
+ {
1098
+ return exclusive.owns_lock()?&upgrade_to_unique_lock::swap:0;
1099
+ }
1100
+ bool operator!() const BOOST_NOEXCEPT
1101
+ {
1102
+ return !owns_lock();
1103
+ }
1104
+ #else
1105
+ explicit operator bool() const BOOST_NOEXCEPT
1106
+ {
1107
+ return owns_lock();
1108
+ }
1109
+ #endif
1110
+
1111
+ bool owns_lock() const BOOST_NOEXCEPT
1112
+ {
1113
+ return exclusive.owns_lock();
1114
+ }
1115
+ };
1116
+
1117
+ BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_to_unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
1118
+
1119
+ namespace detail
1120
+ {
1121
+ template<typename Mutex>
1122
+ class try_lock_wrapper:
1123
+ private unique_lock<Mutex>
1124
+ {
1125
+ typedef unique_lock<Mutex> base;
1126
+ public:
1127
+ BOOST_THREAD_MOVABLE_ONLY(try_lock_wrapper)
1128
+
1129
+ try_lock_wrapper()
1130
+ {}
1131
+
1132
+ explicit try_lock_wrapper(Mutex& m):
1133
+ base(m,try_to_lock)
1134
+ {}
1135
+
1136
+ try_lock_wrapper(Mutex& m_,adopt_lock_t):
1137
+ base(m_,adopt_lock)
1138
+ {
1139
+ #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
1140
+ BOOST_ASSERT(is_locked_by_this_thread(m_));
1141
+ #endif
1142
+ }
1143
+ try_lock_wrapper(Mutex& m_,defer_lock_t):
1144
+ base(m_,defer_lock)
1145
+ {}
1146
+ try_lock_wrapper(Mutex& m_,try_to_lock_t):
1147
+ base(m_,try_to_lock)
1148
+ {}
1149
+ #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1150
+ try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
1151
+ base(::boost::move(other))
1152
+ {}
1153
+
1154
+ #elif defined BOOST_THREAD_USES_MOVE
1155
+ try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
1156
+ base(::boost::move(static_cast<base&>(other)))
1157
+ {}
1158
+
1159
+ #else
1160
+ try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
1161
+ base(BOOST_THREAD_RV_REF(base)(*other))
1162
+ {}
1163
+ #endif
1164
+ try_lock_wrapper& operator=(BOOST_THREAD_RV_REF_BEG try_lock_wrapper<Mutex> BOOST_THREAD_RV_REF_END other)
1165
+ {
1166
+ try_lock_wrapper temp(other);
1167
+ swap(temp);
1168
+ return *this;
1169
+ }
1170
+ void swap(try_lock_wrapper& other)
1171
+ {
1172
+ base::swap(other);
1173
+ }
1174
+ void lock()
1175
+ {
1176
+ base::lock();
1177
+ }
1178
+ bool try_lock()
1179
+ {
1180
+ return base::try_lock();
1181
+ }
1182
+ void unlock()
1183
+ {
1184
+ base::unlock();
1185
+ }
1186
+ bool owns_lock() const
1187
+ {
1188
+ return base::owns_lock();
1189
+ }
1190
+ Mutex* mutex() const
1191
+ {
1192
+ return base::mutex();
1193
+ }
1194
+ Mutex* release()
1195
+ {
1196
+ return base::release();
1197
+ }
1198
+
1199
+ #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
1200
+ typedef typename base::bool_type bool_type;
1201
+ operator bool_type() const
1202
+ {
1203
+ return base::operator bool_type();
1204
+ }
1205
+ bool operator!() const
1206
+ {
1207
+ return !this->owns_lock();
1208
+ }
1209
+ #else
1210
+ explicit operator bool() const
1211
+ {
1212
+ return owns_lock();
1213
+ }
1214
+ #endif
1215
+ };
1216
+
1217
+ template<typename Mutex>
1218
+ void swap(try_lock_wrapper<Mutex>& lhs,try_lock_wrapper<Mutex>& rhs)
1219
+ {
1220
+ lhs.swap(rhs);
1221
+ }
1222
+ }
1223
+ }
1224
+ #include <boost/config/abi_suffix.hpp>
1225
+
1226
+ #endif