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,183 @@
1
+
2
+ // Copyright (C) 2005-2011 Daniel James
3
+ // Distributed under the Boost Software License, Version 1.0. (See accompanying
4
+ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
+
6
+ #ifndef BOOST_UNORDERED_DETAIL_EXTRACT_KEY_HPP_INCLUDED
7
+ #define BOOST_UNORDERED_DETAIL_EXTRACT_KEY_HPP_INCLUDED
8
+
9
+ #include <boost/unordered/detail/table.hpp>
10
+
11
+ namespace boost {
12
+ namespace unordered {
13
+ namespace detail {
14
+
15
+ // key extractors
16
+ //
17
+ // no throw
18
+ //
19
+ // 'extract_key' is called with the emplace parameters to return a
20
+ // key if available or 'no_key' is one isn't and will need to be
21
+ // constructed. This could be done by overloading the emplace implementation
22
+ // for the different cases, but that's a bit tricky on compilers without
23
+ // variadic templates.
24
+
25
+ struct no_key {
26
+ no_key() {}
27
+ template <class T> no_key(T const&) {}
28
+ };
29
+
30
+ template <typename Key, typename T>
31
+ struct is_key {
32
+ template <typename T2>
33
+ static choice1::type test(T2 const&);
34
+ static choice2::type test(Key const&);
35
+
36
+ enum { value = sizeof(test(boost::unordered::detail::make<T>())) ==
37
+ sizeof(choice2::type) };
38
+
39
+ typedef typename boost::detail::if_true<value>::
40
+ BOOST_NESTED_TEMPLATE then<Key const&, no_key>::type type;
41
+ };
42
+
43
+ template <class ValueType>
44
+ struct set_extractor
45
+ {
46
+ typedef ValueType value_type;
47
+ typedef ValueType key_type;
48
+
49
+ static key_type const& extract(key_type const& v)
50
+ {
51
+ return v;
52
+ }
53
+
54
+ static no_key extract()
55
+ {
56
+ return no_key();
57
+ }
58
+
59
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
60
+ template <class... Args>
61
+ static no_key extract(Args const&...)
62
+ {
63
+ return no_key();
64
+ }
65
+ #else
66
+ template <class Arg>
67
+ static no_key extract(Arg const&)
68
+ {
69
+ return no_key();
70
+ }
71
+
72
+ template <class Arg1, class Arg2>
73
+ static no_key extract(Arg1 const&, Arg2 const&)
74
+ {
75
+ return no_key();
76
+ }
77
+ #endif
78
+ };
79
+
80
+ template <class Key, class ValueType>
81
+ struct map_extractor
82
+ {
83
+ typedef ValueType value_type;
84
+ typedef typename boost::remove_const<Key>::type key_type;
85
+
86
+ static key_type const& extract(value_type const& v)
87
+ {
88
+ return v.first;
89
+ }
90
+
91
+ template <class Second>
92
+ static key_type const& extract(std::pair<key_type, Second> const& v)
93
+ {
94
+ return v.first;
95
+ }
96
+
97
+ template <class Second>
98
+ static key_type const& extract(
99
+ std::pair<key_type const, Second> const& v)
100
+ {
101
+ return v.first;
102
+ }
103
+
104
+ template <class Arg1>
105
+ static key_type const& extract(key_type const& k, Arg1 const&)
106
+ {
107
+ return k;
108
+ }
109
+
110
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
111
+ template <class... Args>
112
+ static no_key extract(Args const&...)
113
+ {
114
+ return no_key();
115
+ }
116
+ #else
117
+
118
+ static no_key extract()
119
+ {
120
+ return no_key();
121
+ }
122
+
123
+ template <class Arg>
124
+ static no_key extract(Arg const&)
125
+ {
126
+ return no_key();
127
+ }
128
+
129
+ template <class Arg, class Arg1>
130
+ static no_key extract(Arg const&, Arg1 const&)
131
+ {
132
+ return no_key();
133
+ }
134
+ #endif
135
+
136
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
137
+
138
+ #define BOOST_UNORDERED_KEY_FROM_TUPLE(namespace_) \
139
+ template <typename T2> \
140
+ static no_key extract(boost::unordered::piecewise_construct_t, \
141
+ namespace_ tuple<> const&, T2 const&) \
142
+ { \
143
+ return no_key(); \
144
+ } \
145
+ \
146
+ template <typename T, typename T2> \
147
+ static typename is_key<key_type, T>::type \
148
+ extract(boost::unordered::piecewise_construct_t, \
149
+ namespace_ tuple<T> const& k, T2 const&) \
150
+ { \
151
+ return typename is_key<key_type, T>::type( \
152
+ namespace_ get<0>(k)); \
153
+ }
154
+
155
+ #else
156
+
157
+ #define BOOST_UNORDERED_KEY_FROM_TUPLE(namespace_) \
158
+ static no_key extract(boost::unordered::piecewise_construct_t, \
159
+ namespace_ tuple<> const&) \
160
+ { \
161
+ return no_key(); \
162
+ } \
163
+ \
164
+ template <typename T> \
165
+ static typename is_key<key_type, T>::type \
166
+ extract(boost::unordered::piecewise_construct_t, \
167
+ namespace_ tuple<T> const& k) \
168
+ { \
169
+ return typename is_key<key_type, T>::type( \
170
+ namespace_ get<0>(k)); \
171
+ }
172
+
173
+ #endif
174
+
175
+ BOOST_UNORDERED_KEY_FROM_TUPLE(boost::)
176
+
177
+ #if !defined(BOOST_NO_CXX11_HDR_TUPLE)
178
+ BOOST_UNORDERED_KEY_FROM_TUPLE(std::)
179
+ #endif
180
+ };
181
+ }}}
182
+
183
+ #endif
@@ -0,0 +1,23 @@
1
+
2
+ // Copyright (C) 2008-2011 Daniel James.
3
+ // Distributed under the Boost Software License, Version 1.0. (See accompanying
4
+ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
+
6
+ #ifndef BOOST_UNORDERED_FWD_HPP_INCLUDED
7
+ #define BOOST_UNORDERED_FWD_HPP_INCLUDED
8
+
9
+ #if defined(_MSC_VER) && (_MSC_VER >= 1020)
10
+ # pragma once
11
+ #endif
12
+
13
+
14
+ namespace boost
15
+ {
16
+ namespace unordered
17
+ {
18
+ struct piecewise_construct_t {};
19
+ const piecewise_construct_t piecewise_construct = piecewise_construct_t();
20
+ }
21
+ }
22
+
23
+ #endif
@@ -0,0 +1,861 @@
1
+
2
+ // Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
3
+ // Copyright (C) 2005-2011 Daniel James
4
+ // Distributed under the Boost Software License, Version 1.0. (See accompanying
5
+ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
+
7
+ #ifndef BOOST_UNORDERED_DETAIL_ALL_HPP_INCLUDED
8
+ #define BOOST_UNORDERED_DETAIL_ALL_HPP_INCLUDED
9
+
10
+ #include <boost/unordered/detail/buckets.hpp>
11
+ #include <boost/unordered/detail/util.hpp>
12
+ #include <boost/type_traits/aligned_storage.hpp>
13
+ #include <boost/type_traits/alignment_of.hpp>
14
+ #include <cmath>
15
+
16
+ #if defined(BOOST_MSVC)
17
+ #pragma warning(push)
18
+ #pragma warning(disable:4127) // conditional expression is constant
19
+ #endif
20
+
21
+ #if defined(BOOST_UNORDERED_DEPRECATED_EQUALITY)
22
+
23
+ #if defined(__EDG__)
24
+ #elif defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
25
+ #pragma message("Warning: BOOST_UNORDERED_DEPRECATED_EQUALITY is no longer supported.")
26
+ #elif defined(__GNUC__) || defined(__HP_aCC) || \
27
+ defined(__SUNPRO_CC) || defined(__IBMCPP__)
28
+ #warning "BOOST_UNORDERED_DEPRECATED_EQUALITY is no longer supported."
29
+ #endif
30
+
31
+ #endif
32
+
33
+ namespace boost { namespace unordered { namespace detail {
34
+
35
+ ////////////////////////////////////////////////////////////////////////////
36
+ // convert double to std::size_t
37
+
38
+ inline std::size_t double_to_size(double f)
39
+ {
40
+ return f >= static_cast<double>(
41
+ (std::numeric_limits<std::size_t>::max)()) ?
42
+ (std::numeric_limits<std::size_t>::max)() :
43
+ static_cast<std::size_t>(f);
44
+ }
45
+
46
+ // The space used to store values in a node.
47
+
48
+ template <typename ValueType>
49
+ struct value_base
50
+ {
51
+ typedef ValueType value_type;
52
+
53
+ typename boost::aligned_storage<
54
+ sizeof(value_type),
55
+ boost::alignment_of<value_type>::value>::type data_;
56
+
57
+ void* address() {
58
+ return this;
59
+ }
60
+
61
+ value_type& value() {
62
+ return *(ValueType*) this;
63
+ }
64
+
65
+ value_type* value_ptr() {
66
+ return (ValueType*) this;
67
+ }
68
+
69
+ private:
70
+
71
+ value_base& operator=(value_base const&);
72
+ };
73
+
74
+ template <typename NodeAlloc>
75
+ struct copy_nodes
76
+ {
77
+ typedef boost::unordered::detail::allocator_traits<NodeAlloc>
78
+ node_allocator_traits;
79
+
80
+ node_constructor<NodeAlloc> constructor;
81
+
82
+ explicit copy_nodes(NodeAlloc& a) : constructor(a) {}
83
+
84
+ typename node_allocator_traits::pointer create(
85
+ typename node_allocator_traits::value_type::value_type const& v)
86
+ {
87
+ constructor.construct_with_value2(v);
88
+ return constructor.release();
89
+ }
90
+ };
91
+
92
+ template <typename NodeAlloc>
93
+ struct move_nodes
94
+ {
95
+ typedef boost::unordered::detail::allocator_traits<NodeAlloc>
96
+ node_allocator_traits;
97
+
98
+ node_constructor<NodeAlloc> constructor;
99
+
100
+ explicit move_nodes(NodeAlloc& a) : constructor(a) {}
101
+
102
+ typename node_allocator_traits::pointer create(
103
+ typename node_allocator_traits::value_type::value_type& v)
104
+ {
105
+ constructor.construct_with_value2(boost::move(v));
106
+ return constructor.release();
107
+ }
108
+ };
109
+
110
+ template <typename Buckets>
111
+ struct assign_nodes
112
+ {
113
+ node_holder<typename Buckets::node_allocator> holder;
114
+
115
+ explicit assign_nodes(Buckets& b) : holder(b) {}
116
+
117
+ typename Buckets::node_pointer create(
118
+ typename Buckets::value_type const& v)
119
+ {
120
+ return holder.copy_of(v);
121
+ }
122
+ };
123
+
124
+ template <typename Buckets>
125
+ struct move_assign_nodes
126
+ {
127
+ node_holder<typename Buckets::node_allocator> holder;
128
+
129
+ explicit move_assign_nodes(Buckets& b) : holder(b) {}
130
+
131
+ typename Buckets::node_pointer create(
132
+ typename Buckets::value_type& v)
133
+ {
134
+ return holder.move_copy_of(v);
135
+ }
136
+ };
137
+
138
+ template <typename Types>
139
+ struct table :
140
+ boost::unordered::detail::functions<
141
+ typename Types::hasher,
142
+ typename Types::key_equal>
143
+ {
144
+ private:
145
+ table(table const&);
146
+ table& operator=(table const&);
147
+ public:
148
+ typedef typename Types::node node;
149
+ typedef typename Types::bucket bucket;
150
+ typedef typename Types::hasher hasher;
151
+ typedef typename Types::key_equal key_equal;
152
+ typedef typename Types::key_type key_type;
153
+ typedef typename Types::extractor extractor;
154
+ typedef typename Types::value_type value_type;
155
+ typedef typename Types::table table_impl;
156
+ typedef typename Types::link_pointer link_pointer;
157
+ typedef typename Types::policy policy;
158
+
159
+ typedef boost::unordered::detail::functions<
160
+ typename Types::hasher,
161
+ typename Types::key_equal> functions;
162
+ typedef typename functions::set_hash_functions set_hash_functions;
163
+
164
+ typedef typename Types::allocator allocator;
165
+ typedef typename boost::unordered::detail::
166
+ rebind_wrap<allocator, node>::type node_allocator;
167
+ typedef typename boost::unordered::detail::
168
+ rebind_wrap<allocator, bucket>::type bucket_allocator;
169
+ typedef boost::unordered::detail::allocator_traits<node_allocator>
170
+ node_allocator_traits;
171
+ typedef boost::unordered::detail::allocator_traits<bucket_allocator>
172
+ bucket_allocator_traits;
173
+ typedef typename node_allocator_traits::pointer
174
+ node_pointer;
175
+ typedef typename node_allocator_traits::const_pointer
176
+ const_node_pointer;
177
+ typedef typename bucket_allocator_traits::pointer
178
+ bucket_pointer;
179
+ typedef boost::unordered::detail::node_constructor<node_allocator>
180
+ node_constructor;
181
+
182
+ typedef boost::unordered::iterator_detail::
183
+ iterator<node> iterator;
184
+ typedef boost::unordered::iterator_detail::
185
+ c_iterator<node, const_node_pointer> c_iterator;
186
+ typedef boost::unordered::iterator_detail::
187
+ l_iterator<node, policy> l_iterator;
188
+ typedef boost::unordered::iterator_detail::
189
+ cl_iterator<node, const_node_pointer, policy> cl_iterator;
190
+
191
+ ////////////////////////////////////////////////////////////////////////
192
+ // Members
193
+
194
+ boost::unordered::detail::compressed<bucket_allocator, node_allocator>
195
+ allocators_;
196
+ std::size_t bucket_count_;
197
+ std::size_t size_;
198
+ float mlf_;
199
+ std::size_t max_load_;
200
+ bucket_pointer buckets_;
201
+
202
+ ////////////////////////////////////////////////////////////////////////
203
+ // Data access
204
+
205
+ bucket_allocator const& bucket_alloc() const
206
+ {
207
+ return allocators_.first();
208
+ }
209
+
210
+ node_allocator const& node_alloc() const
211
+ {
212
+ return allocators_.second();
213
+ }
214
+
215
+ bucket_allocator& bucket_alloc()
216
+ {
217
+ return allocators_.first();
218
+ }
219
+
220
+ node_allocator& node_alloc()
221
+ {
222
+ return allocators_.second();
223
+ }
224
+
225
+ std::size_t max_bucket_count() const
226
+ {
227
+ // -1 to account for the start bucket.
228
+ return policy::prev_bucket_count(
229
+ bucket_allocator_traits::max_size(bucket_alloc()) - 1);
230
+ }
231
+
232
+ bucket_pointer get_bucket(std::size_t bucket_index) const
233
+ {
234
+ BOOST_ASSERT(buckets_);
235
+ return buckets_ + static_cast<std::ptrdiff_t>(bucket_index);
236
+ }
237
+
238
+ link_pointer get_previous_start() const
239
+ {
240
+ return get_bucket(bucket_count_)->first_from_start();
241
+ }
242
+
243
+ link_pointer get_previous_start(std::size_t bucket_index) const
244
+ {
245
+ return get_bucket(bucket_index)->next_;
246
+ }
247
+
248
+ iterator begin() const
249
+ {
250
+ return size_ ? iterator(get_previous_start()->next_) : iterator();
251
+ }
252
+
253
+ iterator begin(std::size_t bucket_index) const
254
+ {
255
+ if (!size_) return iterator();
256
+ link_pointer prev = get_previous_start(bucket_index);
257
+ return prev ? iterator(prev->next_) : iterator();
258
+ }
259
+
260
+ std::size_t hash_to_bucket(std::size_t hash) const
261
+ {
262
+ return policy::to_bucket(bucket_count_, hash);
263
+ }
264
+
265
+ float load_factor() const
266
+ {
267
+ BOOST_ASSERT(bucket_count_ != 0);
268
+ return static_cast<float>(size_)
269
+ / static_cast<float>(bucket_count_);
270
+ }
271
+
272
+ std::size_t bucket_size(std::size_t index) const
273
+ {
274
+ iterator it = begin(index);
275
+ if (!it.node_) return 0;
276
+
277
+ std::size_t count = 0;
278
+ while(it.node_ && hash_to_bucket(it.node_->hash_) == index)
279
+ {
280
+ ++count;
281
+ ++it;
282
+ }
283
+
284
+ return count;
285
+ }
286
+
287
+ ////////////////////////////////////////////////////////////////////////
288
+ // Load methods
289
+
290
+ std::size_t max_size() const
291
+ {
292
+ using namespace std;
293
+
294
+ // size < mlf_ * count
295
+ return boost::unordered::detail::double_to_size(ceil(
296
+ static_cast<double>(mlf_) *
297
+ static_cast<double>(max_bucket_count())
298
+ )) - 1;
299
+ }
300
+
301
+ void recalculate_max_load()
302
+ {
303
+ using namespace std;
304
+
305
+ // From 6.3.1/13:
306
+ // Only resize when size >= mlf_ * count
307
+ max_load_ = buckets_ ? boost::unordered::detail::double_to_size(ceil(
308
+ static_cast<double>(mlf_) *
309
+ static_cast<double>(bucket_count_)
310
+ )) : 0;
311
+
312
+ }
313
+
314
+ void max_load_factor(float z)
315
+ {
316
+ BOOST_ASSERT(z > 0);
317
+ mlf_ = (std::max)(z, minimum_max_load_factor);
318
+ recalculate_max_load();
319
+ }
320
+
321
+ std::size_t min_buckets_for_size(std::size_t size) const
322
+ {
323
+ BOOST_ASSERT(mlf_ >= minimum_max_load_factor);
324
+
325
+ using namespace std;
326
+
327
+ // From 6.3.1/13:
328
+ // size < mlf_ * count
329
+ // => count > size / mlf_
330
+ //
331
+ // Or from rehash post-condition:
332
+ // count > size / mlf_
333
+
334
+ return policy::new_bucket_count(
335
+ boost::unordered::detail::double_to_size(floor(
336
+ static_cast<double>(size) /
337
+ static_cast<double>(mlf_))) + 1);
338
+ }
339
+
340
+ ////////////////////////////////////////////////////////////////////////
341
+ // Constructors
342
+
343
+ table(std::size_t num_buckets,
344
+ hasher const& hf,
345
+ key_equal const& eq,
346
+ node_allocator const& a) :
347
+ functions(hf, eq),
348
+ allocators_(a,a),
349
+ bucket_count_(policy::new_bucket_count(num_buckets)),
350
+ size_(0),
351
+ mlf_(1.0f),
352
+ max_load_(0),
353
+ buckets_()
354
+ {}
355
+
356
+ table(table const& x, node_allocator const& a) :
357
+ functions(x),
358
+ allocators_(a,a),
359
+ bucket_count_(x.min_buckets_for_size(x.size_)),
360
+ size_(0),
361
+ mlf_(x.mlf_),
362
+ max_load_(0),
363
+ buckets_()
364
+ {}
365
+
366
+ table(table& x, boost::unordered::detail::move_tag m) :
367
+ functions(x, m),
368
+ allocators_(x.allocators_, m),
369
+ bucket_count_(x.bucket_count_),
370
+ size_(x.size_),
371
+ mlf_(x.mlf_),
372
+ max_load_(x.max_load_),
373
+ buckets_(x.buckets_)
374
+ {
375
+ x.buckets_ = bucket_pointer();
376
+ x.size_ = 0;
377
+ x.max_load_ = 0;
378
+ }
379
+
380
+ table(table& x, node_allocator const& a,
381
+ boost::unordered::detail::move_tag m) :
382
+ functions(x, m),
383
+ allocators_(a, a),
384
+ bucket_count_(x.bucket_count_),
385
+ size_(0),
386
+ mlf_(x.mlf_),
387
+ max_load_(x.max_load_),
388
+ buckets_()
389
+ {}
390
+
391
+ ////////////////////////////////////////////////////////////////////////
392
+ // Initialisation.
393
+
394
+ void init(table const& x)
395
+ {
396
+ if (x.size_) {
397
+ create_buckets(bucket_count_);
398
+ copy_nodes<node_allocator> copy(node_alloc());
399
+ table_impl::fill_buckets(x.begin(), *this, copy);
400
+ }
401
+ }
402
+
403
+ void move_init(table& x)
404
+ {
405
+ if(node_alloc() == x.node_alloc()) {
406
+ move_buckets_from(x);
407
+ }
408
+ else if(x.size_) {
409
+ // TODO: Could pick new bucket size?
410
+ create_buckets(bucket_count_);
411
+
412
+ move_nodes<node_allocator> move(node_alloc());
413
+ node_holder<node_allocator> nodes(x);
414
+ table_impl::fill_buckets(nodes.begin(), *this, move);
415
+ }
416
+ }
417
+
418
+ ////////////////////////////////////////////////////////////////////////
419
+ // Create buckets
420
+
421
+ void create_buckets(std::size_t new_count)
422
+ {
423
+ boost::unordered::detail::array_constructor<bucket_allocator>
424
+ constructor(bucket_alloc());
425
+
426
+ // Creates an extra bucket to act as the start node.
427
+ constructor.construct(bucket(), new_count + 1);
428
+
429
+ if (buckets_)
430
+ {
431
+ // Copy the nodes to the new buckets, including the dummy
432
+ // node if there is one.
433
+ (constructor.get() +
434
+ static_cast<std::ptrdiff_t>(new_count))->next_ =
435
+ (buckets_ + static_cast<std::ptrdiff_t>(
436
+ bucket_count_))->next_;
437
+ destroy_buckets();
438
+ }
439
+ else if (bucket::extra_node)
440
+ {
441
+ node_constructor a(node_alloc());
442
+ a.construct();
443
+
444
+ (constructor.get() +
445
+ static_cast<std::ptrdiff_t>(new_count))->next_ =
446
+ a.release();
447
+ }
448
+
449
+ bucket_count_ = new_count;
450
+ buckets_ = constructor.release();
451
+ recalculate_max_load();
452
+ }
453
+
454
+ ////////////////////////////////////////////////////////////////////////
455
+ // Swap and Move
456
+
457
+ void swap_allocators(table& other, false_type)
458
+ {
459
+ // According to 23.2.1.8, if propagate_on_container_swap is
460
+ // false the behaviour is undefined unless the allocators
461
+ // are equal.
462
+ BOOST_ASSERT(node_alloc() == other.node_alloc());
463
+ }
464
+
465
+ void swap_allocators(table& other, true_type)
466
+ {
467
+ allocators_.swap(other.allocators_);
468
+ }
469
+
470
+ // Only swaps the allocators if propagate_on_container_swap
471
+ void swap(table& x)
472
+ {
473
+ set_hash_functions op1(*this, x);
474
+ set_hash_functions op2(x, *this);
475
+
476
+ // I think swap can throw if Propagate::value,
477
+ // since the allocators' swap can throw. Not sure though.
478
+ swap_allocators(x,
479
+ boost::unordered::detail::integral_constant<bool,
480
+ allocator_traits<node_allocator>::
481
+ propagate_on_container_swap::value>());
482
+
483
+ boost::swap(buckets_, x.buckets_);
484
+ boost::swap(bucket_count_, x.bucket_count_);
485
+ boost::swap(size_, x.size_);
486
+ std::swap(mlf_, x.mlf_);
487
+ std::swap(max_load_, x.max_load_);
488
+ op1.commit();
489
+ op2.commit();
490
+ }
491
+
492
+ void move_buckets_from(table& other)
493
+ {
494
+ BOOST_ASSERT(node_alloc() == other.node_alloc());
495
+ BOOST_ASSERT(!buckets_);
496
+ buckets_ = other.buckets_;
497
+ bucket_count_ = other.bucket_count_;
498
+ size_ = other.size_;
499
+ other.buckets_ = bucket_pointer();
500
+ other.size_ = 0;
501
+ other.max_load_ = 0;
502
+ }
503
+
504
+ ////////////////////////////////////////////////////////////////////////
505
+ // Delete/destruct
506
+
507
+ ~table()
508
+ {
509
+ delete_buckets();
510
+ }
511
+
512
+ void delete_node(link_pointer prev)
513
+ {
514
+ node_pointer n = static_cast<node_pointer>(prev->next_);
515
+ prev->next_ = n->next_;
516
+
517
+ boost::unordered::detail::destroy_value_impl(node_alloc(),
518
+ n->value_ptr());
519
+ node_allocator_traits::destroy(node_alloc(),
520
+ boost::addressof(*n));
521
+ node_allocator_traits::deallocate(node_alloc(), n, 1);
522
+ --size_;
523
+ }
524
+
525
+ std::size_t delete_nodes(link_pointer prev, link_pointer end)
526
+ {
527
+ BOOST_ASSERT(prev->next_ != end);
528
+
529
+ std::size_t count = 0;
530
+
531
+ do {
532
+ delete_node(prev);
533
+ ++count;
534
+ } while (prev->next_ != end);
535
+
536
+ return count;
537
+ }
538
+
539
+ void delete_buckets()
540
+ {
541
+ if(buckets_) {
542
+ if (size_) delete_nodes(get_previous_start(), link_pointer());
543
+
544
+ if (bucket::extra_node) {
545
+ node_pointer n = static_cast<node_pointer>(
546
+ get_bucket(bucket_count_)->next_);
547
+ node_allocator_traits::destroy(node_alloc(),
548
+ boost::addressof(*n));
549
+ node_allocator_traits::deallocate(node_alloc(), n, 1);
550
+ }
551
+
552
+ destroy_buckets();
553
+ buckets_ = bucket_pointer();
554
+ max_load_ = 0;
555
+ }
556
+
557
+ BOOST_ASSERT(!size_);
558
+ }
559
+
560
+ void clear()
561
+ {
562
+ if (!size_) return;
563
+
564
+ delete_nodes(get_previous_start(), link_pointer());
565
+ clear_buckets();
566
+
567
+ BOOST_ASSERT(!size_);
568
+ }
569
+
570
+ void clear_buckets()
571
+ {
572
+ bucket_pointer end = get_bucket(bucket_count_);
573
+ for(bucket_pointer it = buckets_; it != end; ++it)
574
+ {
575
+ it->next_ = node_pointer();
576
+ }
577
+ }
578
+
579
+ void destroy_buckets()
580
+ {
581
+ bucket_pointer end = get_bucket(bucket_count_ + 1);
582
+ for(bucket_pointer it = buckets_; it != end; ++it)
583
+ {
584
+ bucket_allocator_traits::destroy(bucket_alloc(),
585
+ boost::addressof(*it));
586
+ }
587
+
588
+ bucket_allocator_traits::deallocate(bucket_alloc(),
589
+ buckets_, bucket_count_ + 1);
590
+ }
591
+
592
+ ////////////////////////////////////////////////////////////////////////
593
+ // Fix buckets after delete
594
+ //
595
+
596
+ std::size_t fix_bucket(std::size_t bucket_index, link_pointer prev)
597
+ {
598
+ link_pointer end = prev->next_;
599
+ std::size_t bucket_index2 = bucket_index;
600
+
601
+ if (end)
602
+ {
603
+ bucket_index2 = hash_to_bucket(
604
+ static_cast<node_pointer>(end)->hash_);
605
+
606
+ // If begin and end are in the same bucket, then
607
+ // there's nothing to do.
608
+ if (bucket_index == bucket_index2) return bucket_index2;
609
+
610
+ // Update the bucket containing end.
611
+ get_bucket(bucket_index2)->next_ = prev;
612
+ }
613
+
614
+ // Check if this bucket is now empty.
615
+ bucket_pointer this_bucket = get_bucket(bucket_index);
616
+ if (this_bucket->next_ == prev)
617
+ this_bucket->next_ = link_pointer();
618
+
619
+ return bucket_index2;
620
+ }
621
+
622
+ ////////////////////////////////////////////////////////////////////////
623
+ // Assignment
624
+
625
+ void assign(table const& x)
626
+ {
627
+ if (this != boost::addressof(x))
628
+ {
629
+ assign(x,
630
+ boost::unordered::detail::integral_constant<bool,
631
+ allocator_traits<node_allocator>::
632
+ propagate_on_container_copy_assignment::value>());
633
+ }
634
+ }
635
+
636
+ void assign(table const& x, false_type)
637
+ {
638
+ // Strong exception safety.
639
+ set_hash_functions new_func_this(*this, x);
640
+ new_func_this.commit();
641
+ mlf_ = x.mlf_;
642
+ recalculate_max_load();
643
+
644
+ if (!size_ && !x.size_) return;
645
+
646
+ if (x.size_ >= max_load_) {
647
+ create_buckets(min_buckets_for_size(x.size_));
648
+ }
649
+ else {
650
+ clear_buckets();
651
+ }
652
+
653
+ // assign_nodes takes ownership of the container's elements,
654
+ // assigning to them if possible, and deleting any that are
655
+ // left over.
656
+ assign_nodes<table> assign(*this);
657
+ table_impl::fill_buckets(x.begin(), *this, assign);
658
+ }
659
+
660
+ void assign(table const& x, true_type)
661
+ {
662
+ if (node_alloc() == x.node_alloc()) {
663
+ allocators_.assign(x.allocators_);
664
+ assign(x, false_type());
665
+ }
666
+ else {
667
+ set_hash_functions new_func_this(*this, x);
668
+
669
+ // Delete everything with current allocators before assigning
670
+ // the new ones.
671
+ delete_buckets();
672
+ allocators_.assign(x.allocators_);
673
+
674
+ // Copy over other data, all no throw.
675
+ new_func_this.commit();
676
+ mlf_ = x.mlf_;
677
+ bucket_count_ = min_buckets_for_size(x.size_);
678
+ max_load_ = 0;
679
+
680
+ // Finally copy the elements.
681
+ if (x.size_) {
682
+ create_buckets(bucket_count_);
683
+ copy_nodes<node_allocator> copy(node_alloc());
684
+ table_impl::fill_buckets(x.begin(), *this, copy);
685
+ }
686
+ }
687
+ }
688
+
689
+ void move_assign(table& x)
690
+ {
691
+ if (this != boost::addressof(x))
692
+ {
693
+ move_assign(x,
694
+ boost::unordered::detail::integral_constant<bool,
695
+ allocator_traits<node_allocator>::
696
+ propagate_on_container_move_assignment::value>());
697
+ }
698
+ }
699
+
700
+ void move_assign(table& x, true_type)
701
+ {
702
+ delete_buckets();
703
+ allocators_.move_assign(x.allocators_);
704
+ move_assign_no_alloc(x);
705
+ }
706
+
707
+ void move_assign(table& x, false_type)
708
+ {
709
+ if (node_alloc() == x.node_alloc()) {
710
+ delete_buckets();
711
+ move_assign_no_alloc(x);
712
+ }
713
+ else {
714
+ set_hash_functions new_func_this(*this, x);
715
+ new_func_this.commit();
716
+ mlf_ = x.mlf_;
717
+ recalculate_max_load();
718
+
719
+ if (!size_ && !x.size_) return;
720
+
721
+ if (x.size_ >= max_load_) {
722
+ create_buckets(min_buckets_for_size(x.size_));
723
+ }
724
+ else {
725
+ clear_buckets();
726
+ }
727
+
728
+ // move_assign_nodes takes ownership of the container's
729
+ // elements, assigning to them if possible, and deleting
730
+ // any that are left over.
731
+ move_assign_nodes<table> assign(*this);
732
+ node_holder<node_allocator> nodes(x);
733
+ table_impl::fill_buckets(nodes.begin(), *this, assign);
734
+ }
735
+ }
736
+
737
+ void move_assign_no_alloc(table& x)
738
+ {
739
+ set_hash_functions new_func_this(*this, x);
740
+ // No throw from here.
741
+ mlf_ = x.mlf_;
742
+ max_load_ = x.max_load_;
743
+ move_buckets_from(x);
744
+ new_func_this.commit();
745
+ }
746
+
747
+ // Accessors
748
+
749
+ key_type const& get_key(value_type const& x) const
750
+ {
751
+ return extractor::extract(x);
752
+ }
753
+
754
+ std::size_t hash(key_type const& k) const
755
+ {
756
+ return policy::apply_hash(this->hash_function(), k);
757
+ }
758
+
759
+ // Find Node
760
+
761
+ template <typename Key, typename Hash, typename Pred>
762
+ iterator generic_find_node(
763
+ Key const& k,
764
+ Hash const& hf,
765
+ Pred const& eq) const
766
+ {
767
+ return static_cast<table_impl const*>(this)->
768
+ find_node_impl(policy::apply_hash(hf, k), k, eq);
769
+ }
770
+
771
+ iterator find_node(
772
+ std::size_t key_hash,
773
+ key_type const& k) const
774
+ {
775
+ return static_cast<table_impl const*>(this)->
776
+ find_node_impl(key_hash, k, this->key_eq());
777
+ }
778
+
779
+ iterator find_node(key_type const& k) const
780
+ {
781
+ return static_cast<table_impl const*>(this)->
782
+ find_node_impl(hash(k), k, this->key_eq());
783
+ }
784
+
785
+ iterator find_matching_node(iterator n) const
786
+ {
787
+ // TODO: Does this apply to C++11?
788
+ //
789
+ // For some stupid reason, I decided to support equality comparison
790
+ // when different hash functions are used. So I can't use the hash
791
+ // value from the node here.
792
+
793
+ return find_node(get_key(*n));
794
+ }
795
+
796
+ // Reserve and rehash
797
+
798
+ void reserve_for_insert(std::size_t);
799
+ void rehash(std::size_t);
800
+ void reserve(std::size_t);
801
+ };
802
+
803
+ ////////////////////////////////////////////////////////////////////////////
804
+ // Reserve & Rehash
805
+
806
+ // basic exception safety
807
+ template <typename Types>
808
+ inline void table<Types>::reserve_for_insert(std::size_t size)
809
+ {
810
+ if (!buckets_) {
811
+ create_buckets((std::max)(bucket_count_,
812
+ min_buckets_for_size(size)));
813
+ }
814
+ // According to the standard this should be 'size >= max_load_',
815
+ // but I think this is better, defect report filed.
816
+ else if(size > max_load_) {
817
+ std::size_t num_buckets
818
+ = min_buckets_for_size((std::max)(size,
819
+ size_ + (size_ >> 1)));
820
+
821
+ if (num_buckets != bucket_count_)
822
+ static_cast<table_impl*>(this)->rehash_impl(num_buckets);
823
+ }
824
+ }
825
+
826
+ // if hash function throws, basic exception safety
827
+ // strong otherwise.
828
+
829
+ template <typename Types>
830
+ inline void table<Types>::rehash(std::size_t min_buckets)
831
+ {
832
+ using namespace std;
833
+
834
+ if(!size_) {
835
+ delete_buckets();
836
+ bucket_count_ = policy::new_bucket_count(min_buckets);
837
+ }
838
+ else {
839
+ min_buckets = policy::new_bucket_count((std::max)(min_buckets,
840
+ boost::unordered::detail::double_to_size(floor(
841
+ static_cast<double>(size_) /
842
+ static_cast<double>(mlf_))) + 1));
843
+
844
+ if(min_buckets != bucket_count_)
845
+ static_cast<table_impl*>(this)->rehash_impl(min_buckets);
846
+ }
847
+ }
848
+
849
+ template <typename Types>
850
+ inline void table<Types>::reserve(std::size_t num_elements)
851
+ {
852
+ rehash(static_cast<std::size_t>(
853
+ std::ceil(static_cast<double>(num_elements) / mlf_)));
854
+ }
855
+ }}}
856
+
857
+ #if defined(BOOST_MSVC)
858
+ #pragma warning(pop)
859
+ #endif
860
+
861
+ #endif