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
@@ -4,22 +4,26 @@
4
4
  // accompanying file LICENSE_1_0.txt or copy at
5
5
  // http://www.boost.org/LICENSE_1_0.txt)
6
6
  // (C) Copyright 2007-8 Anthony Williams
7
- // (C) Copyright 2011 Vicente J. Botet Escriba
7
+ // (C) Copyright 2011-2012 Vicente J. Botet Escriba
8
8
 
9
9
  #include <boost/assert.hpp>
10
10
  #include <boost/throw_exception.hpp>
11
11
  #include <pthread.h>
12
12
  #include <boost/thread/cv_status.hpp>
13
13
  #include <boost/thread/mutex.hpp>
14
- #include <boost/thread/locks.hpp>
14
+ #include <boost/thread/lock_types.hpp>
15
15
  #include <boost/thread/thread_time.hpp>
16
+ #include <boost/thread/pthread/timespec.hpp>
17
+ #if defined BOOST_THREAD_USES_DATETIME
16
18
  #include <boost/thread/xtime.hpp>
19
+ #endif
17
20
  #ifdef BOOST_THREAD_USES_CHRONO
18
21
  #include <boost/chrono/system_clocks.hpp>
19
22
  #include <boost/chrono/ceil.hpp>
20
23
  #endif
21
24
  #include <boost/thread/detail/delete.hpp>
22
25
  #include <boost/date_time/posix_time/posix_time_duration.hpp>
26
+
23
27
  #include <boost/config/abi_prefix.hpp>
24
28
 
25
29
  namespace boost
@@ -28,33 +32,58 @@ namespace boost
28
32
  class condition_variable
29
33
  {
30
34
  private:
35
+ #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
31
36
  pthread_mutex_t internal_mutex;
37
+ #endif
32
38
  pthread_cond_t cond;
33
39
 
40
+ public:
41
+ //private: // used by boost::thread::try_join_until
42
+
43
+ inline bool do_wait_until(
44
+ unique_lock<mutex>& lock,
45
+ struct timespec const &timeout);
46
+
47
+ bool do_wait_for(
48
+ unique_lock<mutex>& lock,
49
+ struct timespec const &timeout)
50
+ {
51
+ return do_wait_until(lock, boost::detail::timespec_plus(timeout, boost::detail::timespec_now()));
52
+ }
53
+
34
54
  public:
35
55
  BOOST_THREAD_NO_COPYABLE(condition_variable)
36
56
  condition_variable()
37
57
  {
58
+ #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
38
59
  int const res=pthread_mutex_init(&internal_mutex,NULL);
39
60
  if(res)
40
61
  {
41
- boost::throw_exception(thread_resource_error(res, "boost:: condition_variable constructor failed in pthread_mutex_init"));
62
+ boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_mutex_init"));
42
63
  }
64
+ #endif
43
65
  int const res2=pthread_cond_init(&cond,NULL);
44
66
  if(res2)
45
67
  {
68
+ #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
46
69
  BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
47
- boost::throw_exception(thread_resource_error(res2, "boost:: condition_variable constructor failed in pthread_cond_init"));
70
+ #endif
71
+ boost::throw_exception(thread_resource_error(res2, "boost::condition_variable::condition_variable() constructor failed in pthread_cond_init"));
48
72
  }
49
73
  }
50
74
  ~condition_variable()
51
75
  {
52
- BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
53
76
  int ret;
77
+ #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
78
+ do {
79
+ ret = pthread_mutex_destroy(&internal_mutex);
80
+ } while (ret == EINTR);
81
+ BOOST_ASSERT(!ret);
82
+ #endif
54
83
  do {
55
84
  ret = pthread_cond_destroy(&cond);
56
85
  } while (ret == EINTR);
57
- BOOST_VERIFY(!ret);
86
+ BOOST_ASSERT(!ret);
58
87
  }
59
88
 
60
89
  void wait(unique_lock<mutex>& m);
@@ -66,16 +95,17 @@ namespace boost
66
95
  }
67
96
 
68
97
 
98
+ #if defined BOOST_THREAD_USES_DATETIME
69
99
  inline bool timed_wait(
70
100
  unique_lock<mutex>& m,
71
101
  boost::system_time const& wait_until)
72
102
  {
73
103
  #if defined BOOST_THREAD_WAIT_BUG
74
- struct timespec const timeout=detail::get_timespec(wait_until + BOOST_THREAD_WAIT_BUG);
75
- return do_timed_wait(m, timeout);
104
+ struct timespec const timeout=detail::to_timespec(wait_until + BOOST_THREAD_WAIT_BUG);
105
+ return do_wait_until(m, timeout);
76
106
  #else
77
- struct timespec const timeout=detail::get_timespec(wait_until);
78
- return do_timed_wait(m, timeout);
107
+ struct timespec const timeout=detail::to_timespec(wait_until);
108
+ return do_wait_until(m, timeout);
79
109
  #endif
80
110
  }
81
111
  bool timed_wait(
@@ -121,6 +151,7 @@ namespace boost
121
151
  {
122
152
  return timed_wait(m,get_system_time()+wait_duration,pred);
123
153
  }
154
+ #endif
124
155
 
125
156
  #ifdef BOOST_THREAD_USES_CHRONO
126
157
 
@@ -190,12 +221,14 @@ namespace boost
190
221
  const chrono::duration<Rep, Period>& d,
191
222
  Predicate pred)
192
223
  {
193
- while (!pred())
194
- {
195
- if (wait_for(lock, d) == cv_status::timeout)
196
- return pred();
197
- }
198
- return true;
224
+ return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
225
+
226
+ // while (!pred())
227
+ // {
228
+ // if (wait_for(lock, d) == cv_status::timeout)
229
+ // return pred();
230
+ // }
231
+ // return true;
199
232
  }
200
233
  #endif
201
234
 
@@ -210,27 +243,21 @@ namespace boost
210
243
  void notify_all() BOOST_NOEXCEPT;
211
244
 
212
245
  #ifdef BOOST_THREAD_USES_CHRONO
213
- inline void wait_until(
246
+ inline cv_status wait_until(
214
247
  unique_lock<mutex>& lk,
215
248
  chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
216
249
  {
217
250
  using namespace chrono;
218
251
  nanoseconds d = tp.time_since_epoch();
219
- timespec ts;
220
- seconds s = duration_cast<seconds>(d);
221
- ts.tv_sec = static_cast<long>(s.count());
222
- ts.tv_nsec = static_cast<long>((d - s).count());
223
- do_timed_wait(lk, ts);
252
+ timespec ts = boost::detail::to_timespec(d);
253
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
254
+ else return cv_status::timeout;
224
255
  }
225
256
  #endif
226
- //private: // used by boost::thread::try_join_until
227
-
228
- inline bool do_timed_wait(
229
- unique_lock<mutex>& lock,
230
- struct timespec const &timeout);
231
257
  };
232
258
 
233
259
  BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
260
+
234
261
  }
235
262
 
236
263
 
@@ -6,10 +6,13 @@
6
6
  // accompanying file LICENSE_1_0.txt or copy at
7
7
  // http://www.boost.org/LICENSE_1_0.txt)
8
8
 
9
+ #include <boost/thread/detail/config.hpp>
9
10
  #include <pthread.h>
10
11
  #include <boost/throw_exception.hpp>
11
12
  #include <boost/thread/exceptions.hpp>
12
- #include <boost/thread/locks.hpp>
13
+ #if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
14
+ #include <boost/thread/lock_types.hpp>
15
+ #endif
13
16
  #include <boost/thread/thread_time.hpp>
14
17
  #include <boost/thread/xtime.hpp>
15
18
  #include <boost/assert.hpp>
@@ -23,15 +26,68 @@
23
26
  #include <boost/thread/detail/delete.hpp>
24
27
 
25
28
  #ifdef _POSIX_TIMEOUTS
26
- #if _POSIX_TIMEOUTS >= 0 && _POSIX_C_SOURCE>=200112L
29
+ #if _POSIX_TIMEOUTS >= 0 && _POSIX_TIMEOUTS>=200112L
30
+ #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
27
31
  #define BOOST_PTHREAD_HAS_TIMEDLOCK
28
32
  #endif
29
33
  #endif
34
+ #endif
35
+
30
36
 
31
37
  #include <boost/config/abi_prefix.hpp>
32
38
 
39
+ #ifndef BOOST_THREAD_HAS_NO_EINTR_BUG
40
+ #define BOOST_THREAD_HAS_EINTR_BUG
41
+ #endif
42
+
33
43
  namespace boost
34
44
  {
45
+ namespace posix {
46
+ #ifdef BOOST_THREAD_HAS_EINTR_BUG
47
+ BOOST_FORCEINLINE int pthread_mutex_destroy(pthread_mutex_t* m)
48
+ {
49
+ int ret;
50
+ do
51
+ {
52
+ ret = ::pthread_mutex_destroy(m);
53
+ } while (ret == EINTR);
54
+ return ret;
55
+ }
56
+ BOOST_FORCEINLINE int pthread_mutex_lock(pthread_mutex_t* m)
57
+ {
58
+ int ret;
59
+ do
60
+ {
61
+ ret = ::pthread_mutex_lock(m);
62
+ } while (ret == EINTR);
63
+ return ret;
64
+ }
65
+ BOOST_FORCEINLINE int pthread_mutex_unlock(pthread_mutex_t* m)
66
+ {
67
+ int ret;
68
+ do
69
+ {
70
+ ret = ::pthread_mutex_unlock(m);
71
+ } while (ret == EINTR);
72
+ return ret;
73
+ }
74
+ #else
75
+ BOOST_FORCEINLINE int pthread_mutex_destroy(pthread_mutex_t* m)
76
+ {
77
+ return ::pthread_mutex_destroy(m);
78
+ }
79
+ BOOST_FORCEINLINE int pthread_mutex_lock(pthread_mutex_t* m)
80
+ {
81
+ return ::pthread_mutex_lock(m);
82
+ }
83
+ BOOST_FORCEINLINE int pthread_mutex_unlock(pthread_mutex_t* m)
84
+ {
85
+ return ::pthread_mutex_unlock(m);
86
+ }
87
+
88
+ #endif
89
+
90
+ }
35
91
  class mutex
36
92
  {
37
93
  private:
@@ -49,20 +105,12 @@ namespace boost
49
105
  }
50
106
  ~mutex()
51
107
  {
52
- int ret;
53
- do
54
- {
55
- ret = pthread_mutex_destroy(&m);
56
- } while (ret == EINTR);
108
+ BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
57
109
  }
58
110
 
59
111
  void lock()
60
112
  {
61
- int res;
62
- do
63
- {
64
- res = pthread_mutex_lock(&m);
65
- } while (res == EINTR);
113
+ int res = posix::pthread_mutex_lock(&m);
66
114
  if (res)
67
115
  {
68
116
  boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock"));
@@ -71,12 +119,11 @@ namespace boost
71
119
 
72
120
  void unlock()
73
121
  {
74
- int ret;
75
- do
122
+ int res = posix::pthread_mutex_unlock(&m);
123
+ if (res)
76
124
  {
77
- ret = pthread_mutex_unlock(&m);
78
- } while (ret == EINTR);
79
- BOOST_VERIFY(!ret);
125
+ boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
126
+ }
80
127
  }
81
128
 
82
129
  bool try_lock()
@@ -86,12 +133,8 @@ namespace boost
86
133
  {
87
134
  res = pthread_mutex_trylock(&m);
88
135
  } while (res == EINTR);
89
- if(res && (res!=EBUSY))
136
+ if (res==EBUSY)
90
137
  {
91
- // The following throw_exception has been replaced by an assertion and just return false,
92
- // as this is an internal error and the user can do nothing with the exception.
93
- //boost::throw_exception(lock_error(res,"boost: mutex try_lock failed in pthread_mutex_trylock"));
94
- BOOST_ASSERT_MSG(false ,"boost: mutex try_lock failed in pthread_mutex_trylock");
95
138
  return false;
96
139
  }
97
140
 
@@ -105,8 +148,10 @@ namespace boost
105
148
  return &m;
106
149
  }
107
150
 
151
+ #if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
108
152
  typedef unique_lock<mutex> scoped_lock;
109
153
  typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
154
+ #endif
110
155
  };
111
156
 
112
157
  typedef mutex try_mutex;
@@ -132,7 +177,8 @@ namespace boost
132
177
  int const res2=pthread_cond_init(&cond,NULL);
133
178
  if(res2)
134
179
  {
135
- BOOST_VERIFY(!pthread_mutex_destroy(&m));
180
+ BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
181
+ //BOOST_VERIFY(!pthread_mutex_destroy(&m));
136
182
  boost::throw_exception(thread_resource_error(res2, "boost:: timed_mutex constructor failed in pthread_cond_init"));
137
183
  }
138
184
  is_locked=false;
@@ -140,12 +186,13 @@ namespace boost
140
186
  }
141
187
  ~timed_mutex()
142
188
  {
143
- BOOST_VERIFY(!pthread_mutex_destroy(&m));
189
+ BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
144
190
  #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
145
191
  BOOST_VERIFY(!pthread_cond_destroy(&cond));
146
192
  #endif
147
193
  }
148
194
 
195
+ #if defined BOOST_THREAD_USES_DATETIME
149
196
  template<typename TimeDuration>
150
197
  bool timed_lock(TimeDuration const & relative_time)
151
198
  {
@@ -155,23 +202,39 @@ namespace boost
155
202
  {
156
203
  return timed_lock(system_time(absolute_time));
157
204
  }
158
-
205
+ #endif
159
206
  #ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
160
207
  void lock()
161
208
  {
162
- BOOST_VERIFY(!pthread_mutex_lock(&m));
209
+ int res = posix::pthread_mutex_lock(&m);
210
+ if (res)
211
+ {
212
+ boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock"));
213
+ }
163
214
  }
164
215
 
165
216
  void unlock()
166
217
  {
167
- BOOST_VERIFY(!pthread_mutex_unlock(&m));
218
+ int res = posix::pthread_mutex_unlock(&m);
219
+ if (res)
220
+ {
221
+ boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
222
+ }
168
223
  }
169
224
 
170
225
  bool try_lock()
171
226
  {
172
- int const res=pthread_mutex_trylock(&m);
173
- BOOST_ASSERT(!res || res==EBUSY);
174
- return !res;
227
+ int res;
228
+ do
229
+ {
230
+ res = pthread_mutex_trylock(&m);
231
+ } while (res == EINTR);
232
+ if (res==EBUSY)
233
+ {
234
+ return false;
235
+ }
236
+
237
+ return !res;
175
238
  }
176
239
 
177
240
 
@@ -232,12 +295,13 @@ namespace boost
232
295
  public:
233
296
  #endif
234
297
 
298
+ #if defined BOOST_THREAD_USES_DATETIME
235
299
  bool timed_lock(system_time const & abs_time)
236
300
  {
237
- struct timespec const ts=detail::get_timespec(abs_time);
301
+ struct timespec const ts=boost::detail::to_timespec(abs_time);
238
302
  return do_try_lock_until(ts);
239
303
  }
240
-
304
+ #endif
241
305
  #ifdef BOOST_THREAD_USES_CHRONO
242
306
  template <class Rep, class Period>
243
307
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
@@ -261,12 +325,9 @@ namespace boost
261
325
  }
262
326
  bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
263
327
  {
264
- using namespace chrono;
265
- nanoseconds d = tp.time_since_epoch();
266
- timespec ts;
267
- seconds s = duration_cast<seconds>(d);
268
- ts.tv_sec = static_cast<long>(s.count());
269
- ts.tv_nsec = static_cast<long>((d - s).count());
328
+ //using namespace chrono;
329
+ chrono::nanoseconds d = tp.time_since_epoch();
330
+ timespec ts = boost::detail::to_timespec(d);
270
331
  return do_try_lock_until(ts);
271
332
  }
272
333
  #endif
@@ -278,9 +339,11 @@ namespace boost
278
339
  return &m;
279
340
  }
280
341
 
342
+ #if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
281
343
  typedef unique_lock<timed_mutex> scoped_timed_lock;
282
344
  typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
283
345
  typedef scoped_timed_lock scoped_lock;
346
+ #endif
284
347
  };
285
348
 
286
349
  }
@@ -11,11 +11,14 @@
11
11
  // http://www.boost.org/LICENSE_1_0.txt)
12
12
 
13
13
  #include <boost/thread/detail/config.hpp>
14
+ #include <boost/thread/detail/move.hpp>
15
+ #include <boost/thread/detail/invoke.hpp>
14
16
 
15
17
  #include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
16
18
  #include <boost/thread/detail/delete.hpp>
17
19
  #include <boost/detail/no_exceptions_support.hpp>
18
20
 
21
+ #include <boost/bind.hpp>
19
22
  #include <boost/assert.hpp>
20
23
  #include <boost/config/abi_prefix.hpp>
21
24
 
@@ -26,21 +29,32 @@
26
29
  namespace boost
27
30
  {
28
31
 
29
- #define BOOST_ONCE_INITIAL_FLAG_VALUE 0
32
+ struct once_flag;
33
+
34
+ #define BOOST_ONCE_INITIAL_FLAG_VALUE 0
30
35
 
31
36
  namespace thread_detail
32
37
  {
33
- //#ifdef SIG_ATOMIC_MAX
34
- // typedef sig_atomic_t uintmax_atomic_t;
35
- // #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C SIG_ATOMIC_MAX
36
- //#else
37
- typedef unsigned long uintmax_atomic_t;
38
- #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(value) value##ul
38
+ typedef boost::uint32_t uintmax_atomic_t;
39
+ #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(value) value##u
39
40
  #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(~0)
40
- //#endif
41
+
41
42
  }
42
43
 
43
44
  #ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
45
+ #ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
46
+ template<typename Function, class ...ArgTypes>
47
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args);
48
+ #else
49
+ template<typename Function>
50
+ inline void call_once(once_flag& flag, Function f);
51
+ template<typename Function, typename T1>
52
+ inline void call_once(once_flag& flag, Function f, T1 p1);
53
+ template<typename Function, typename T1, typename T2>
54
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2);
55
+ template<typename Function, typename T1, typename T2, typename T3>
56
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3);
57
+ #endif
44
58
 
45
59
  struct once_flag
46
60
  {
@@ -50,11 +64,26 @@ namespace boost
50
64
  {}
51
65
  private:
52
66
  volatile thread_detail::uintmax_atomic_t epoch;
67
+
68
+ #ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
69
+ template<typename Function, class ...ArgTypes>
70
+ friend void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args);
71
+ #else
53
72
  template<typename Function>
54
- friend
55
- void call_once(once_flag& flag,Function f);
73
+ friend void call_once(once_flag& flag, Function f);
74
+ template<typename Function, typename T1>
75
+ friend void call_once(once_flag& flag, Function f, T1 p1);
76
+ template<typename Function, typename T1, typename T2>
77
+ friend void call_once(once_flag& flag, Function f, T1 p1, T2 p2);
78
+ template<typename Function, typename T1, typename T2, typename T3>
79
+ friend void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3);
80
+
81
+ #endif
82
+
56
83
  };
57
84
 
85
+ #define BOOST_ONCE_INIT once_flag()
86
+
58
87
  #else // BOOST_THREAD_PROVIDES_ONCE_CXX11
59
88
 
60
89
  struct once_flag
@@ -65,59 +94,445 @@ namespace boost
65
94
  #define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE}
66
95
  #endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
67
96
 
68
- namespace detail
97
+
98
+ #if defined BOOST_THREAD_PROVIDES_INVOKE
99
+ #define BOOST_THREAD_INVOKE_RET_VOID detail::invoke
100
+ #define BOOST_THREAD_INVOKE_RET_VOID_CALL
101
+ #elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
102
+ #define BOOST_THREAD_INVOKE_RET_VOID detail::invoke<void>
103
+ #define BOOST_THREAD_INVOKE_RET_VOID_CALL
104
+ #else
105
+ #define BOOST_THREAD_INVOKE_RET_VOID boost::bind
106
+ #define BOOST_THREAD_INVOKE_RET_VOID_CALL ()
107
+ #endif
108
+
109
+ namespace thread_detail
69
110
  {
70
- BOOST_THREAD_DECL thread_detail::uintmax_atomic_t& get_once_per_thread_epoch();
71
- BOOST_THREAD_DECL extern thread_detail::uintmax_atomic_t once_global_epoch;
111
+ BOOST_THREAD_DECL uintmax_atomic_t& get_once_per_thread_epoch();
112
+ BOOST_THREAD_DECL extern uintmax_atomic_t once_global_epoch;
72
113
  BOOST_THREAD_DECL extern pthread_mutex_t once_epoch_mutex;
73
114
  BOOST_THREAD_DECL extern pthread_cond_t once_epoch_cv;
74
115
  }
75
116
 
76
117
  // Based on Mike Burrows fast_pthread_once algorithm as described in
77
118
  // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2444.html
78
- template<typename Function>
79
- void call_once(once_flag& flag,Function f)
119
+
120
+
121
+ #ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
122
+
123
+
124
+ template<typename Function, class ...ArgTypes>
125
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args)
126
+ {
127
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
128
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
129
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
130
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
131
+
132
+ if(epoch<this_thread_epoch)
133
+ {
134
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
135
+
136
+ while(flag.epoch<=being_initialized)
137
+ {
138
+ if(flag.epoch==uninitialized_flag)
139
+ {
140
+ flag.epoch=being_initialized;
141
+ BOOST_TRY
142
+ {
143
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
144
+ BOOST_THREAD_INVOKE_RET_VOID(
145
+ thread_detail::decay_copy(boost::forward<Function>(f)),
146
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
147
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
148
+ }
149
+ BOOST_CATCH (...)
150
+ {
151
+ flag.epoch=uninitialized_flag;
152
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
153
+ BOOST_RETHROW
154
+ }
155
+ BOOST_CATCH_END
156
+ flag.epoch=--thread_detail::once_global_epoch;
157
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
158
+ }
159
+ else
160
+ {
161
+ while(flag.epoch==being_initialized)
162
+ {
163
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
164
+ }
165
+ }
166
+ }
167
+ this_thread_epoch=thread_detail::once_global_epoch;
168
+
169
+ }
170
+ }
171
+ #else
172
+ template<typename Function>
173
+ inline void call_once(once_flag& flag, Function f)
174
+ {
175
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
176
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
177
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
178
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
179
+
180
+ if(epoch<this_thread_epoch)
181
+ {
182
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
183
+
184
+ while(flag.epoch<=being_initialized)
185
+ {
186
+ if(flag.epoch==uninitialized_flag)
187
+ {
188
+ flag.epoch=being_initialized;
189
+ BOOST_TRY
190
+ {
191
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
192
+ f();
193
+ }
194
+ BOOST_CATCH (...)
195
+ {
196
+ flag.epoch=uninitialized_flag;
197
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
198
+ BOOST_RETHROW
199
+ }
200
+ BOOST_CATCH_END
201
+ flag.epoch=--thread_detail::once_global_epoch;
202
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
203
+ }
204
+ else
205
+ {
206
+ while(flag.epoch==being_initialized)
207
+ {
208
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
209
+ }
210
+ }
211
+ }
212
+ this_thread_epoch=thread_detail::once_global_epoch;
213
+ }
214
+ }
215
+
216
+ template<typename Function, typename T1>
217
+ inline void call_once(once_flag& flag, Function f, T1 p1)
218
+ {
219
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
220
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
221
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
222
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
223
+
224
+ if(epoch<this_thread_epoch)
225
+ {
226
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
227
+
228
+ while(flag.epoch<=being_initialized)
229
+ {
230
+ if(flag.epoch==uninitialized_flag)
231
+ {
232
+ flag.epoch=being_initialized;
233
+ BOOST_TRY
234
+ {
235
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
236
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
237
+ }
238
+ BOOST_CATCH (...)
239
+ {
240
+ flag.epoch=uninitialized_flag;
241
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
242
+ BOOST_RETHROW
243
+ }
244
+ BOOST_CATCH_END
245
+ flag.epoch=--thread_detail::once_global_epoch;
246
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
247
+ }
248
+ else
249
+ {
250
+ while(flag.epoch==being_initialized)
251
+ {
252
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
253
+ }
254
+ }
255
+ }
256
+ this_thread_epoch=thread_detail::once_global_epoch;
257
+ }
258
+ }
259
+ template<typename Function, typename T1, typename T2>
260
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2)
261
+ {
262
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
263
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
264
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
265
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
266
+
267
+ if(epoch<this_thread_epoch)
268
+ {
269
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
270
+
271
+ while(flag.epoch<=being_initialized)
272
+ {
273
+ if(flag.epoch==uninitialized_flag)
274
+ {
275
+ flag.epoch=being_initialized;
276
+ BOOST_TRY
277
+ {
278
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
279
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1, p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
280
+ }
281
+ BOOST_CATCH (...)
282
+ {
283
+ flag.epoch=uninitialized_flag;
284
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
285
+ BOOST_RETHROW
286
+ }
287
+ BOOST_CATCH_END
288
+ flag.epoch=--thread_detail::once_global_epoch;
289
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
290
+ }
291
+ else
292
+ {
293
+ while(flag.epoch==being_initialized)
294
+ {
295
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
296
+ }
297
+ }
298
+ }
299
+ this_thread_epoch=thread_detail::once_global_epoch;
300
+ }
301
+ }
302
+
303
+ template<typename Function, typename T1, typename T2, typename T3>
304
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3)
305
+ {
306
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
307
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
308
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
309
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
310
+
311
+ if(epoch<this_thread_epoch)
312
+ {
313
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
314
+
315
+ while(flag.epoch<=being_initialized)
316
+ {
317
+ if(flag.epoch==uninitialized_flag)
318
+ {
319
+ flag.epoch=being_initialized;
320
+ BOOST_TRY
321
+ {
322
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
323
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1, p2, p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
324
+ }
325
+ BOOST_CATCH (...)
326
+ {
327
+ flag.epoch=uninitialized_flag;
328
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
329
+ BOOST_RETHROW
330
+ }
331
+ BOOST_CATCH_END
332
+ flag.epoch=--thread_detail::once_global_epoch;
333
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
334
+ }
335
+ else
336
+ {
337
+ while(flag.epoch==being_initialized)
338
+ {
339
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
340
+ }
341
+ }
342
+ }
343
+ this_thread_epoch=thread_detail::once_global_epoch;
344
+ }
345
+ }
346
+
347
+ template<typename Function>
348
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f)
349
+ {
350
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
351
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
352
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
353
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
354
+
355
+ if(epoch<this_thread_epoch)
356
+ {
357
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
358
+
359
+ while(flag.epoch<=being_initialized)
360
+ {
361
+ if(flag.epoch==uninitialized_flag)
362
+ {
363
+ flag.epoch=being_initialized;
364
+ BOOST_TRY
365
+ {
366
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
367
+ f();
368
+ }
369
+ BOOST_CATCH (...)
370
+ {
371
+ flag.epoch=uninitialized_flag;
372
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
373
+ BOOST_RETHROW
374
+ }
375
+ BOOST_CATCH_END
376
+ flag.epoch=--thread_detail::once_global_epoch;
377
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
378
+ }
379
+ else
380
+ {
381
+ while(flag.epoch==being_initialized)
382
+ {
383
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
384
+ }
385
+ }
386
+ }
387
+ this_thread_epoch=thread_detail::once_global_epoch;
388
+ }
389
+ }
390
+
391
+ template<typename Function, typename T1>
392
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1)
393
+ {
394
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
395
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
396
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
397
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
398
+
399
+ if(epoch<this_thread_epoch)
80
400
  {
81
- static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
82
- static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
83
- thread_detail::uintmax_atomic_t const epoch=flag.epoch;
84
- thread_detail::uintmax_atomic_t& this_thread_epoch=detail::get_once_per_thread_epoch();
401
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
85
402
 
86
- if(epoch<this_thread_epoch)
403
+ while(flag.epoch<=being_initialized)
87
404
  {
88
- pthread::pthread_mutex_scoped_lock lk(&detail::once_epoch_mutex);
405
+ if(flag.epoch==uninitialized_flag)
406
+ {
407
+ flag.epoch=being_initialized;
408
+ BOOST_TRY
409
+ {
410
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
411
+ BOOST_THREAD_INVOKE_RET_VOID(
412
+ thread_detail::decay_copy(boost::forward<Function>(f)),
413
+ thread_detail::decay_copy(boost::forward<T1>(p1))
414
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
415
+ }
416
+ BOOST_CATCH (...)
417
+ {
418
+ flag.epoch=uninitialized_flag;
419
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
420
+ BOOST_RETHROW
421
+ }
422
+ BOOST_CATCH_END
423
+ flag.epoch=--thread_detail::once_global_epoch;
424
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
425
+ }
426
+ else
427
+ {
428
+ while(flag.epoch==being_initialized)
429
+ {
430
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
431
+ }
432
+ }
433
+ }
434
+ this_thread_epoch=thread_detail::once_global_epoch;
435
+ }
436
+ }
437
+ template<typename Function, typename T1, typename T2>
438
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
439
+ {
440
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
441
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
442
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
443
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
444
+
445
+ if(epoch<this_thread_epoch)
446
+ {
447
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
448
+
449
+ while(flag.epoch<=being_initialized)
450
+ {
451
+ if(flag.epoch==uninitialized_flag)
452
+ {
453
+ flag.epoch=being_initialized;
454
+ BOOST_TRY
455
+ {
456
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
457
+ BOOST_THREAD_INVOKE_RET_VOID(
458
+ thread_detail::decay_copy(boost::forward<Function>(f)),
459
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
460
+ thread_detail::decay_copy(boost::forward<T1>(p2))
461
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
462
+ }
463
+ BOOST_CATCH (...)
464
+ {
465
+ flag.epoch=uninitialized_flag;
466
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
467
+ BOOST_RETHROW
468
+ }
469
+ BOOST_CATCH_END
470
+ flag.epoch=--thread_detail::once_global_epoch;
471
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
472
+ }
473
+ else
474
+ {
475
+ while(flag.epoch==being_initialized)
476
+ {
477
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
478
+ }
479
+ }
480
+ }
481
+ this_thread_epoch=thread_detail::once_global_epoch;
482
+ }
483
+ }
484
+
485
+ template<typename Function, typename T1, typename T2, typename T3>
486
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
487
+ {
488
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
489
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
490
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
491
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
89
492
 
90
- while(flag.epoch<=being_initialized)
493
+ if(epoch<this_thread_epoch)
494
+ {
495
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
496
+
497
+ while(flag.epoch<=being_initialized)
498
+ {
499
+ if(flag.epoch==uninitialized_flag)
91
500
  {
92
- if(flag.epoch==uninitialized_flag)
501
+ flag.epoch=being_initialized;
502
+ BOOST_TRY
93
503
  {
94
- flag.epoch=being_initialized;
95
- BOOST_TRY
96
- {
97
- pthread::pthread_mutex_scoped_unlock relocker(&detail::once_epoch_mutex);
98
- f();
99
- }
100
- BOOST_CATCH (...)
101
- {
102
- flag.epoch=uninitialized_flag;
103
- BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
104
- BOOST_RETHROW
105
- }
106
- BOOST_CATCH_END
107
- flag.epoch=--detail::once_global_epoch;
108
- BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
504
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
505
+ BOOST_THREAD_INVOKE_RET_VOID(
506
+ thread_detail::decay_copy(boost::forward<Function>(f)),
507
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
508
+ thread_detail::decay_copy(boost::forward<T1>(p2)),
509
+ thread_detail::decay_copy(boost::forward<T1>(p3))
510
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
109
511
  }
110
- else
512
+ BOOST_CATCH (...)
111
513
  {
112
- while(flag.epoch==being_initialized)
113
- {
114
- BOOST_VERIFY(!pthread_cond_wait(&detail::once_epoch_cv,&detail::once_epoch_mutex));
115
- }
514
+ flag.epoch=uninitialized_flag;
515
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
516
+ BOOST_RETHROW
517
+ }
518
+ BOOST_CATCH_END
519
+ flag.epoch=--thread_detail::once_global_epoch;
520
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
521
+ }
522
+ else
523
+ {
524
+ while(flag.epoch==being_initialized)
525
+ {
526
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
116
527
  }
117
528
  }
118
- this_thread_epoch=detail::once_global_epoch;
119
529
  }
530
+ this_thread_epoch=thread_detail::once_global_epoch;
120
531
  }
532
+ }
533
+
534
+ #endif
535
+
121
536
  }
122
537
 
123
538
  #include <boost/config/abi_suffix.hpp>