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,1001 @@
1
+ // (C) Copyright 2010 Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
2
+ // (C) Copyright 2012 Vicente J. Botet Escriba
3
+ // Distributed under the Boost Software License, Version 1.0. (See
4
+ // accompanying file LICENSE_1_0.txt or copy at
5
+ // http://www.boost.org/LICENSE_1_0.txt)
6
+
7
+
8
+ #ifndef BOOST_THREAD_SYNCHRONIZED_VALUE_HPP
9
+ #define BOOST_THREAD_SYNCHRONIZED_VALUE_HPP
10
+
11
+ #include <boost/thread/detail/config.hpp>
12
+
13
+ #include <boost/thread/detail/move.hpp>
14
+ #include <boost/thread/mutex.hpp>
15
+ #include <boost/thread/lock_types.hpp>
16
+ #include <boost/thread/lock_guard.hpp>
17
+ #include <boost/thread/lock_algorithms.hpp>
18
+ #include <boost/thread/lock_factories.hpp>
19
+ #include <boost/thread/strict_lock.hpp>
20
+ #include <boost/utility/swap.hpp>
21
+ #include <boost/utility/declval.hpp>
22
+ //#include <boost/type_traits.hpp>
23
+ //#include <boost/thread/detail/is_nothrow_default_constructible.hpp>
24
+ //#if ! defined BOOST_NO_CXX11_HDR_TYPE_TRAITS
25
+ //#include <type_traits>
26
+ //#endif
27
+
28
+ #if ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
29
+ #include <tuple> // todo change to <boost/tuple.hpp> once Boost.Tuple or Boost.Fusion provides Move semantics.
30
+ #include <functional>
31
+ #endif
32
+
33
+ #include <boost/config/abi_prefix.hpp>
34
+
35
+ namespace boost
36
+ {
37
+
38
+ /**
39
+ * strict lock providing a const pointer access to the synchronized value type.
40
+ *
41
+ * @param T the value type.
42
+ * @param Lockable the mutex type protecting the value type.
43
+ */
44
+ template <typename T, typename Lockable = mutex>
45
+ class const_strict_lock_ptr
46
+ {
47
+ public:
48
+ typedef T value_type;
49
+ typedef Lockable mutex_type;
50
+ protected:
51
+
52
+ // this should be a strict_lock, but unique_lock is needed to be able to return it.
53
+ boost::unique_lock<mutex_type> lk_;
54
+ T const& value_;
55
+
56
+ public:
57
+ BOOST_THREAD_MOVABLE_ONLY( const_strict_lock_ptr )
58
+
59
+ /**
60
+ * @param value constant reference of the value to protect.
61
+ * @param mtx reference to the mutex used to protect the value.
62
+ * @effects locks the mutex @c mtx, stores a reference to it and to the value type @c value.
63
+ */
64
+ const_strict_lock_ptr(T const& val, Lockable & mtx) :
65
+ lk_(mtx), value_(val)
66
+ {
67
+ }
68
+ const_strict_lock_ptr(T const& val, Lockable & mtx, adopt_lock_t tag) BOOST_NOEXCEPT :
69
+ lk_(mtx, tag), value_(val)
70
+ {
71
+ }
72
+ /**
73
+ * Move constructor.
74
+ * @effects takes ownership of the mutex owned by @c other, stores a reference to the mutex and the value type of @c other.
75
+ */
76
+ const_strict_lock_ptr(BOOST_THREAD_RV_REF(const_strict_lock_ptr) other) BOOST_NOEXCEPT
77
+ : lk_(boost::move(BOOST_THREAD_RV(other).lk_)),value_(BOOST_THREAD_RV(other).value_)
78
+ {
79
+ }
80
+
81
+ ~const_strict_lock_ptr()
82
+ {
83
+ }
84
+
85
+ /**
86
+ * @return a constant pointer to the protected value
87
+ */
88
+ const T* operator->() const
89
+ {
90
+ return &value_;
91
+ }
92
+
93
+ /**
94
+ * @return a constant reference to the protected value
95
+ */
96
+ const T& operator*() const
97
+ {
98
+ return value_;
99
+ }
100
+
101
+ };
102
+
103
+ /**
104
+ * strict lock providing a pointer access to the synchronized value type.
105
+ *
106
+ * @param T the value type.
107
+ * @param Lockable the mutex type protecting the value type.
108
+ */
109
+ template <typename T, typename Lockable = mutex>
110
+ class strict_lock_ptr : public const_strict_lock_ptr<T,Lockable>
111
+ {
112
+ typedef const_strict_lock_ptr<T,Lockable> base_type;
113
+ public:
114
+ BOOST_THREAD_MOVABLE_ONLY( strict_lock_ptr )
115
+
116
+ /**
117
+ * @param value reference of the value to protect.
118
+ * @param mtx reference to the mutex used to protect the value.
119
+ * @effects locks the mutex @c mtx, stores a reference to it and to the value type @c value.
120
+ */
121
+ strict_lock_ptr(T & val, Lockable & mtx) :
122
+ base_type(val, mtx)
123
+ {
124
+ }
125
+ strict_lock_ptr(T & val, Lockable & mtx, adopt_lock_t tag) :
126
+ base_type(val, mtx, tag)
127
+ {
128
+ }
129
+
130
+ /**
131
+ * Move constructor.
132
+ * @effects takes ownership of the mutex owned by @c other, stores a reference to the mutex and the value type of @c other.
133
+ */
134
+ strict_lock_ptr(BOOST_THREAD_RV_REF(strict_lock_ptr) other)
135
+ : base_type(boost::move(static_cast<base_type&>(other)))
136
+ {
137
+ }
138
+
139
+ ~strict_lock_ptr()
140
+ {
141
+ }
142
+
143
+ /**
144
+ * @return a pointer to the protected value
145
+ */
146
+ T* operator->()
147
+ {
148
+ return const_cast<T*>(&this->value_);
149
+ }
150
+
151
+ /**
152
+ * @return a reference to the protected value
153
+ */
154
+ T& operator*()
155
+ {
156
+ return const_cast<T&>(this->value_);
157
+ }
158
+
159
+ };
160
+
161
+ template <typename SV>
162
+ struct synchronized_value_strict_lock_ptr
163
+ {
164
+ typedef strict_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
165
+ };
166
+
167
+ template <typename SV>
168
+ struct synchronized_value_strict_lock_ptr<const SV>
169
+ {
170
+ typedef const_strict_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
171
+ };
172
+ /**
173
+ * unique_lock providing a const pointer access to the synchronized value type.
174
+ *
175
+ * An object of type const_unique_lock_ptr is a unique_lock that provides a const pointer access to the synchronized value type.
176
+ * As unique_lock controls the ownership of a lockable object within a scope.
177
+ * Ownership of the lockable object may be acquired at construction or after construction,
178
+ * and may be transferred, after acquisition, to another const_unique_lock_ptr object.
179
+ * Objects of type const_unique_lock_ptr are not copyable but are movable.
180
+ * The behavior of a program is undefined if the mutex and the value type
181
+ * pointed do not exist for the entire remaining lifetime of the const_unique_lock_ptr object.
182
+ * The supplied Mutex type shall meet the BasicLockable requirements.
183
+ *
184
+ * @note const_unique_lock_ptr<T, Lockable> meets the Lockable requirements.
185
+ * If Lockable meets the TimedLockable requirements, const_unique_lock_ptr<T,Lockable>
186
+ * also meets the TimedLockable requirements.
187
+ *
188
+ * @param T the value type.
189
+ * @param Lockable the mutex type protecting the value type.
190
+ */
191
+ template <typename T, typename Lockable = mutex>
192
+ class const_unique_lock_ptr : public unique_lock<Lockable>
193
+ {
194
+ typedef unique_lock<Lockable> base_type;
195
+ public:
196
+ typedef T value_type;
197
+ typedef Lockable mutex_type;
198
+ protected:
199
+ T const& value_;
200
+
201
+ public:
202
+ BOOST_THREAD_MOVABLE_ONLY(const_unique_lock_ptr)
203
+
204
+ /**
205
+ * @param value reference of the value to protect.
206
+ * @param mtx reference to the mutex used to protect the value.
207
+ *
208
+ * @requires If mutex_type is not a recursive mutex the calling thread does not own the mutex.
209
+ *
210
+ * @effects locks the mutex @c mtx, stores a reference to it and to the value type @c value.
211
+ */
212
+ const_unique_lock_ptr(T const& val, Lockable & mtx)
213
+ : base_type(mtx), value_(val)
214
+ {
215
+ }
216
+ /**
217
+ * @param value reference of the value to protect.
218
+ * @param mtx reference to the mutex used to protect the value.
219
+ * @param tag of type adopt_lock_t used to differentiate the constructor.
220
+ * @requires The calling thread own the mutex.
221
+ * @effects stores a reference to it and to the value type @c value taking ownership.
222
+ */
223
+ const_unique_lock_ptr(T const& val, Lockable & mtx, adopt_lock_t) BOOST_NOEXCEPT
224
+ : base_type(mtx, adopt_lock), value_(val)
225
+ {
226
+ }
227
+ /**
228
+ * @param value reference of the value to protect.
229
+ * @param mtx reference to the mutex used to protect the value.
230
+ * @param tag of type defer_lock_t used to differentiate the constructor.
231
+ * @effects stores a reference to it and to the value type @c value c.
232
+ */
233
+ const_unique_lock_ptr(T const& val, Lockable & mtx, defer_lock_t) BOOST_NOEXCEPT
234
+ : base_type(mtx, defer_lock), value_(val)
235
+ {
236
+ }
237
+ /**
238
+ * @param value reference of the value to protect.
239
+ * @param mtx reference to the mutex used to protect the value.
240
+ * @param tag of type try_to_lock_t used to differentiate the constructor.
241
+ * @requires If mutex_type is not a recursive mutex the calling thread does not own the mutex.
242
+ * @effects try to lock the mutex @c mtx, stores a reference to it and to the value type @c value.
243
+ */
244
+ const_unique_lock_ptr(T const& val, Lockable & mtx, try_to_lock_t) BOOST_NOEXCEPT
245
+ : base_type(mtx, try_to_lock), value_(val)
246
+ {
247
+ }
248
+ /**
249
+ * Move constructor.
250
+ * @effects takes ownership of the mutex owned by @c other, stores a reference to the mutex and the value type of @c other.
251
+ */
252
+ const_unique_lock_ptr(BOOST_THREAD_RV_REF(const_unique_lock_ptr) other) BOOST_NOEXCEPT
253
+ : base_type(boost::move(static_cast<base_type&>(other))), value_(BOOST_THREAD_RV(other).value_)
254
+ {
255
+ }
256
+
257
+ /**
258
+ * @effects If owns calls unlock() on the owned mutex.
259
+ */
260
+ ~const_unique_lock_ptr()
261
+ {
262
+ }
263
+
264
+ /**
265
+ * @return a constant pointer to the protected value
266
+ */
267
+ const T* operator->() const
268
+ {
269
+ BOOST_ASSERT (this->owns_lock());
270
+ return &value_;
271
+ }
272
+
273
+ /**
274
+ * @return a constant reference to the protected value
275
+ */
276
+ const T& operator*() const
277
+ {
278
+ BOOST_ASSERT (this->owns_lock());
279
+ return value_;
280
+ }
281
+
282
+ };
283
+
284
+ /**
285
+ * unique lock providing a pointer access to the synchronized value type.
286
+ *
287
+ * @param T the value type.
288
+ * @param Lockable the mutex type protecting the value type.
289
+ */
290
+ template <typename T, typename Lockable = mutex>
291
+ class unique_lock_ptr : public const_unique_lock_ptr<T, Lockable>
292
+ {
293
+ typedef const_unique_lock_ptr<T, Lockable> base_type;
294
+ public:
295
+ typedef T value_type;
296
+ typedef Lockable mutex_type;
297
+
298
+ BOOST_THREAD_MOVABLE_ONLY(unique_lock_ptr)
299
+
300
+ /**
301
+ * @param value reference of the value to protect.
302
+ * @param mtx reference to the mutex used to protect the value.
303
+ * @effects locks the mutex @c mtx, stores a reference to it and to the value type @c value.
304
+ */
305
+ unique_lock_ptr(T & val, Lockable & mtx)
306
+ : base_type(val, mtx)
307
+ {
308
+ }
309
+ /**
310
+ * @param value reference of the value to protect.
311
+ * @param mtx reference to the mutex used to protect the value.
312
+ * @param tag of type adopt_lock_t used to differentiate the constructor.
313
+ * @effects stores a reference to it and to the value type @c value taking ownership.
314
+ */
315
+ unique_lock_ptr(T & value, Lockable & mtx, adopt_lock_t) BOOST_NOEXCEPT
316
+ : base_type(value, mtx, adopt_lock)
317
+ {
318
+ }
319
+ /**
320
+ * @param value reference of the value to protect.
321
+ * @param mtx reference to the mutex used to protect the value.
322
+ * @param tag of type defer_lock_t used to differentiate the constructor.
323
+ * @effects stores a reference to it and to the value type @c value c.
324
+ */
325
+ unique_lock_ptr(T & value, Lockable & mtx, defer_lock_t) BOOST_NOEXCEPT
326
+ : base_type(value, mtx, defer_lock)
327
+ {
328
+ }
329
+ /**
330
+ * @param value reference of the value to protect.
331
+ * @param mtx reference to the mutex used to protect the value.
332
+ * @param tag of type try_to_lock_t used to differentiate the constructor.
333
+ * @effects try to lock the mutex @c mtx, stores a reference to it and to the value type @c value.
334
+ */
335
+ unique_lock_ptr(T & value, Lockable & mtx, try_to_lock_t) BOOST_NOEXCEPT
336
+ : base_type(value, mtx, try_to_lock)
337
+ {
338
+ }
339
+ /**
340
+ * Move constructor.
341
+ * @effects takes ownership of the mutex owned by @c other, stores a reference to the mutex and the value type of @c other.
342
+ */
343
+ unique_lock_ptr(BOOST_THREAD_RV_REF(unique_lock_ptr) other) BOOST_NOEXCEPT
344
+ : base_type(boost::move(static_cast<base_type&>(other)))
345
+ {
346
+ }
347
+
348
+ ~unique_lock_ptr()
349
+ {
350
+ }
351
+
352
+ /**
353
+ * @return a pointer to the protected value
354
+ */
355
+ T* operator->()
356
+ {
357
+ BOOST_ASSERT (this->owns_lock());
358
+ return const_cast<T*>(&this->value_);
359
+ }
360
+
361
+ /**
362
+ * @return a reference to the protected value
363
+ */
364
+ T& operator*()
365
+ {
366
+ BOOST_ASSERT (this->owns_lock());
367
+ return const_cast<T&>(this->value_);
368
+ }
369
+
370
+
371
+ };
372
+
373
+ template <typename SV>
374
+ struct synchronized_value_unique_lock_ptr
375
+ {
376
+ typedef unique_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
377
+ };
378
+
379
+ template <typename SV>
380
+ struct synchronized_value_unique_lock_ptr<const SV>
381
+ {
382
+ typedef const_unique_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
383
+ };
384
+ /**
385
+ * cloaks a value type and the mutex used to protect it together.
386
+ * @param T the value type.
387
+ * @param Lockable the mutex type protecting the value type.
388
+ */
389
+ template <typename T, typename Lockable = mutex>
390
+ class synchronized_value
391
+ {
392
+
393
+ #if ! defined(BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS)
394
+ #if ! defined BOOST_NO_CXX11_VARIADIC_TEMPLATES
395
+ template <typename ...SV>
396
+ friend std::tuple<typename synchronized_value_strict_lock_ptr<SV>::type ...> synchronize(SV& ...sv);
397
+ #else
398
+ template <typename SV1, typename SV2>
399
+ friend std::tuple<
400
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
401
+ typename synchronized_value_strict_lock_ptr<SV2>::type
402
+ >
403
+ synchronize(SV1& sv1, SV2& sv2);
404
+ template <typename SV1, typename SV2, typename SV3>
405
+ friend std::tuple<
406
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
407
+ typename synchronized_value_strict_lock_ptr<SV2>::type,
408
+ typename synchronized_value_strict_lock_ptr<SV3>::type
409
+ >
410
+ synchronize(SV1& sv1, SV2& sv2, SV3& sv3);
411
+ #endif
412
+ #endif
413
+
414
+ public:
415
+ typedef T value_type;
416
+ typedef Lockable mutex_type;
417
+ private:
418
+ T value_;
419
+ mutable mutex_type mtx_;
420
+ public:
421
+ // construction/destruction
422
+ /**
423
+ * Default constructor.
424
+ *
425
+ * @Requires: T is DefaultConstructible
426
+ */
427
+ synchronized_value()
428
+ //BOOST_NOEXCEPT_IF(is_nothrow_default_constructible<T>::value)
429
+ : value_()
430
+ {
431
+ }
432
+
433
+ /**
434
+ * Constructor from copy constructible value.
435
+ *
436
+ * Requires: T is CopyConstructible
437
+ */
438
+ synchronized_value(T const& other)
439
+ //BOOST_NOEXCEPT_IF(is_nothrow_copy_constructible<T>::value)
440
+ : value_(other)
441
+ {
442
+ }
443
+
444
+ /**
445
+ * Move Constructor.
446
+ *
447
+ * Requires: T is CopyMovable
448
+ */
449
+ synchronized_value(BOOST_THREAD_RV_REF(T) other)
450
+ //BOOST_NOEXCEPT_IF(is_nothrow_move_constructible<T>::value)
451
+ : value_(boost::move(other))
452
+ {
453
+ }
454
+
455
+ /**
456
+ * Constructor from value type.
457
+ *
458
+ * Requires: T is DefaultConstructible and Assignable
459
+ * Effects: Assigns the value on a scope protected by the mutex of the rhs. The mutex is not copied.
460
+ */
461
+ synchronized_value(synchronized_value const& rhs)
462
+ {
463
+ strict_lock<mutex_type> lk(rhs.mtx_);
464
+ value_ = rhs.value_;
465
+ }
466
+
467
+ /**
468
+ * Move Constructor from movable value type
469
+ *
470
+ */
471
+ synchronized_value(BOOST_THREAD_RV_REF(synchronized_value) other)
472
+ {
473
+ strict_lock<mutex_type> lk(other.mtx_);
474
+ value_= boost::move(other.value_);
475
+ }
476
+
477
+ // mutation
478
+ /**
479
+ * Assignment operator.
480
+ *
481
+ * Effects: Copies the underlying value on a scope protected by the two mutexes.
482
+ * The mutex is not copied. The locks are acquired using lock, so deadlock is avoided.
483
+ * For example, there is no problem if one thread assigns a = b and the other assigns b = a.
484
+ *
485
+ * Return: *this
486
+ */
487
+
488
+ synchronized_value& operator=(synchronized_value const& rhs)
489
+ {
490
+ if(&rhs != this)
491
+ {
492
+ // auto _ = make_unique_locks(mtx_, rhs.mtx_);
493
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
494
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
495
+ lock(lk1,lk2);
496
+
497
+ value_ = rhs.value_;
498
+ }
499
+ return *this;
500
+ }
501
+ /**
502
+ * Assignment operator from a T const&.
503
+ * Effects: The operator copies the value on a scope protected by the mutex.
504
+ * Return: *this
505
+ */
506
+ synchronized_value& operator=(value_type const& val)
507
+ {
508
+ {
509
+ strict_lock<mutex_type> lk(mtx_);
510
+ value_ = val;
511
+ }
512
+ return *this;
513
+ }
514
+
515
+ //observers
516
+ /**
517
+ * Explicit conversion to value type.
518
+ *
519
+ * Requires: T is CopyConstructible
520
+ * Return: A copy of the protected value obtained on a scope protected by the mutex.
521
+ *
522
+ */
523
+ T get() const
524
+ {
525
+ strict_lock<mutex_type> lk(mtx_);
526
+ return value_;
527
+ }
528
+ /**
529
+ * Explicit conversion to value type.
530
+ *
531
+ * Requires: T is CopyConstructible
532
+ * Return: A copy of the protected value obtained on a scope protected by the mutex.
533
+ *
534
+ */
535
+ #if ! defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
536
+ explicit operator T() const
537
+ {
538
+ return get();
539
+ }
540
+ #endif
541
+
542
+ /**
543
+ * value type getter.
544
+ *
545
+ * Return: A constant reference to the protected value.
546
+ *
547
+ * Note: Not thread safe
548
+ *
549
+ */
550
+ T const& value() const
551
+ {
552
+ return value_;
553
+ }
554
+ /**
555
+ * mutex getter.
556
+ *
557
+ * Return: A constant reference to the protecting mutex.
558
+ *
559
+ * Note: Not thread safe
560
+ *
561
+ */
562
+ mutex_type const& mutex() const
563
+ {
564
+ return mtx_;
565
+ }
566
+ /**
567
+ * Swap
568
+ *
569
+ * Effects: Swaps the data. Again, locks are acquired using lock(). The mutexes are not swapped.
570
+ * A swap method accepts a T& and swaps the data inside a critical section.
571
+ * This is by far the preferred method of changing the guarded datum wholesale because it keeps the lock only
572
+ * for a short time, thus lowering the pressure on the mutex.
573
+ */
574
+ void swap(synchronized_value & rhs)
575
+ {
576
+ if (this == &rhs) {
577
+ return;
578
+ }
579
+ // auto _ = make_unique_locks(mtx_, rhs.mtx_);
580
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
581
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
582
+ lock(lk1,lk2);
583
+ boost::swap(value_, rhs.value_);
584
+ }
585
+ /**
586
+ * Swap with the underlying value type
587
+ *
588
+ * Effects: Swaps the data on a scope protected by the mutex.
589
+ */
590
+ void swap(value_type & rhs)
591
+ {
592
+ strict_lock<mutex_type> lk(mtx_);
593
+ boost::swap(value_, rhs);
594
+ }
595
+
596
+
597
+
598
+ /**
599
+ * Essentially calling a method obj->foo(x, y, z) calls the method foo(x, y, z) inside a critical section as
600
+ * long-lived as the call itself.
601
+ */
602
+ strict_lock_ptr<T,Lockable> operator->()
603
+ {
604
+ return BOOST_THREAD_MAKE_RV_REF((strict_lock_ptr<T,Lockable>(value_, mtx_)));
605
+ }
606
+ /**
607
+ * If the synchronized_value object involved is const-qualified, then you'll only be able to call const methods
608
+ * through operator->. So, for example, vec->push_back("xyz") won't work if vec were const-qualified.
609
+ * The locking mechanism capitalizes on the assumption that const methods don't modify their underlying data.
610
+ */
611
+ const_strict_lock_ptr<T,Lockable> operator->() const
612
+ {
613
+ return BOOST_THREAD_MAKE_RV_REF((const_strict_lock_ptr<T,Lockable>(value_, mtx_)));
614
+ }
615
+
616
+ /**
617
+ * The synchronize() factory make easier to lock on a scope.
618
+ * As discussed, operator-> can only lock over the duration of a call, so it is insufficient for complex operations.
619
+ * With synchronize() you get to lock the object in a scoped and to directly access the object inside that scope.
620
+ *
621
+ * Example
622
+ * void fun(synchronized_value<vector<int>> & vec) {
623
+ * auto&& vec=vec.synchronize();
624
+ * vec.push_back(42);
625
+ * assert(vec.back() == 42);
626
+ * }
627
+ */
628
+ strict_lock_ptr<T,Lockable> synchronize()
629
+ {
630
+ return BOOST_THREAD_MAKE_RV_REF((strict_lock_ptr<T,Lockable>(value_, mtx_)));
631
+ }
632
+ const_strict_lock_ptr<T,Lockable> synchronize() const
633
+ {
634
+ return BOOST_THREAD_MAKE_RV_REF((const_strict_lock_ptr<T,Lockable>(value_, mtx_)));
635
+ }
636
+
637
+ unique_lock_ptr<T,Lockable> unique_synchronize()
638
+ {
639
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_)));
640
+ }
641
+ const_unique_lock_ptr<T,Lockable> unique_synchronize() const
642
+ {
643
+ return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_)));
644
+ }
645
+ unique_lock_ptr<T,Lockable> unique_synchronize(defer_lock_t tag)
646
+ {
647
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, tag)));
648
+ }
649
+ const_unique_lock_ptr<T,Lockable> unique_synchronize(defer_lock_t tag) const
650
+ {
651
+ return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, tag)));
652
+ }
653
+ unique_lock_ptr<T,Lockable> defer_synchronize() BOOST_NOEXCEPT
654
+ {
655
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, defer_lock)));
656
+ }
657
+ const_unique_lock_ptr<T,Lockable> defer_synchronize() const BOOST_NOEXCEPT
658
+ {
659
+ return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, defer_lock)));
660
+ }
661
+ unique_lock_ptr<T,Lockable> try_to_synchronize() BOOST_NOEXCEPT
662
+ {
663
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, try_to_lock)));
664
+ }
665
+ const_unique_lock_ptr<T,Lockable> try_to_synchronize() const BOOST_NOEXCEPT
666
+ {
667
+ return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, try_to_lock)));
668
+ }
669
+ unique_lock_ptr<T,Lockable> adopt_synchronize() BOOST_NOEXCEPT
670
+ {
671
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, adopt_lock)));
672
+ }
673
+ const_unique_lock_ptr<T,Lockable> adopt_synchronize() const BOOST_NOEXCEPT
674
+ {
675
+ return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, adopt_lock)));
676
+ }
677
+
678
+
679
+ #if ! defined __IBMCPP__
680
+ private:
681
+ #endif
682
+ class deref_value
683
+ {
684
+ private:
685
+ friend class synchronized_value;
686
+
687
+ boost::unique_lock<mutex_type> lk_;
688
+ T& value_;
689
+
690
+ explicit deref_value(synchronized_value& outer):
691
+ lk_(outer.mtx_),value_(outer.value_)
692
+ {}
693
+
694
+ public:
695
+ BOOST_THREAD_MOVABLE_ONLY(deref_value)
696
+
697
+ deref_value(BOOST_THREAD_RV_REF(deref_value) other):
698
+ lk_(boost::move(BOOST_THREAD_RV(other).lk_)),value_(BOOST_THREAD_RV(other).value_)
699
+ {}
700
+ operator T&()
701
+ {
702
+ return value_;
703
+ }
704
+
705
+ deref_value& operator=(T const& newVal)
706
+ {
707
+ value_=newVal;
708
+ return *this;
709
+ }
710
+ };
711
+ class const_deref_value
712
+ {
713
+ private:
714
+ friend class synchronized_value;
715
+
716
+ boost::unique_lock<mutex_type> lk_;
717
+ const T& value_;
718
+
719
+ explicit const_deref_value(synchronized_value const& outer):
720
+ lk_(outer.mtx_), value_(outer.value_)
721
+ {}
722
+
723
+ public:
724
+ BOOST_THREAD_MOVABLE_ONLY(const_deref_value)
725
+
726
+ const_deref_value(BOOST_THREAD_RV_REF(const_deref_value) other):
727
+ lk_(boost::move(BOOST_THREAD_RV(other).lk_)), value_(BOOST_THREAD_RV(other).value_)
728
+ {}
729
+
730
+ operator const T&()
731
+ {
732
+ return value_;
733
+ }
734
+ };
735
+
736
+ public:
737
+ deref_value operator*()
738
+ {
739
+ return BOOST_THREAD_MAKE_RV_REF(deref_value(*this));
740
+ }
741
+
742
+ const_deref_value operator*() const
743
+ {
744
+ return BOOST_THREAD_MAKE_RV_REF(const_deref_value(*this));
745
+ }
746
+
747
+ // io functions
748
+ /**
749
+ * @requires T is OutputStreamable
750
+ * @effects saves the value type on the output stream @c os.
751
+ */
752
+ template <typename OStream>
753
+ void save(OStream& os) const
754
+ {
755
+ strict_lock<mutex_type> lk(mtx_);
756
+ os << value_;
757
+ }
758
+ /**
759
+ * @requires T is InputStreamable
760
+ * @effects loads the value type from the input stream @c is.
761
+ */
762
+ template <typename IStream>
763
+ void load(IStream& is) const
764
+ {
765
+ strict_lock<mutex_type> lk(mtx_);
766
+ is >> value_;
767
+ }
768
+
769
+ // relational operators
770
+ /**
771
+ * @requires T is EqualityComparable
772
+ *
773
+ */
774
+ bool operator==(synchronized_value const& rhs) const
775
+ {
776
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
777
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
778
+ lock(lk1,lk2);
779
+
780
+ return value_ == rhs.value_;
781
+ }
782
+ /**
783
+ * @requires T is LessThanComparable
784
+ *
785
+ */
786
+ bool operator<(synchronized_value const& rhs) const
787
+ {
788
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
789
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
790
+ lock(lk1,lk2);
791
+
792
+ return value_ < rhs.value_;
793
+ }
794
+ /**
795
+ * @requires T is GreaterThanComparable
796
+ *
797
+ */
798
+ bool operator>(synchronized_value const& rhs) const
799
+ {
800
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
801
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
802
+ lock(lk1,lk2);
803
+
804
+ return value_ > rhs.value_;
805
+ }
806
+ bool operator<=(synchronized_value const& rhs) const
807
+ {
808
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
809
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
810
+ lock(lk1,lk2);
811
+
812
+ return value_ <= rhs.value_;
813
+ }
814
+ bool operator>=(synchronized_value const& rhs) const
815
+ {
816
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
817
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
818
+ lock(lk1,lk2);
819
+
820
+ return value_ >= rhs.value_;
821
+ }
822
+ bool operator==(value_type const& rhs) const
823
+ {
824
+ unique_lock<mutex_type> lk1(mtx_);
825
+
826
+ return value_ == rhs;
827
+ }
828
+ bool operator!=(value_type const& rhs) const
829
+ {
830
+ unique_lock<mutex_type> lk1(mtx_);
831
+
832
+ return value_ != rhs;
833
+ }
834
+ bool operator<(value_type const& rhs) const
835
+ {
836
+ unique_lock<mutex_type> lk1(mtx_);
837
+
838
+ return value_ < rhs;
839
+ }
840
+ bool operator<=(value_type const& rhs) const
841
+ {
842
+ unique_lock<mutex_type> lk1(mtx_);
843
+
844
+ return value_ <= rhs;
845
+ }
846
+ bool operator>(value_type const& rhs) const
847
+ {
848
+ unique_lock<mutex_type> lk1(mtx_);
849
+
850
+ return value_ > rhs;
851
+ }
852
+ bool operator>=(value_type const& rhs) const
853
+ {
854
+ unique_lock<mutex_type> lk1(mtx_);
855
+
856
+ return value_ >= rhs;
857
+ }
858
+
859
+ };
860
+
861
+ // Specialized algorithms
862
+ /**
863
+ *
864
+ */
865
+ template <typename T, typename L>
866
+ inline void swap(synchronized_value<T,L> & lhs, synchronized_value<T,L> & rhs)
867
+ {
868
+ lhs.swap(rhs);
869
+ }
870
+ template <typename T, typename L>
871
+ inline void swap(synchronized_value<T,L> & lhs, T & rhs)
872
+ {
873
+ lhs.swap(rhs);
874
+ }
875
+ template <typename T, typename L>
876
+ inline void swap(T & lhs, synchronized_value<T,L> & rhs)
877
+ {
878
+ rhs.swap(lhs);
879
+ }
880
+
881
+ //Hash support
882
+
883
+ template <class T> struct hash;
884
+ template <typename T, typename L>
885
+ struct hash<synchronized_value<T,L> >;
886
+
887
+ // Comparison with T
888
+ template <typename T, typename L>
889
+ bool operator!=(synchronized_value<T,L> const&lhs, synchronized_value<T,L> const& rhs)
890
+ {
891
+ return ! (lhs==rhs);
892
+ }
893
+
894
+ template <typename T, typename L>
895
+ bool operator==(T const& lhs, synchronized_value<T,L> const&rhs)
896
+ {
897
+ return rhs==lhs;
898
+ }
899
+ template <typename T, typename L>
900
+ bool operator!=(T const& lhs, synchronized_value<T,L> const&rhs)
901
+ {
902
+ return rhs!=lhs;
903
+ }
904
+ template <typename T, typename L>
905
+ bool operator<(T const& lhs, synchronized_value<T,L> const&rhs)
906
+ {
907
+ return rhs>=lhs;
908
+ }
909
+ template <typename T, typename L>
910
+ bool operator<=(T const& lhs, synchronized_value<T,L> const&rhs)
911
+ {
912
+ return rhs>lhs;
913
+ }
914
+ template <typename T, typename L>
915
+ bool operator>(T const& lhs, synchronized_value<T,L> const&rhs)
916
+ {
917
+ return rhs<=lhs;
918
+ }
919
+ template <typename T, typename L>
920
+ bool operator>=(T const& lhs, synchronized_value<T,L> const&rhs)
921
+ {
922
+ return rhs<lhs;
923
+ }
924
+
925
+ /**
926
+ *
927
+ */
928
+ template <typename OStream, typename T, typename L>
929
+ inline OStream& operator<<(OStream& os, synchronized_value<T,L> const& rhs)
930
+ {
931
+ rhs.save(os);
932
+ return os;
933
+ }
934
+ template <typename IStream, typename T, typename L>
935
+ inline IStream& operator>>(IStream& is, synchronized_value<T,L> const& rhs)
936
+ {
937
+ rhs.load(is);
938
+ return is;
939
+ }
940
+
941
+ #if ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
942
+ #if ! defined BOOST_NO_CXX11_VARIADIC_TEMPLATES
943
+
944
+ template <typename ...SV>
945
+ std::tuple<typename synchronized_value_strict_lock_ptr<SV>::type ...> synchronize(SV& ...sv)
946
+ {
947
+ boost::lock(sv.mtx_ ...);
948
+ typedef std::tuple<typename synchronized_value_strict_lock_ptr<SV>::type ...> t_type;
949
+
950
+ return t_type(typename synchronized_value_strict_lock_ptr<SV>::type(sv.value_, sv.mtx_, adopt_lock) ...);
951
+ }
952
+ #else
953
+
954
+ template <typename SV1, typename SV2>
955
+ std::tuple<
956
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
957
+ typename synchronized_value_strict_lock_ptr<SV2>::type
958
+ >
959
+ synchronize(SV1& sv1, SV2& sv2)
960
+ {
961
+ boost::lock(sv1.mtx_, sv2.mtx_);
962
+ typedef std::tuple<
963
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
964
+ typename synchronized_value_strict_lock_ptr<SV2>::type
965
+ > t_type;
966
+
967
+ return t_type(
968
+ typename synchronized_value_strict_lock_ptr<SV1>::type(sv1.value_, sv1.mtx_, adopt_lock),
969
+ typename synchronized_value_strict_lock_ptr<SV2>::type(sv2.value_, sv2.mtx_, adopt_lock)
970
+ );
971
+
972
+ }
973
+ template <typename SV1, typename SV2, typename SV3>
974
+ std::tuple<
975
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
976
+ typename synchronized_value_strict_lock_ptr<SV2>::type,
977
+ typename synchronized_value_strict_lock_ptr<SV3>::type
978
+ >
979
+ synchronize(SV1& sv1, SV2& sv2, SV3& sv3)
980
+ {
981
+ boost::lock(sv1.mtx_, sv2.mtx_);
982
+ typedef std::tuple<
983
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
984
+ typename synchronized_value_strict_lock_ptr<SV2>::type,
985
+ typename synchronized_value_strict_lock_ptr<SV3>::type
986
+ > t_type;
987
+
988
+ return t_type(
989
+ typename synchronized_value_strict_lock_ptr<SV1>::type(sv1.value_, sv1.mtx_, adopt_lock),
990
+ typename synchronized_value_strict_lock_ptr<SV2>::type(sv2.value_, sv2.mtx_, adopt_lock),
991
+ typename synchronized_value_strict_lock_ptr<SV3>::type(sv3.value_, sv3.mtx_, adopt_lock)
992
+ );
993
+
994
+ }
995
+ #endif
996
+ #endif
997
+ }
998
+
999
+ #include <boost/config/abi_suffix.hpp>
1000
+
1001
+ #endif // header