passenger 5.1.4 → 5.1.5

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 (542) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +9 -0
  3. data/CHANGELOG +9 -0
  4. data/build/cxx_tests.rb +11 -1
  5. data/build/documentation.rb +0 -32
  6. data/build/support/cxx_dependency_map.rb +602 -2
  7. data/build/test_basics.rb +3 -3
  8. data/dev/boost-patches/0001-Patch-boost-thread-so-that-oxt-thread-can-use-it.patch +48 -0
  9. data/dev/boost-patches/0002-Make-boost-thread_interrupted-derive-from-oxt-tracab.patch +33 -0
  10. data/dev/boost-patches/0003-Disable-a-Clang-pragma-to-prevent-warnings-on-OS-X.patch +25 -0
  11. data/dev/ci/README.md +121 -0
  12. data/dev/ci/lib/functions.sh +129 -0
  13. data/dev/ci/lib/set-container-envvars.sh +46 -0
  14. data/dev/ci/lib/setup-container.sh +43 -0
  15. data/dev/ci/run-tests-natively +24 -0
  16. data/dev/ci/run-tests-with-docker +42 -0
  17. data/dev/ci/scripts/debug-console-wrapper.sh +27 -0
  18. data/dev/ci/scripts/docker-entrypoint-stage2.sh +17 -0
  19. data/dev/ci/scripts/docker-entrypoint.sh +17 -0
  20. data/dev/ci/scripts/inituidgid +17 -0
  21. data/dev/ci/scripts/run-tests-natively-stage2.sh +17 -0
  22. data/dev/ci/scripts/setup-host-natively.sh +11 -0
  23. data/dev/ci/setup-host +50 -0
  24. data/dev/ci/tests/apache2/run +6 -0
  25. data/dev/ci/tests/apache2/setup +4 -0
  26. data/dev/ci/tests/cxx/run +9 -0
  27. data/dev/ci/tests/cxx/setup +4 -0
  28. data/dev/ci/tests/nginx-dynamic/run +20 -0
  29. data/dev/ci/tests/nginx-dynamic/setup +4 -0
  30. data/dev/ci/tests/nginx/run +5 -0
  31. data/dev/ci/tests/nginx/setup +4 -0
  32. data/dev/ci/tests/nodejs/run +4 -0
  33. data/dev/ci/tests/nodejs/setup +4 -0
  34. data/dev/ci/tests/ruby/run +4 -0
  35. data/dev/ci/tests/ruby/setup +4 -0
  36. data/dev/ci/tests/source-packaging/run +4 -0
  37. data/dev/ci/tests/source-packaging/setup +4 -0
  38. data/dev/ci/tests/standalone/run +4 -0
  39. data/dev/ci/tests/standalone/setup +4 -0
  40. data/dev/copy_boost_headers +8 -2
  41. data/src/agent/Core/ApiServer.h +11 -5
  42. data/src/agent/Core/Controller.h +12 -46
  43. data/src/agent/Core/Controller/CheckoutSession.cpp +1 -1
  44. data/src/agent/Core/Controller/Config.h +369 -0
  45. data/src/agent/Core/Controller/ForwardResponse.cpp +4 -4
  46. data/src/agent/Core/Controller/Hooks.cpp +15 -3
  47. data/src/agent/Core/Controller/Implementation.cpp +1 -1
  48. data/src/agent/Core/Controller/InitRequest.cpp +28 -39
  49. data/src/agent/Core/Controller/InitializationAndShutdown.cpp +25 -60
  50. data/src/agent/Core/Controller/InternalUtils.cpp +0 -16
  51. data/src/agent/Core/Controller/Miscellaneous.cpp +0 -17
  52. data/src/agent/Core/Controller/Request.h +2 -0
  53. data/src/agent/Core/Controller/SendRequest.cpp +4 -4
  54. data/src/agent/Core/Controller/{StateInspectionAndConfiguration.cpp → StateInspection.cpp} +0 -22
  55. data/src/agent/Core/Controller/TurboCaching.h +11 -10
  56. data/src/agent/Core/CoreMain.cpp +16 -6
  57. data/src/agent/Core/ResponseCache.h +3 -3
  58. data/src/agent/Core/SpawningKit/SmartSpawner.h +9 -3
  59. data/src/agent/Core/SpawningKit/Spawner.h +7 -3
  60. data/src/agent/UstRouter/ApiServer.h +3 -2
  61. data/src/agent/UstRouter/Controller.h +66 -32
  62. data/src/agent/UstRouter/UstRouterMain.cpp +10 -2
  63. data/src/agent/Watchdog/ApiServer.h +3 -2
  64. data/src/agent/Watchdog/WatchdogMain.cpp +3 -1
  65. data/src/apache2_module/ConfigurationCommands.cpp +1 -1
  66. data/src/cxx_supportlib/ConfigKit/Common.h +125 -0
  67. data/src/cxx_supportlib/ConfigKit/ConfigKit.h +34 -0
  68. data/src/cxx_supportlib/ConfigKit/README.md +895 -0
  69. data/src/cxx_supportlib/ConfigKit/Schema.h +331 -0
  70. data/src/cxx_supportlib/ConfigKit/Store.h +385 -0
  71. data/src/cxx_supportlib/ConfigKit/TableTranslator.h +185 -0
  72. data/src/cxx_supportlib/ConfigKit/Utils.h +141 -0
  73. data/src/cxx_supportlib/ConfigKit/VariantMapUtils.h +81 -0
  74. data/src/cxx_supportlib/Constants.h +1 -1
  75. data/src/cxx_supportlib/Crypto.cpp +2 -2
  76. data/src/cxx_supportlib/Logging.h +0 -35
  77. data/src/cxx_supportlib/ServerKit/HttpServer.h +35 -16
  78. data/src/cxx_supportlib/ServerKit/Server.h +65 -25
  79. data/src/cxx_supportlib/oxt/macros.hpp +3 -0
  80. data/src/cxx_supportlib/vendor-modified/boost/algorithm/string/replace.hpp +0 -2
  81. data/src/cxx_supportlib/vendor-modified/boost/array.hpp +53 -42
  82. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/atomic_template.hpp +11 -5
  83. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/bitwise_cast.hpp +13 -2
  84. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/caps_gcc_x86.hpp +23 -0
  85. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/caps_msvc_x86.hpp +5 -0
  86. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/config.hpp +3 -2
  87. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/interlocked.hpp +8 -1
  88. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_emulated.hpp +3 -1
  89. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_alpha.hpp +2 -0
  90. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_arm.hpp +2 -0
  91. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_atomic.hpp +5 -0
  92. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_ppc.hpp +2 -0
  93. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_sparc.hpp +6 -4
  94. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_sync.hpp +2 -0
  95. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_x86.hpp +3 -1
  96. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_x86_dcas.hpp +28 -17
  97. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_linux_arm.hpp +2 -0
  98. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_msvc_arm.hpp +2 -0
  99. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_msvc_x86.hpp +9 -4
  100. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/platform.hpp +3 -3
  101. data/src/cxx_supportlib/vendor-modified/boost/bind/arg.hpp +10 -3
  102. data/src/cxx_supportlib/vendor-modified/boost/bind/bind.hpp +90 -18
  103. data/src/cxx_supportlib/vendor-modified/boost/cerrno.hpp +2 -2
  104. data/src/cxx_supportlib/vendor-modified/boost/chrono/duration.hpp +1 -1
  105. data/src/cxx_supportlib/vendor-modified/boost/config/auto_link.hpp +8 -3
  106. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/borland.hpp +2 -0
  107. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/clang.hpp +35 -6
  108. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/codegear.hpp +2 -0
  109. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/comeau.hpp +1 -1
  110. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/common_edg.hpp +2 -0
  111. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/compaq_cxx.hpp +1 -1
  112. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/cray.hpp +3 -1
  113. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/digitalmars.hpp +2 -0
  114. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/gcc.hpp +19 -4
  115. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/gcc_xml.hpp +3 -1
  116. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/greenhills.hpp +1 -1
  117. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/hp_acc.hpp +3 -1
  118. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/intel.hpp +29 -7
  119. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/kai.hpp +1 -1
  120. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/metrowerks.hpp +2 -0
  121. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/mpw.hpp +2 -0
  122. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/nvcc.hpp +16 -0
  123. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/pathscale.hpp +2 -0
  124. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/pgi.hpp +2 -0
  125. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/sgi_mipspro.hpp +1 -1
  126. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/sunpro_cc.hpp +10 -1
  127. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/vacpp.hpp +2 -0
  128. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/visualc.hpp +44 -16
  129. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/xlcpp.hpp +4 -0
  130. data/src/cxx_supportlib/vendor-modified/boost/config/platform/cygwin.hpp +1 -2
  131. data/src/cxx_supportlib/vendor-modified/boost/config/platform/linux.hpp +1 -1
  132. data/src/cxx_supportlib/vendor-modified/boost/config/select_compiler_config.hpp +21 -21
  133. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/dinkumware.hpp +42 -1
  134. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/libcomo.hpp +7 -0
  135. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/libcpp.hpp +40 -7
  136. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/libstdcpp3.hpp +39 -6
  137. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/modena.hpp +7 -0
  138. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/msl.hpp +7 -0
  139. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/roguewave.hpp +7 -0
  140. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/sgi.hpp +8 -1
  141. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/stlport.hpp +7 -0
  142. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/vacpp.hpp +7 -0
  143. data/src/cxx_supportlib/vendor-modified/boost/config/suffix.hpp +33 -4
  144. data/src/cxx_supportlib/vendor-modified/boost/container/adaptive_pool.hpp +0 -2
  145. data/src/cxx_supportlib/vendor-modified/boost/container/allocator.hpp +0 -3
  146. data/src/cxx_supportlib/vendor-modified/boost/container/allocator_traits.hpp +34 -27
  147. data/src/cxx_supportlib/vendor-modified/boost/container/deque.hpp +62 -26
  148. data/src/cxx_supportlib/vendor-modified/boost/container/detail/addressof.hpp +2 -2
  149. data/src/cxx_supportlib/vendor-modified/boost/container/detail/advanced_insert_int.hpp +4 -4
  150. data/src/cxx_supportlib/vendor-modified/boost/container/detail/compare_functors.hpp +4 -4
  151. data/src/cxx_supportlib/vendor-modified/boost/container/detail/config_begin.hpp +2 -0
  152. data/src/cxx_supportlib/vendor-modified/boost/container/detail/construct_in_place.hpp +39 -5
  153. data/src/cxx_supportlib/vendor-modified/boost/container/detail/copy_move_algo.hpp +49 -32
  154. data/src/cxx_supportlib/vendor-modified/boost/container/detail/dispatch_uses_allocator.hpp +175 -7
  155. data/src/cxx_supportlib/vendor-modified/boost/container/detail/flat_tree.hpp +223 -98
  156. data/src/cxx_supportlib/vendor-modified/boost/container/detail/is_sorted.hpp +57 -0
  157. data/src/cxx_supportlib/vendor-modified/boost/container/detail/iterators.hpp +88 -41
  158. data/src/cxx_supportlib/vendor-modified/boost/container/detail/mpl.hpp +7 -8
  159. data/src/cxx_supportlib/vendor-modified/boost/container/detail/mutex.hpp +4 -9
  160. data/src/cxx_supportlib/vendor-modified/boost/container/detail/node_alloc_holder.hpp +45 -18
  161. data/src/cxx_supportlib/vendor-modified/boost/container/detail/pair.hpp +205 -26
  162. data/src/cxx_supportlib/vendor-modified/boost/container/detail/tree.hpp +290 -181
  163. data/src/cxx_supportlib/vendor-modified/boost/container/detail/value_init.hpp +2 -0
  164. data/src/cxx_supportlib/vendor-modified/boost/container/detail/variadic_templates_tools.hpp +24 -19
  165. data/src/cxx_supportlib/vendor-modified/boost/container/detail/workaround.hpp +38 -0
  166. data/src/cxx_supportlib/vendor-modified/boost/container/flat_map.hpp +320 -46
  167. data/src/cxx_supportlib/vendor-modified/boost/container/flat_set.hpp +91 -18
  168. data/src/cxx_supportlib/vendor-modified/boost/container/list.hpp +23 -19
  169. data/src/cxx_supportlib/vendor-modified/boost/container/map.hpp +491 -120
  170. data/src/cxx_supportlib/vendor-modified/boost/container/new_allocator.hpp +4 -4
  171. data/src/cxx_supportlib/vendor-modified/boost/container/node_allocator.hpp +0 -3
  172. data/src/cxx_supportlib/vendor-modified/boost/container/node_handle.hpp +399 -0
  173. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/deque.hpp +2 -0
  174. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/flat_map.hpp +4 -0
  175. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/flat_set.hpp +4 -0
  176. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/list.hpp +2 -0
  177. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/map.hpp +4 -0
  178. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/set.hpp +4 -0
  179. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/slist.hpp +2 -0
  180. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/small_vector.hpp +2 -0
  181. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/stable_vector.hpp +2 -0
  182. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/string.hpp +2 -0
  183. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/vector.hpp +2 -0
  184. data/src/cxx_supportlib/vendor-modified/boost/container/set.hpp +101 -20
  185. data/src/cxx_supportlib/vendor-modified/boost/container/slist.hpp +19 -14
  186. data/src/cxx_supportlib/vendor-modified/boost/container/small_vector.hpp +117 -59
  187. data/src/cxx_supportlib/vendor-modified/boost/container/stable_vector.hpp +8 -6
  188. data/src/cxx_supportlib/vendor-modified/boost/container/static_vector.hpp +33 -28
  189. data/src/cxx_supportlib/vendor-modified/boost/container/string.hpp +414 -70
  190. data/src/cxx_supportlib/vendor-modified/boost/container/throw_exception.hpp +1 -0
  191. data/src/cxx_supportlib/vendor-modified/boost/container/uses_allocator_fwd.hpp +2 -2
  192. data/src/cxx_supportlib/vendor-modified/boost/container/vector.hpp +134 -117
  193. data/src/cxx_supportlib/vendor-modified/boost/core/addressof.hpp +202 -99
  194. data/src/cxx_supportlib/vendor-modified/boost/core/demangle.hpp +8 -10
  195. data/src/cxx_supportlib/vendor-modified/boost/core/lightweight_test.hpp +217 -1
  196. data/src/cxx_supportlib/vendor-modified/boost/core/scoped_enum.hpp +29 -27
  197. data/src/cxx_supportlib/vendor-modified/boost/current_function.hpp +5 -1
  198. data/src/cxx_supportlib/vendor-modified/boost/date_time/c_time.hpp +13 -13
  199. data/src/cxx_supportlib/vendor-modified/boost/date_time/constrained_value.hpp +3 -3
  200. data/src/cxx_supportlib/vendor-modified/boost/date_time/date.hpp +2 -1
  201. data/src/cxx_supportlib/vendor-modified/boost/date_time/date_duration.hpp +4 -3
  202. data/src/cxx_supportlib/vendor-modified/boost/date_time/date_duration_types.hpp +6 -5
  203. data/src/cxx_supportlib/vendor-modified/boost/date_time/date_facet.hpp +2 -2
  204. data/src/cxx_supportlib/vendor-modified/boost/date_time/date_names_put.hpp +8 -7
  205. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_calendar.hpp +2 -1
  206. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_date.hpp +2 -1
  207. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_day.hpp +4 -3
  208. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_day_of_year.hpp +3 -2
  209. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_duration.hpp +2 -1
  210. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_duration_types.hpp +4 -3
  211. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_facet.hpp +27 -7
  212. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_month.hpp +5 -5
  213. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_serialize.hpp +5 -0
  214. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_weekday.hpp +4 -4
  215. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_year.hpp +4 -5
  216. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian_calendar.hpp +2 -1
  217. data/src/cxx_supportlib/vendor-modified/boost/date_time/local_time/local_date_time.hpp +5 -4
  218. data/src/cxx_supportlib/vendor-modified/boost/date_time/local_time/posix_time_zone.hpp +4 -3
  219. data/src/cxx_supportlib/vendor-modified/boost/date_time/period.hpp +3 -2
  220. data/src/cxx_supportlib/vendor-modified/boost/date_time/posix_time/date_duration_operators.hpp +1 -1
  221. data/src/cxx_supportlib/vendor-modified/boost/date_time/posix_time/posix_time_config.hpp +2 -2
  222. data/src/cxx_supportlib/vendor-modified/boost/date_time/posix_time/posix_time_duration.hpp +5 -4
  223. data/src/cxx_supportlib/vendor-modified/boost/date_time/posix_time/ptime.hpp +6 -5
  224. data/src/cxx_supportlib/vendor-modified/boost/date_time/posix_time/time_parsers.hpp +4 -0
  225. data/src/cxx_supportlib/vendor-modified/boost/date_time/time_duration.hpp +2 -2
  226. data/src/cxx_supportlib/vendor-modified/boost/date_time/time_facet.hpp +5 -4
  227. data/src/cxx_supportlib/vendor-modified/boost/date_time/time_zone_base.hpp +2 -1
  228. data/src/cxx_supportlib/vendor-modified/boost/date_time/year_month_day.hpp +3 -1
  229. data/src/cxx_supportlib/vendor-modified/boost/detail/iterator.hpp +13 -0
  230. data/src/cxx_supportlib/vendor-modified/boost/detail/lcast_precision.hpp +1 -0
  231. data/src/cxx_supportlib/vendor-modified/boost/detail/workaround.hpp +5 -0
  232. data/src/cxx_supportlib/vendor-modified/boost/exception/detail/error_info_impl.hpp +11 -0
  233. data/src/cxx_supportlib/vendor-modified/boost/exception/detail/shared_ptr.hpp +17 -0
  234. data/src/cxx_supportlib/vendor-modified/boost/exception/exception.hpp +25 -3
  235. data/src/cxx_supportlib/vendor-modified/boost/exception/get_error_info.hpp +2 -1
  236. data/src/cxx_supportlib/vendor-modified/boost/exception/info.hpp +114 -1
  237. data/src/cxx_supportlib/vendor-modified/boost/function/function_base.hpp +116 -142
  238. data/src/cxx_supportlib/vendor-modified/boost/function/function_template.hpp +57 -69
  239. data/src/cxx_supportlib/vendor-modified/boost/functional/hash/detail/hash_float.hpp +1 -1
  240. data/src/cxx_supportlib/vendor-modified/boost/functional/hash/extensions.hpp +3 -3
  241. data/src/cxx_supportlib/vendor-modified/boost/functional/hash/hash.hpp +27 -13
  242. data/src/cxx_supportlib/vendor-modified/boost/intrusive/any_hook.hpp +4 -2
  243. data/src/cxx_supportlib/vendor-modified/boost/intrusive/avl_set.hpp +99 -12
  244. data/src/cxx_supportlib/vendor-modified/boost/intrusive/avl_set_hook.hpp +4 -2
  245. data/src/cxx_supportlib/vendor-modified/boost/intrusive/avltree.hpp +35 -4
  246. data/src/cxx_supportlib/vendor-modified/boost/intrusive/avltree_algorithms.hpp +37 -6
  247. data/src/cxx_supportlib/vendor-modified/boost/intrusive/bs_set.hpp +95 -8
  248. data/src/cxx_supportlib/vendor-modified/boost/intrusive/bs_set_hook.hpp +4 -2
  249. data/src/cxx_supportlib/vendor-modified/boost/intrusive/bstree.hpp +209 -72
  250. data/src/cxx_supportlib/vendor-modified/boost/intrusive/bstree_algorithms.hpp +86 -20
  251. data/src/cxx_supportlib/vendor-modified/boost/intrusive/circular_list_algorithms.hpp +11 -11
  252. data/src/cxx_supportlib/vendor-modified/boost/intrusive/circular_slist_algorithms.hpp +6 -6
  253. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/algo_type.hpp +4 -1
  254. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/any_node_and_algorithms.hpp +58 -45
  255. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/avltree_node.hpp +27 -26
  256. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/bstree_algorithms_base.hpp +2 -2
  257. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/common_slist_algorithms.hpp +7 -7
  258. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/config_begin.hpp +8 -3
  259. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/default_header_holder.hpp +4 -3
  260. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/ebo_functor_holder.hpp +27 -26
  261. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/equal_to_value.hpp +3 -1
  262. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/exception_disposer.hpp +4 -2
  263. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/generic_hook.hpp +9 -7
  264. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/has_member_function_callable_with.hpp +83 -57
  265. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/hashtable_node.hpp +30 -30
  266. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/hook_traits.hpp +9 -8
  267. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/iiterator.hpp +8 -7
  268. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/iterator.hpp +16 -15
  269. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/key_nodeptr_comp.hpp +70 -44
  270. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/list_iterator.hpp +22 -21
  271. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/list_node.hpp +7 -6
  272. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/parent_from_member.hpp +5 -4
  273. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/rbtree_node.hpp +29 -28
  274. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/reverse_iterator.hpp +33 -12
  275. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/size_holder.hpp +19 -12
  276. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/slist_iterator.hpp +21 -20
  277. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/slist_node.hpp +4 -3
  278. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/to_raw_pointer.hpp +3 -2
  279. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/transform_iterator.hpp +23 -22
  280. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/tree_iterator.hpp +23 -22
  281. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/tree_node.hpp +10 -9
  282. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/tree_value_compare.hpp +103 -29
  283. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/workaround.hpp +15 -0
  284. data/src/cxx_supportlib/vendor-modified/boost/intrusive/hashtable.hpp +295 -211
  285. data/src/cxx_supportlib/vendor-modified/boost/intrusive/linear_slist_algorithms.hpp +2 -2
  286. data/src/cxx_supportlib/vendor-modified/boost/intrusive/list.hpp +20 -7
  287. data/src/cxx_supportlib/vendor-modified/boost/intrusive/list_hook.hpp +4 -2
  288. data/src/cxx_supportlib/vendor-modified/boost/intrusive/member_value_traits.hpp +5 -4
  289. data/src/cxx_supportlib/vendor-modified/boost/intrusive/options.hpp +4 -4
  290. data/src/cxx_supportlib/vendor-modified/boost/intrusive/parent_from_member.hpp +3 -2
  291. data/src/cxx_supportlib/vendor-modified/boost/intrusive/pointer_plus_bits.hpp +4 -4
  292. data/src/cxx_supportlib/vendor-modified/boost/intrusive/pointer_traits.hpp +4 -4
  293. data/src/cxx_supportlib/vendor-modified/boost/intrusive/priority_compare.hpp +22 -4
  294. data/src/cxx_supportlib/vendor-modified/boost/intrusive/rbtree.hpp +36 -4
  295. data/src/cxx_supportlib/vendor-modified/boost/intrusive/rbtree_algorithms.hpp +43 -13
  296. data/src/cxx_supportlib/vendor-modified/boost/intrusive/set.hpp +95 -8
  297. data/src/cxx_supportlib/vendor-modified/boost/intrusive/set_hook.hpp +4 -2
  298. data/src/cxx_supportlib/vendor-modified/boost/intrusive/sg_set.hpp +96 -12
  299. data/src/cxx_supportlib/vendor-modified/boost/intrusive/sgtree.hpp +102 -5
  300. data/src/cxx_supportlib/vendor-modified/boost/intrusive/sgtree_algorithms.hpp +48 -4
  301. data/src/cxx_supportlib/vendor-modified/boost/intrusive/slist.hpp +20 -11
  302. data/src/cxx_supportlib/vendor-modified/boost/intrusive/slist_hook.hpp +9 -2
  303. data/src/cxx_supportlib/vendor-modified/boost/intrusive/splay_set.hpp +95 -8
  304. data/src/cxx_supportlib/vendor-modified/boost/intrusive/splaytree.hpp +36 -4
  305. data/src/cxx_supportlib/vendor-modified/boost/intrusive/splaytree_algorithms.hpp +27 -0
  306. data/src/cxx_supportlib/vendor-modified/boost/intrusive/treap.hpp +167 -23
  307. data/src/cxx_supportlib/vendor-modified/boost/intrusive/treap_algorithms.hpp +28 -0
  308. data/src/cxx_supportlib/vendor-modified/boost/intrusive/treap_set.hpp +100 -46
  309. data/src/cxx_supportlib/vendor-modified/boost/intrusive/trivial_value_traits.hpp +5 -4
  310. data/src/cxx_supportlib/vendor-modified/boost/intrusive/unordered_set.hpp +37 -27
  311. data/src/cxx_supportlib/vendor-modified/boost/intrusive/unordered_set_hook.hpp +30 -14
  312. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast.hpp +1 -1
  313. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/converter_lexical_streams.hpp +35 -36
  314. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/converter_numeric.hpp +6 -28
  315. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/try_lexical_convert.hpp +20 -5
  316. data/src/cxx_supportlib/vendor-modified/boost/libs/regex/src/posix_api.cpp +4 -2
  317. data/src/cxx_supportlib/vendor-modified/boost/libs/regex/src/regex.cpp +3 -1
  318. data/src/cxx_supportlib/vendor-modified/boost/libs/thread/src/pthread/once.cpp +5 -0
  319. data/src/cxx_supportlib/vendor-modified/boost/libs/thread/src/pthread/thread.cpp +11 -7
  320. data/src/cxx_supportlib/vendor-modified/boost/math/policies/policy.hpp +1 -3
  321. data/src/cxx_supportlib/vendor-modified/boost/math/special_functions/fpclassify.hpp +5 -1
  322. data/src/cxx_supportlib/vendor-modified/boost/math/special_functions/math_fwd.hpp +11 -0
  323. data/src/cxx_supportlib/vendor-modified/boost/math/tools/config.hpp +10 -2
  324. data/src/cxx_supportlib/vendor-modified/boost/move/adl_move_swap.hpp +40 -7
  325. data/src/cxx_supportlib/vendor-modified/boost/move/algo/adaptive_merge.hpp +67 -0
  326. data/src/cxx_supportlib/vendor-modified/boost/move/algo/adaptive_sort.hpp +63 -0
  327. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/adaptive_sort_merge.hpp +2437 -0
  328. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/basic_op.hpp +121 -0
  329. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/insertion_sort.hpp +127 -0
  330. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/merge.hpp +637 -0
  331. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/merge_sort.hpp +139 -0
  332. data/src/cxx_supportlib/vendor-modified/boost/move/algo/move.hpp +155 -0
  333. data/src/cxx_supportlib/vendor-modified/boost/move/algorithm.hpp +1 -116
  334. data/src/cxx_supportlib/vendor-modified/boost/move/core.hpp +14 -13
  335. data/src/cxx_supportlib/vendor-modified/boost/move/default_delete.hpp +17 -1
  336. data/src/cxx_supportlib/vendor-modified/boost/move/detail/config_begin.hpp +2 -0
  337. data/src/cxx_supportlib/vendor-modified/boost/move/detail/destruct_n.hpp +67 -0
  338. data/src/cxx_supportlib/vendor-modified/boost/move/detail/fwd_macros.hpp +227 -32
  339. data/src/cxx_supportlib/vendor-modified/boost/move/detail/iterator_traits.hpp +4 -0
  340. data/src/cxx_supportlib/vendor-modified/boost/move/detail/meta_utils.hpp +30 -9
  341. data/src/cxx_supportlib/vendor-modified/boost/move/detail/meta_utils_core.hpp +12 -0
  342. data/src/cxx_supportlib/vendor-modified/boost/move/detail/move_helpers.hpp +84 -80
  343. data/src/cxx_supportlib/vendor-modified/boost/move/detail/placement_new.hpp +30 -0
  344. data/src/cxx_supportlib/vendor-modified/boost/move/detail/reverse_iterator.hpp +171 -0
  345. data/src/cxx_supportlib/vendor-modified/boost/move/detail/type_traits.hpp +14 -20
  346. data/src/cxx_supportlib/vendor-modified/boost/move/detail/unique_ptr_meta_utils.hpp +1 -1
  347. data/src/cxx_supportlib/vendor-modified/boost/move/detail/workaround.hpp +14 -0
  348. data/src/cxx_supportlib/vendor-modified/boost/move/iterator.hpp +32 -33
  349. data/src/cxx_supportlib/vendor-modified/boost/move/make_unique.hpp +2 -1
  350. data/src/cxx_supportlib/vendor-modified/boost/move/unique_ptr.hpp +49 -49
  351. data/src/cxx_supportlib/vendor-modified/boost/move/utility.hpp +8 -7
  352. data/src/cxx_supportlib/vendor-modified/boost/move/utility_core.hpp +17 -16
  353. data/src/cxx_supportlib/vendor-modified/boost/mpl/print.hpp +3 -0
  354. data/src/cxx_supportlib/vendor-modified/boost/none.hpp +1 -1
  355. data/src/cxx_supportlib/vendor-modified/boost/none_t.hpp +2 -3
  356. data/src/cxx_supportlib/vendor-modified/boost/operators.hpp +197 -255
  357. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/old_optional_implementation.hpp +1059 -0
  358. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_aligned_storage.hpp +75 -0
  359. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_config.hpp +116 -0
  360. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_factory_support.hpp +36 -0
  361. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_reference_spec.hpp +253 -0
  362. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_relops.hpp +196 -0
  363. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_swap.hpp +117 -0
  364. data/src/cxx_supportlib/vendor-modified/boost/optional/optional.hpp +372 -554
  365. data/src/cxx_supportlib/vendor-modified/boost/optional/optional_fwd.hpp +12 -1
  366. data/src/cxx_supportlib/vendor-modified/boost/pool/detail/mutex.hpp +15 -7
  367. data/src/cxx_supportlib/vendor-modified/boost/pool/pool_alloc.hpp +24 -0
  368. data/src/cxx_supportlib/vendor-modified/boost/predef/compiler/intel.h +9 -2
  369. data/src/cxx_supportlib/vendor-modified/boost/predef/compiler/visualc.h +15 -1
  370. data/src/cxx_supportlib/vendor-modified/boost/predef/hardware/simd.h +16 -4
  371. data/src/cxx_supportlib/vendor-modified/boost/predef/hardware/simd/x86.h +3 -3
  372. data/src/cxx_supportlib/vendor-modified/boost/predef/hardware/simd/x86_amd.h +4 -4
  373. data/src/cxx_supportlib/vendor-modified/boost/predef/hardware/simd/x86_amd/versions.h +4 -4
  374. data/src/cxx_supportlib/vendor-modified/boost/predef/os/cygwin.h +1 -1
  375. data/src/cxx_supportlib/vendor-modified/boost/predef/version.h +2 -2
  376. data/src/cxx_supportlib/vendor-modified/boost/predef/version_number.h +20 -1
  377. data/src/cxx_supportlib/vendor-modified/boost/preprocessor/cat.hpp +1 -1
  378. data/src/cxx_supportlib/vendor-modified/boost/preprocessor/config/config.hpp +6 -6
  379. data/src/cxx_supportlib/vendor-modified/boost/preprocessor/seq/detail/binary_transform.hpp +5 -6
  380. data/src/cxx_supportlib/vendor-modified/boost/preprocessor/seq/detail/to_list_msvc.hpp +55 -0
  381. data/src/cxx_supportlib/vendor-modified/boost/preprocessor/seq/to_list.hpp +12 -0
  382. data/src/cxx_supportlib/vendor-modified/boost/range/const_iterator.hpp +4 -4
  383. data/src/cxx_supportlib/vendor-modified/boost/range/size_type.hpp +0 -5
  384. data/src/cxx_supportlib/vendor-modified/boost/regex/concepts.hpp +16 -16
  385. data/src/cxx_supportlib/vendor-modified/boost/regex/config.hpp +4 -4
  386. data/src/cxx_supportlib/vendor-modified/boost/regex/pending/unicode_iterator.hpp +3 -0
  387. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/basic_regex_creator.hpp +102 -87
  388. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/basic_regex_parser.hpp +45 -21
  389. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/cpp_regex_traits.hpp +4 -4
  390. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/fileiter.hpp +2 -2
  391. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/instances.hpp +1 -1
  392. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/match_flags.hpp +14 -2
  393. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/mem_block_cache.hpp +46 -0
  394. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/perl_matcher.hpp +5 -2
  395. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/perl_matcher_common.hpp +5 -14
  396. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/perl_matcher_non_recursive.hpp +116 -13
  397. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/perl_matcher_recursive.hpp +34 -0
  398. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_format.hpp +2 -2
  399. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_traits.hpp +1 -1
  400. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_traits_defaults.hpp +3 -3
  401. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_workaround.hpp +1 -0
  402. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/w32_regex_traits.hpp +2 -2
  403. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/allocate_shared_array.hpp +1004 -159
  404. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/bad_weak_ptr.hpp +9 -0
  405. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/atomic_count.hpp +3 -0
  406. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/shared_count.hpp +4 -58
  407. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base.hpp +5 -2
  408. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_clang.hpp +9 -0
  409. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_impl.hpp +0 -8
  410. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_has_sync.hpp +3 -3
  411. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_noexcept.hpp +30 -0
  412. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/spinlock.hpp +3 -0
  413. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/enable_shared_from_this.hpp +5 -4
  414. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/intrusive_ptr.hpp +28 -3
  415. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/intrusive_ref_counter.hpp +187 -0
  416. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/make_shared_array.hpp +52 -144
  417. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/make_shared_object.hpp +120 -450
  418. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/scoped_array.hpp +2 -1
  419. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/scoped_ptr.hpp +2 -1
  420. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/shared_array.hpp +7 -6
  421. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/shared_ptr.hpp +70 -8
  422. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/weak_ptr.hpp +6 -5
  423. data/src/cxx_supportlib/vendor-modified/boost/system/error_code.hpp +9 -8
  424. data/src/cxx_supportlib/vendor-modified/boost/system/system_error.hpp +3 -3
  425. data/src/cxx_supportlib/vendor-modified/boost/thread/barrier.hpp +5 -4
  426. data/src/cxx_supportlib/vendor-modified/boost/thread/completion_latch.hpp +0 -1
  427. data/src/cxx_supportlib/vendor-modified/boost/thread/concurrent_queues/queue_views.hpp +0 -11
  428. data/src/cxx_supportlib/vendor-modified/boost/thread/concurrent_queues/sync_timed_queue.hpp +6 -4
  429. data/src/cxx_supportlib/vendor-modified/boost/thread/detail/config.hpp +11 -2
  430. data/src/cxx_supportlib/vendor-modified/boost/thread/detail/thread.hpp +11 -4
  431. data/src/cxx_supportlib/vendor-modified/boost/thread/exceptions.hpp +8 -8
  432. data/src/cxx_supportlib/vendor-modified/boost/thread/executors/executor.hpp +1 -1
  433. data/src/cxx_supportlib/vendor-modified/boost/thread/executors/generic_executor_ref.hpp +5 -5
  434. data/src/cxx_supportlib/vendor-modified/boost/thread/executors/loop_executor.hpp +22 -18
  435. data/src/cxx_supportlib/vendor-modified/boost/thread/future.hpp +163 -55
  436. data/src/cxx_supportlib/vendor-modified/boost/thread/futures/launch.hpp +1 -0
  437. data/src/cxx_supportlib/vendor-modified/boost/thread/futures/wait_for_all.hpp +1 -1
  438. data/src/cxx_supportlib/vendor-modified/boost/thread/lock_types.hpp +9 -9
  439. data/src/cxx_supportlib/vendor-modified/boost/thread/locks.hpp +1 -0
  440. data/src/cxx_supportlib/vendor-modified/boost/thread/pthread/condition_variable.hpp +6 -7
  441. data/src/cxx_supportlib/vendor-modified/boost/thread/pthread/condition_variable_fwd.hpp +17 -2
  442. data/src/cxx_supportlib/vendor-modified/boost/thread/pthread/shared_mutex.hpp +2 -2
  443. data/src/cxx_supportlib/vendor-modified/boost/thread/pthread/thread_data.hpp +5 -5
  444. data/src/cxx_supportlib/vendor-modified/boost/thread/pthread/timespec.hpp +29 -0
  445. data/src/cxx_supportlib/vendor-modified/boost/thread/scoped_thread.hpp +23 -18
  446. data/src/cxx_supportlib/vendor-modified/boost/thread/synchronized_value.hpp +6 -6
  447. data/src/cxx_supportlib/vendor-modified/boost/thread/thread_functors.hpp +19 -4
  448. data/src/cxx_supportlib/vendor-modified/boost/thread/thread_guard.hpp +3 -3
  449. data/src/cxx_supportlib/vendor-modified/boost/thread/user_scheduler.hpp +1 -1
  450. data/src/cxx_supportlib/vendor-modified/boost/type_index.hpp +265 -0
  451. data/src/cxx_supportlib/vendor-modified/boost/type_index/stl_type_index.hpp +272 -0
  452. data/src/cxx_supportlib/vendor-modified/boost/type_index/type_index_facade.hpp +300 -0
  453. data/src/cxx_supportlib/vendor-modified/boost/type_traits/add_reference.hpp +3 -3
  454. data/src/cxx_supportlib/vendor-modified/boost/type_traits/aligned_storage.hpp +6 -6
  455. data/src/cxx_supportlib/vendor-modified/boost/type_traits/common_type.hpp +1 -0
  456. data/src/cxx_supportlib/vendor-modified/boost/type_traits/detail/common_arithmetic_type.hpp +9 -3
  457. data/src/cxx_supportlib/vendor-modified/boost/type_traits/detail/mp_defer.hpp +3 -3
  458. data/src/cxx_supportlib/vendor-modified/boost/type_traits/extent.hpp +1 -0
  459. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_nothrow_assign.hpp +2 -1
  460. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_nothrow_constructor.hpp +2 -1
  461. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_nothrow_destructor.hpp +1 -1
  462. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_trivial_assign.hpp +2 -1
  463. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_trivial_copy.hpp +1 -0
  464. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_trivial_destructor.hpp +1 -1
  465. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_trivial_move_assign.hpp +1 -0
  466. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_trivial_move_constructor.hpp +1 -0
  467. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_abstract.hpp +1 -0
  468. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_array.hpp +1 -1
  469. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_assignable.hpp +1 -0
  470. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_const.hpp +2 -1
  471. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_default_constructible.hpp +21 -1
  472. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_destructible.hpp +1 -0
  473. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_nothrow_move_assignable.hpp +1 -1
  474. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_nothrow_move_constructible.hpp +2 -1
  475. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_pod.hpp +1 -0
  476. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_rvalue_reference.hpp +1 -1
  477. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_virtual_base_of.hpp +1 -1
  478. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_volatile.hpp +2 -1
  479. data/src/cxx_supportlib/vendor-modified/boost/type_traits/make_void.hpp +52 -0
  480. data/src/cxx_supportlib/vendor-modified/boost/type_traits/rank.hpp +1 -0
  481. data/src/cxx_supportlib/vendor-modified/boost/type_traits/remove_all_extents.hpp +1 -1
  482. data/src/cxx_supportlib/vendor-modified/boost/type_traits/remove_const.hpp +1 -1
  483. data/src/cxx_supportlib/vendor-modified/boost/type_traits/remove_cv.hpp +1 -1
  484. data/src/cxx_supportlib/vendor-modified/boost/type_traits/remove_extent.hpp +1 -1
  485. data/src/cxx_supportlib/vendor-modified/boost/type_traits/remove_pointer.hpp +1 -1
  486. data/src/cxx_supportlib/vendor-modified/boost/type_traits/remove_volatile.hpp +1 -1
  487. data/src/cxx_supportlib/vendor-modified/boost/type_traits/type_with_alignment.hpp +1 -1
  488. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/fwd.hpp +40 -6
  489. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/implementation.hpp +4986 -0
  490. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/map.hpp +107 -0
  491. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/set.hpp +105 -0
  492. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_map.hpp +1814 -1255
  493. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_map_fwd.hpp +41 -45
  494. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_set.hpp +1498 -1161
  495. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_set_fwd.hpp +40 -44
  496. data/src/cxx_supportlib/vendor-modified/boost/utility.hpp +2 -2
  497. data/src/cxx_supportlib/vendor-modified/boost/utility/base_from_member.hpp +7 -6
  498. data/src/cxx_supportlib/vendor-modified/boost/utility/compare_pointees.hpp +10 -2
  499. data/src/cxx_supportlib/vendor-modified/boost/utility/string_ref.hpp +39 -22
  500. data/src/cxx_supportlib/vendor-modified/boost/utility/string_view.hpp +690 -0
  501. data/src/cxx_supportlib/vendor-modified/boost/utility/string_view_fwd.hpp +39 -0
  502. data/src/cxx_supportlib/vendor-modified/boost/version.hpp +2 -2
  503. data/src/helper-scripts/crash-watch.rb +3 -0
  504. data/src/ruby_supportlib/phusion_passenger.rb +1 -1
  505. data/src/ruby_supportlib/phusion_passenger/apache2/config_options.rb +1 -0
  506. data/src/ruby_supportlib/phusion_passenger/packaging.rb +2 -12
  507. metadata +77 -38
  508. data/dev/ci/inituidgid +0 -24
  509. data/dev/ci/run_jenkins.sh +0 -70
  510. data/dev/ci/run_travis.sh +0 -314
  511. data/doc/Design and Architecture.html +0 -2421
  512. data/doc/Design and Architecture.txt +0 -511
  513. data/doc/Security of user switching support.html +0 -1833
  514. data/doc/Users guide Apache.html +0 -3101
  515. data/doc/Users guide Apache.idmap.txt +0 -451
  516. data/doc/Users guide Apache.txt +0 -534
  517. data/doc/Users guide Nginx.html +0 -3026
  518. data/doc/Users guide Nginx.idmap.txt +0 -431
  519. data/doc/Users guide Nginx.txt +0 -451
  520. data/doc/Users guide Standalone.html +0 -2092
  521. data/doc/Users guide Standalone.idmap.txt +0 -137
  522. data/doc/Users guide Standalone.txt +0 -81
  523. data/doc/Users guide.html +0 -1606
  524. data/doc/Users guide.txt +0 -8
  525. data/src/cxx_supportlib/vendor-modified/boost/align/align.hpp +0 -20
  526. data/src/cxx_supportlib/vendor-modified/boost/align/detail/address.hpp +0 -29
  527. data/src/cxx_supportlib/vendor-modified/boost/align/detail/align.hpp +0 -40
  528. data/src/cxx_supportlib/vendor-modified/boost/align/detail/align_cxx11.hpp +0 -22
  529. data/src/cxx_supportlib/vendor-modified/boost/align/detail/is_alignment.hpp +0 -29
  530. data/src/cxx_supportlib/vendor-modified/boost/container/detail/hash_table.hpp +0 -383
  531. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/array_allocator.hpp +0 -318
  532. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/array_count_impl.hpp +0 -67
  533. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/array_traits.hpp +0 -60
  534. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/array_utility.hpp +0 -214
  535. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_if_array.hpp +0 -34
  536. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/allocate.hpp +0 -1128
  537. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/buckets.hpp +0 -928
  538. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/equivalent.hpp +0 -686
  539. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/extract_key.hpp +0 -188
  540. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/table.hpp +0 -873
  541. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/unique.hpp +0 -628
  542. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/util.hpp +0 -266
@@ -0,0 +1,34 @@
1
+ /*
2
+ * Phusion Passenger - https://www.phusionpassenger.com/
3
+ * Copyright (c) 2017 Phusion Holding B.V.
4
+ *
5
+ * "Passenger", "Phusion Passenger" and "Union Station" are registered
6
+ * trademarks of Phusion Holding B.V.
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+ #ifndef _PASSENGER_CONFIG_KIT_H_
27
+ #define _PASSENGER_CONFIG_KIT_H_
28
+
29
+ #include <ConfigKit/Schema.h>
30
+ #include <ConfigKit/Store.h>
31
+ #include <ConfigKit/Utils.h>
32
+ #include <ConfigKit/TableTranslator.h>
33
+
34
+ #endif /* _PASSENGER_CONFIG_KIT_H_ */
@@ -0,0 +1,895 @@
1
+ # About ConfigKit
2
+
3
+ ConfigKit is a configuration management system that lets you define configuration keys and store configuration values, and plays well with JSON.
4
+
5
+ **Table of contents:**
6
+
7
+ * Motivations
8
+ - Configuration flow from high-level to low-level with a minimum of repeated code
9
+ - Unifying configuration management
10
+ * Status inside the Passenger codebase
11
+ * Features and class overview
12
+ - ConfigKit::Schema
13
+ - ConfigKit::Store
14
+ - Translators
15
+ * Using the schema
16
+ - Defining the schema
17
+ - Defining default values
18
+ - Defining custom validators
19
+ - Inspecting the schema
20
+ * Using the store
21
+ - Putting data in the store
22
+ - Updating data
23
+ - Unregistered keys are ignored
24
+ - Deleting data
25
+ - Fetching data
26
+ - Default values
27
+ - Dumping all data
28
+ * Putting it all together: synchronous version
29
+ - SecurityChecker example: a configurable, low-level component
30
+ - DnsQuerier example: a low-level component with post-configuration application operations
31
+ - Downloader example: a high-level component that combines subcomponents
32
+ - The special problem of conflicting overlapping configuration names and translation
33
+ - Code example
34
+ * Putting it all together: asynchronous version
35
+
36
+ ## Motivations
37
+
38
+ ### Configuration flow from high-level to low-level with a minimum of repeated code
39
+
40
+ Passenger is architected as a tree of components. At the top of the tree there are high-level components that implement Passenger business logic, while at the bottom of the tree there are low-level, generic components that are reusable outside Passenger. Higher-level components can encapsulate lower-level components, but not the other way around.
41
+
42
+ Almost every component can be configured individually. This is fairly easy, but when you put all the components together in Passenger's tree-like architecture, you end up with the following challenge: how do higher-level components expose the configuration of their encapsulated subcomponents, and how do higher-level components allow configuring their encapsulated subcomponents, without repeating a lot of code? Suppose that you have a class A that encapsulates B:
43
+
44
+ ~~~c++
45
+ class B {
46
+ public:
47
+ int option1;
48
+ int option2;
49
+ int option3;
50
+ };
51
+
52
+ class A {
53
+ private:
54
+ B b;
55
+ int option4;
56
+
57
+ public:
58
+ void setOption1(int val) { b.option1 = val; }
59
+ void setOption2(int val) { b.option2 = val; }
60
+ void setOption3(int val) { b.option3 = val; }
61
+ void setOption4(int val) { b.option4 = val; }
62
+ };
63
+ ~~~
64
+
65
+ If B has a lot of configuration options, then writing all these setters (and we haven't even looked at getters yet) becomes tiresome quickly. Worse, if there is a component X that encapsulates A, that all the setters in A have to be repeated in X too. And every time you add an option to B, you have to modify A and X too.
66
+
67
+ How do you prevent having to manually write so much code for exposing and configuring all the options exposed by lower-level components? One possible answer consists of the following aspects:
68
+
69
+ - Configuration should be stored in some kind of key-value data structure, e.g. a Json::Value, instead of in individual class members for each option.
70
+ - There must exist the concept of a configuration schema, and this must be introspectable during runtime, so that higher-level components can manage subcomponents' configuration through automation.
71
+
72
+ ConfigKit implements these aspects, and also provides various other useful features in the area of configuration management. ConfigKit is built around the concept of introspection during *runtime*. This is not the only approach: static introspection and code generation is another valid approach (which is used by some components in Passenger), but this is outside ConfigKit's scope.
73
+
74
+ ### Unifying configuration management
75
+
76
+ Another challenge pertains having different ways to configure a component. Should components be configured using getters and setters for each option? Or should they have a single method that accepts a struct (or some kind of key-value map) that specifies multiple options? Should components be configurable at all after construction. It would be great if we have a unified answer for all components in Passenger.
77
+
78
+ ConfigKit provides this unified answer:
79
+
80
+ * Components should be configurable at any time after construction. Motivation: we want to allow configuration reloads without having to restart Passenger.
81
+ * Components should be configurable through a single method that accepts a JSON object. Motivations:
82
+
83
+ - Applying a configuration change is potentially expensive, so you want to batch multiple configuration changes into a single transaction.
84
+ - Configuration parameters often originate from an I/O channel. Using a struct to store all the different configuration options results in a lot of repeated code, like this:
85
+
86
+ config.foo1 = userInput["foo1"];
87
+ config.foo2 = userInput["foo2"];
88
+ config.foo3 = userInput["foo3"];
89
+
90
+ So we want some kind of key-value data structure. JSON is a pretty popular format nowadays, and is likely to be the format used in the I/O channel, so may as well optimize for JSON.
91
+
92
+ ConfigKit backs these answers with code that helps you implement these principles, as well as with documented design patterns that provide guidance.
93
+
94
+ ## Status inside the Passenger codebase
95
+
96
+ At the time of writing (25 Feb 2017), ConfigKit was just introduced, so these practices and patterns documented in this README aren't yet used everywhere throughout the Passenger codebase, but the long-term plan is to adopt these practices/patterns throughout the entire codebase.
97
+
98
+ ## Features and class overview
99
+
100
+ ### ConfigKit::Schema
101
+
102
+ Everything starts with `ConfigKit::Schema`. This is a class that lets you define a schema of supported configuration keys, their types and other properties like default values. Default values may either be static or dynamically calculated. `ConfigKit::Schema` also allows data validation against the schema.
103
+
104
+ ### ConfigKit::Store
105
+
106
+ There is also `ConfigKit::Store`. This is a class that stores configuration values in such a way that it respects a schema. The values supplied to and stored in `ConfigKit::Store` are JSON values (i.e. of the `Json::Value` type), although Store uses the schema to validate that you are actually putting the right JSON types in the Store.
107
+
108
+ `ConfigKit::Store` also keeps track of which values are explicitly supplied and which ones are not.
109
+
110
+ ### Translators
111
+
112
+ And finally there is a "translator" class: `ConfigKit::TableTranslator`. The role of translators are described in the section "The special problem of conflicting overlapping configuration names and translation".
113
+
114
+ ## Using the schema
115
+
116
+ ### Defining the schema
117
+
118
+ Start using ConfigKit by defining a schema. There are two ways to do this. The first one is to simply create ConfigKit::Schema object and adding definitions to it:
119
+
120
+ ~~~c++
121
+ ConfigKit::Schema schema;
122
+
123
+ // A required string key.
124
+ schema.add("foo", ConfigKit::STRING_TYPE, ConfigKit::REQUIRED);
125
+
126
+ // An optional integer key without default value.
127
+ schema.add("bar", ConfigKit::FLOAT_TYPE, ConfigKit::OPTIONAL);
128
+
129
+ // An optional integer key, with default value 123.
130
+ schema.add("baz", ConfigKit::INTEGER_TYPE, ConfigKit::OPTIONAL, 123);
131
+
132
+ // Call this when done, otherwise the object cannot be used yet.
133
+ schema.finalize();
134
+ ~~~
135
+
136
+ The second one, and the one we recommend, is to subclass ConfigKit::Schema and to add the definitions inside the subclass's constructor. It will become apparent in the section "Putting it all together: synchronous version" why this is the recommended approach.
137
+
138
+ ~~~c++
139
+ struct YourSchema: public ConfigKit::Schema {
140
+ YourSchema() {
141
+ using namespace ConfigKit;
142
+ add("foo", STRING_TYPE, REQUIRED);
143
+ add("bar", FLOAT_TYPE, OPTIONAL);
144
+ add("baz", INT_TYPE, OPTIONAL, 123);
145
+ finalize();
146
+ }
147
+ };
148
+
149
+ // Instantiate it:
150
+ YourSchema schema;
151
+ ~~~
152
+
153
+ Tip: see ConfigKit/Common.h for all supported types and flags.
154
+
155
+ ### Defining default values
156
+
157
+ The fourth parameter of `add()` is for specifying a static default value.
158
+
159
+ But ConfigKit also supports *dynamic* default values, by accepting instead of a static default value, a *function object* that returns a default value.
160
+
161
+ The main use case for dynamic default values is this: to return something based on another value in the configuration store. For example suppose that your schema defines a `connect_timeout` and a `recv_timeout` option. You want `recv_timeout` to default to two times whatever the effective value of `connect_timeout` is. You can define a default value getter function like this:
162
+
163
+ ~~~c++
164
+ Json::Value getRecvTimeoutDefaultValue(const ConfigKit::Store &store) {
165
+ return store->get("connect_timeout").getInt() * 2;
166
+ }
167
+
168
+ schema.addWithDynamicDefault("recv_timeout", INT_TYPE, OPTIONAL, getRecvTimeoutDefaultValue);
169
+ ~~~
170
+
171
+ ### Defining custom validators
172
+
173
+ ConfigKit::Store validates your data using the type definitions in ConfigKit::Schema. But sometimes you need custom validations of the data in a ConfigKit::Store. For example, "'bar' is required when 'foo' is specified". This sort of logic can be implemented with custom validators.
174
+
175
+ Custom validators are defined on a ConfigKit::Schema:
176
+
177
+ ~~~c++
178
+ static void myValidator(const ConfigKit::Store &config, vector<ConfigKit::Error> &errors) {
179
+ if (!config["foo"].isNull() && config["bar"].isNull()) {
180
+ errors.push_back(ConfigKit::Error("'{{bar}}' is required when '{{foo}}' is specified"));
181
+ }
182
+ }
183
+
184
+
185
+ ConfigKit::Schema schema;
186
+
187
+ schema.add("foo", STRING_TYPE, OPTIONAL);
188
+ schema.add("bar", STRING_TYPE, OPTIONAL);
189
+ schema.addValidator(myValidator);
190
+ schema.finalize();
191
+ ~~~
192
+
193
+ ### Inspecting the schema
194
+
195
+ You can inspect the schema using the `inspect()` method. It returns a Json::Value in the following format:
196
+
197
+ ~~~json
198
+ {
199
+ "foo": {
200
+ "type": "string",
201
+ "required": true,
202
+ "has_default_value": true
203
+ },
204
+ "bar": {
205
+ "type": "float"
206
+ },
207
+ "baz": {
208
+ "type": "integer"
209
+ }
210
+ }
211
+ ~~~
212
+
213
+ Description of the members:
214
+
215
+ - `type`: the schema definition's type. Could be one of "string", "integer", "unsigned integer", "float" or "boolean".
216
+ - `required`: whether this key is required.
217
+ - `has_default_value`: whether a default value is defined.
218
+
219
+ ## Using the store
220
+
221
+ Once you have defined a schema you can start using ConfigKit::Store. Create it by referencing the schema that it should use. Note that it internally stores a pointer to the schema, so make sure the schema outlives the store.
222
+
223
+ ~~~c++
224
+ ConfigKit::Store store(schema);
225
+ ~~~
226
+
227
+ ### Putting data in the store
228
+
229
+ You can populate the store using the `update()` method. The method also performs validation against the schema. The update only succeeds if validation passes.
230
+
231
+ ~~~c++
232
+ vector<ConfigKit::Error> errors;
233
+ Json::Value updates1;
234
+
235
+ // Validation fails: 'foo' is missing
236
+ store.update(updates1, errors);
237
+ // => return value: false
238
+ // errors: 1 item ("'foo' is required")
239
+
240
+ store.get("foo").isNull();
241
+ // => true, because the update failed
242
+
243
+ errors.clear();
244
+ updates1["foo"] = "strval";
245
+ store.update(updates1, errors);
246
+ // => return value: true
247
+ // errors: empty
248
+
249
+ store.get("foo").asString();
250
+ // => "strval", because the update succeeded
251
+ ~~~
252
+
253
+ #### Updating data
254
+
255
+ Any further calls to `update()` only update the keys that you actually pass to the method, not the keys that you don't pass:
256
+
257
+ ~~~c++
258
+ // Assuming we are using the store from 'Putting data in the store'.
259
+ Json::Value updates2;
260
+
261
+ updates2["bar"] = 123.45;
262
+ store.update(updates2, errors); // => true
263
+ store.get("foo").asString(); // => still "strval"
264
+ store.get("bar").asDouble(); // => 123.45
265
+ ~~~
266
+
267
+ ### Unregistered keys are ignored
268
+
269
+ `update()` ignores keys that aren't registered in the schema:
270
+
271
+ ~~~c++
272
+ // Assuming we are using the store that went through
273
+ // 'Putting data in the store' and 'Updating data'.
274
+ Json::Value updates3;
275
+
276
+ updates3["unknown"] = true;
277
+ store.update(updates3, errors); // => true
278
+ store.get("foo").asString(); // => still "strval"
279
+ store.get("bar").asDouble(); // => still 123.45
280
+ store.get("unknown").isNull(); // => true
281
+ ~~~
282
+
283
+ ### Deleting data
284
+
285
+ You can delete data by calling `update()` with null values on the keys you want to delete.
286
+
287
+ ~~~c++
288
+ // Assuming we are using the store that went through
289
+ // 'Putting data in the store' and 'Updating data'.
290
+ Json::Value deletionSpec;
291
+
292
+ deletionSpec["bar"] = Json::nullValue;
293
+ store.update(deletionSpec, errors);
294
+ // => return value: true
295
+ // errors: empty
296
+
297
+ store.get("bar").isNull(); // => true
298
+ ~~~
299
+
300
+ ### Fetching data
301
+
302
+ Use the `get()` method (of which the `[]` operator is an alias) to fetch data from the store. They both return a Json::Value.
303
+
304
+ ~~~c++
305
+ // Assuming we are using the store that went through
306
+ // 'Putting data in the store' and 'Updating data'.
307
+ store.get("foo").asString(); // => "strval"
308
+ store["foo"].asString(); // => same
309
+ ~~~
310
+
311
+ ### Default values
312
+
313
+ If the key is not defined then `get()` either return the default value as defined in the schema, or (if no default value is defined) a null Json::Value.
314
+
315
+ ~~~c++
316
+ // Assuming we are using the store that went through
317
+ // 'Putting data in the store' and 'Updating data'.
318
+ store.get("baz").asInt(); // => 123
319
+ store.get("unknown").isNull(); // => true
320
+ ~~~
321
+
322
+ ### Inspecting all data
323
+
324
+ You can fetch an overview of all data in the store using `inspect()`.
325
+ This will return a Json::Value in the following format:
326
+
327
+ ~~~javascript
328
+ // Assuming we are using the store that went through
329
+ // 'Putting data in the store' and 'Updating data'.
330
+
331
+ {
332
+ "foo": {
333
+ "user_value": "strval",
334
+ "effective_value": "strval",
335
+ // ...members from ConfigKit::Schema::inspect() go here...
336
+ },
337
+ "bar": {
338
+ "user_value": 123.45,
339
+ "effective_value": 123.45,
340
+ // ...members from ConfigKit::Schema::inspect() go here...
341
+ },
342
+ "baz": {
343
+ "user_value": null,
344
+ "default_value": 123,
345
+ "effective_value": 123,
346
+ // ...members from ConfigKit::Schema::inspect() go here...
347
+ }
348
+ }
349
+ ~~~
350
+
351
+ Description of the members:
352
+
353
+ - `user_value`: the value as explicitly set in the store. If null then it means that the value isn't set.
354
+ - `default_value`: the default value as defined in the schema. May be absent.
355
+ - `effective_value`: the effective value, i.e. the value that `get()` will return.
356
+
357
+ If you want to fetch the effective values only, then use `inspectEffectiveValues()`:
358
+
359
+ ~~~javascript
360
+ // Assuming we are using the store that went through
361
+ // 'Putting data in the store' and 'Updating data'.
362
+
363
+ {
364
+ "foo": "strval",
365
+ "bar": 123.45,
366
+ "baz": 123
367
+ }
368
+ ~~~
369
+
370
+ ## Putting it all together: synchronous version
371
+
372
+ Now that you've learned how to use ConfigKit by itself, how does fit in the bigger picture? This section describes good practices and design patterns can that can be used throughout the overall Passenger C++ codebase. At the time of writing (25 Feb 2017), ConfigKit was just introduced, so these practices and patterns aren't yet used everywhere, but the long-term plan is to adopt these practices/patterns throughout the entire codebase.
373
+
374
+ Let's demonstrate the good practices and design patterns through a number of annotated example classes:
375
+
376
+ - `SecurityChecker` checks whether the given URL is secure to connect to, by checking a database of vulnerable sites. This example demonstrates basic usage of ConfigKit in a low-level component.
377
+ - `DnsQuerier` looks up DNS information for a given URL, from multiple DNS servers. Because the algorithm that DnsQuerier uses is a performance-critical hot path (or so we claim for the sake of the example), it should cache certain configuration values in a variables instead of looking up the config store over and over, because the latter involve unnecessary hash table lookups. This example demonstrates caching of configuration values. More generally, it demonstrates how to perform arbitrary operations necessary for applying a configuration change.
378
+ - `Downloader` is a high-level class for downloading a specific URL. Under the hood it utilizes `SecurityChecker` and `DnsQuerier`. This example demonstrates how to combine its own configuration with the configuration of multiple lower-level classes.
379
+
380
+ ### SecurityChecker example: a configurable, low-level component
381
+
382
+ SecurityChecker checks whether the given URL is secure to connect to, by checking a database of vulnerable sites. This example demonstrates basic usage of ConfigKit in a low-level component.
383
+
384
+ A configurable component should have the following methods.
385
+
386
+ - `previewConfigUpdate()`
387
+ - `configure()`
388
+ - `inspectConfig()`
389
+
390
+ These methods are further explained in the code example
391
+
392
+ ~~~c++
393
+ class SecurityChecker {
394
+ private:
395
+ // This is the internal configuration store. This is also the
396
+ // recommended naming scheme: `config`.
397
+ ConfigKit::Store config;
398
+
399
+ public:
400
+ // This defines the SecurityChecker's configuration schema.
401
+ // This is also the recommended naming scheme:
402
+ // <YourComponentName>::Schema.
403
+ struct Schema: public ConfigKit::Schema {
404
+ Schema() {
405
+ using namespace ConfigKit;
406
+ add("db_path", STRING_TYPE, REQUIRED);
407
+ add("url", STRING_TYPE, REQUIRED);
408
+ add("timeout", INT_TYPE, OPTIONAL, 60);
409
+ finalize();
410
+ }
411
+ };
412
+
413
+ // The constructor takes a Schema so that we can initialize the
414
+ // configuration store. It should also immediately accept some
415
+ // initial configuration.
416
+ //
417
+ // You might wonder, how about instead of taking a Schema as a parameter,
418
+ // we define the Schema as a global variable? After all, a
419
+ // ConfigKit::Schema is immutable after finalization, and different
420
+ // instances of <YourComponentName>::Schema contain the same content.
421
+ //
422
+ // Defining as a global variable is *also* a valid approach, but requires
423
+ // you to declare it inside a .cpp file and adding that file to the linker
424
+ // invocation. It's up to you really. I've found taking a schema as a
425
+ // parameter to be the easiest.
426
+ SecurityChecker(const Schema &schema, const Json::Value &initialConfig)
427
+ : config(schema)
428
+ {
429
+ vector<ConfigKit::Error> errors;
430
+
431
+ if (!config.update(initialConfig, errors)) {
432
+ throw ArgumentException("Invalid initial configuration: "
433
+ + toString(errors));
434
+ }
435
+ }
436
+
437
+ // This method allows checking whether the given configuration updates
438
+ // would result in any validation errors, without actually changing the
439
+ // configuration.
440
+ //
441
+ // Every configurable component should define such a method, because
442
+ // higher-level components need this method in order to make configuration
443
+ // updates across multiple low-level components transactional. You
444
+ // will learn more about this in the Downloader example.
445
+ Json::Value previewConfigUpdate(const Json::Value &updates,
446
+ vector<ConfigKit::Error> &errors)
447
+ {
448
+ // In low-level components, it's as simple as forwarding
449
+ // the call to the configuration store.
450
+ return config.previewUpdate(updates, errors);
451
+ }
452
+
453
+ // This method actually configures the component.
454
+ bool configure(const Json::Value &updates, vector<ConfigKit::Error> &errors) {
455
+ // In low-level components, it's as simple as forwarding
456
+ // the call to the configuration store.
457
+ return config.update(updates, errors);
458
+ }
459
+
460
+ // This method inspects the component's configuration.
461
+ Json::Value inspectConfig() const {
462
+ // In low-level components, it's as simple as forwarding
463
+ // the call to the configuration store.
464
+ return config.inspect();
465
+ }
466
+
467
+ bool check() const {
468
+ // Fictional code here for performing the lookup.
469
+ openDatabase(config["db_path"].asString());
470
+ Entry entry = lookupEntry(config["url"].asString(),
471
+ config["timeout"].asInt());
472
+ closeDatabase();
473
+ return !entry.isNull();
474
+ }
475
+ };
476
+ ~~~
477
+
478
+ Use SecurityChecker like this:
479
+
480
+ ~~~c++
481
+ SecurityChecker::Schema schema;
482
+ Json::Value config;
483
+ config["db_path"] = "/db";
484
+ config["url"] = "http://www.google.com";
485
+
486
+ // Initiate SecurityChecker with initial configuration
487
+ SecurityChecker securityChecker(schema, config);
488
+ securityChecker.check();
489
+
490
+ // Change configuration
491
+ vector<ConfigKit::Error> errors;
492
+ config["url"] = "http://www.example.com";
493
+ if (!securityChecker.configure(config, errors)) {
494
+ cout << "Configuration change failed: " << toString(errors) << endl;
495
+ }
496
+
497
+ // Inspect configuration
498
+ cout << "Final configuration:" << endl;
499
+ cout << securityChecker.inspectConfig().toStyledString() << endl;
500
+ ~~~
501
+
502
+ ### DnsQuerier example: a low-level component with post-configuration application operations
503
+
504
+ DnsQuerier looks up DNS information for a given URL, from multiple DNS servers. Because the algorithm that DnsQuerier uses is a performance-critical hot path (or so we claim for the sake of the example), it should cache certain configuration values in a variables instead of looking up the config store over and over, because the latter involve unnecessary hash table lookups. This example demonstrates caching of configuration values. More generally, it demonstrates how to perform arbitrary operations necessary for applying a configuration change.
505
+
506
+ ~~~c++
507
+ class DnsQuerier {
508
+ private:
509
+ // The configuration store, same as with SecurityChecker.
510
+ ConfigKit::Store config;
511
+
512
+ // Caches the "url" configuration value.
513
+ string url;
514
+
515
+ // Populates the cache using values from the configuration store.
516
+ void updateConfigCache() {
517
+ url = config["url"].asString();
518
+ }
519
+
520
+ public:
521
+ // The schema, same as with SecurityChecker.
522
+ struct Schema: public ConfigKit::Schema {
523
+ Schema() {
524
+ using namespace ConfigKit;
525
+ add("url", STRING_TYPE, REQUIRED);
526
+ add("timeout", INT_TYPE, OPTIONAL, 60);
527
+ finalize();
528
+ }
529
+ };
530
+
531
+ // The constructor, same as with SecurityChecker with only one change:
532
+ // it populates the configuration cache before returning.
533
+ DnsQuerier(const Schema &schema, const Json::Value &initialConfig)
534
+ : config(schema)
535
+ {
536
+ vector<ConfigKit::Error> errors;
537
+
538
+ if (!config.update(initialConfig, errors)) {
539
+ throw ArgumentException("Invalid initial configuration: "
540
+ + toString(errors));
541
+ }
542
+ updateConfigCache();
543
+ }
544
+
545
+ // Same as with SecurityChecker.
546
+ Json::Value previewConfigUpdate(const Json::Value &updates,
547
+ vector<ConfigKit::Error> &errors)
548
+ {
549
+ return config.previewUpdate(updates, errors);
550
+ }
551
+
552
+ // Configures the DnsQuerier. Same as with SecurityChecker with only one
553
+ // modification: it populates the configuration cache if updating succeeds.
554
+ bool configure(const Json::Value &updates, vector<ConfigKit::Error> &errors) {
555
+ if (config.update(updates, errors)) {
556
+ updateConfigCache();
557
+ // In addition to updating the config cache, this is
558
+ // the right place for performing any other operations
559
+ // necessary for applying a configuration change.
560
+ return true;
561
+ } else {
562
+ return false;
563
+ }
564
+ }
565
+
566
+ // Same as with SecurityChecker.
567
+ Json::Value inspectConfig() const {
568
+ return config.inspect();
569
+ }
570
+
571
+ string query() {
572
+ // Fictional code here for performing the lookup.
573
+ setSocketTimeout(config["timeout"].asInt());
574
+ for (unsigned i = 0; i < 1000; i++) {
575
+ // Fictional hot code path that requires the url config option.
576
+ queryNextDnsServer(url);
577
+ receiveResponse();
578
+ }
579
+ return result;
580
+ }
581
+ };
582
+ ~~~
583
+
584
+ ### Downloader example: a high-level component that combines subcomponents
585
+
586
+ `Downloader` is a high-level class for downloading a specific URL. Under the hood it utilizes `SecurityChecker` and `DnsQuerier`. This example demonstrates how to combine its own configuration with the configuration of multiple lower-level classes.
587
+
588
+ Downloader completely *encapsulates* its subcomponents. Users that use Downloader don't have to know that the subcomponents exist. Downloader also completely encapsulates subcomponents' configuration: subcomponents can only be configured (and their configuration only inspected) through Downloader.
589
+
590
+ Because of this, downloader's configuration schema includes not only options directly pertaining Downloader itself, but also includes options pertaining the subcomponents it uses.
591
+
592
+ Similarly, the Downloader's internal configuration store stores not only the configuration values directly pertaining to Downloader itself, but also (a copy of) the configuration values pertaining to the subcomponents.
593
+
594
+ Whenever Downloader is configured, it configures subcomponents too. But whenever Downloader's configuration is inspected, it only returns the data from its own configuration store. Because only the Downloader is allowed to configure its subcomponents, we know that the Downloader's internal configuration store contains the most up-to-date values.
595
+
596
+ #### The special problem of conflicting overlapping configuration names and translation
597
+
598
+ There is one special problem that deserves attention: a high-level component may not necessarily want to expose their subcomponents' configuration options using the same names. For example, both `SecurityChecker` and `DnsQuerier` expose a `timeout` option, but they are *different* timeouts, and are even distinct from the Downloader's own download timeout. To solve this special problem of **conflicting overlapping configuration names**, we utilize a **translation system**. We define how the Downloader's configuration keys are to be mapped a specific subcomponent's configuration keys. We obviously can't define the entire mapping, because that would return us to the original problem of having to manually write so much repeated code. There are several ways to deal with this, such as:
599
+
600
+ - Assuming that most options don't have to be renamed, and only define exceptions to this rule. This is the approach that is demonstrated in this example. The `ConfigKit::TableTranslator` class implements this translation strategy.
601
+ - Prefixing the subcomponents' options. This approach is left as an exercise to the reader.
602
+
603
+ #### Code example
604
+
605
+ ~~~c++
606
+ class Downloader {
607
+ private:
608
+ // The subcomponents used by Downloader.
609
+ SecurityChecker securityChecker;
610
+ DnsQuerier dnsQuerier;
611
+
612
+ // The internal configuration store. As explained, this also contains (a
613
+ // copy of) the configuration options pertaining SecurityChecker and the
614
+ // DnsQuerier.
615
+ ConfigKit::Store config;
616
+
617
+ public:
618
+ // Defines the Downloader's configuration schema. As explained, this schema
619
+ // includes not only options directly pertaining Downloader itself, but also
620
+ // options the subcomponents.
621
+ struct Schema: public ConfigKit::Schema {
622
+ // For each subcomponent that Downloader uses, we define a struct member
623
+ // that contains that subcomponent's schema, as well as a translation table
624
+ // for mapping Downloader's config keys to the subcomponent's config keys.
625
+ struct {
626
+ SecurityChecker::Schema schema;
627
+ ConfigKit::TableTranslator translator;
628
+ } securityChecker;
629
+ struct {
630
+ DnsQuerier::Schema schema;
631
+ ConfigKit::TableTranslator translator;
632
+ } dnsQuerier;
633
+
634
+ Schema() {
635
+ using namespace ConfigKit;
636
+
637
+ // Here we define how to map Downloader configuration keys to
638
+ // SecurityChecker configuration keys. We add the SecurityChecker's
639
+ // configuration schema to our own, taking into account the
640
+ // translations.
641
+ //
642
+ // Note that everything not defined in these translation mapping
643
+ // definitions are simply not translated (i.e. left as-is). So
644
+ // the Downloader's "url" option maps directly to SecurityChecker's
645
+ // "url" option.
646
+ securityChecker.translator.add("security_checker_db_path", "db_path");
647
+ securityChecker.translator.add("security_checker_timeout", "timeout");
648
+ securityChecker.translator.finalize();
649
+ addSubSchema(securityChecker.schema, securityChecker.translator);
650
+
651
+ // Ditto for DnsQuerier.
652
+ dnsQuerier.translator.add("dns_timeout", "timeout");
653
+ dnsQuerier.translator.finalize();
654
+ addSubSchema(dnsQuerier.schema, dnsQuerier.translator);
655
+
656
+ // Here we define Downloader's own configuration keys.
657
+ add("download_timeout", INT_TYPE, OPTIONAL, 60);
658
+ finalize();
659
+ }
660
+ };
661
+
662
+ // The constructor creates subcomponents, passing to them translated
663
+ // versions of the initial configuration passed.
664
+ Downloader(const Schema &schema, const Json::Value &initialConfig)
665
+ : securityChecker(schema.securityChecker.schema,
666
+ schema.securityChecker.translator.translate(initialConfig)),
667
+ dnsQuerier(schema.dnsQuerier.schema,
668
+ schema.dnsQuerier.translator.translate(initialConfig)),
669
+ config(schema)
670
+ {
671
+ vector<ConfigKit::Error> errors;
672
+
673
+ if (!config.update(initialConfig, errors)) {
674
+ throw ArgumentException("Invalid initial configuration: "
675
+ + toString(errors));
676
+ }
677
+ }
678
+
679
+ void download() {
680
+ // Fictional code here for performing the download
681
+
682
+ cout << "Downloading " << config["url"].asString() << endl;
683
+ securityChecker.check();
684
+ dnsQuerier.query();
685
+
686
+ openSocket(config["url"].asString());
687
+ sendRequest();
688
+ receiveData(config["download_timeout"].asInt());
689
+ closeSocket();
690
+ }
691
+
692
+ // In addition to calling previewUpdate() on the internal configuration
693
+ // store, we also perform similar operations on our subcomponents.
694
+ // We use the `ConfigKit::previewConfigUpdateSubComponent()` utility
695
+ // function to achieve this, passing to it a corresponding translator.
696
+ // This function assumes that the subcomponent implements the
697
+ // `previewConfigUpdate()` method.
698
+ Json::Value previewConfigUpdate(const Json::Value &updates,
699
+ vector<ConfigKit::Error> &errors)
700
+ {
701
+ using namespace ConfigKit;
702
+ const Schema &schema = static_cast<const Schema &>(config.getSchema());
703
+
704
+ previewConfigUpdateSubComponent(securityChecker, updates,
705
+ schema.securityChecker.translator, errors);
706
+ previewConfigUpdateSubComponent(dnsQuerier, updates,
707
+ schema.dnsQuerier.translator, errors);
708
+ return config.previewUpdate(updates, errors);
709
+ }
710
+
711
+ // In addition to updating the internal configuration store, we also
712
+ // configure the subcomponents. But we only do this after having verified
713
+ // that *all* subcomponents (as well as Downloader itself) successfully
714
+ // validates of the new configuration data. This is how we make
715
+ // `configure()` *transactional*: if we don't do this then we can end up in
716
+ // a situation where one subcomponent is configured, but another is not.
717
+ //
718
+ // We use the `ConfigKit::configureSubComponent()` utility function to
719
+ // achieve this, passing it a corresponding translator. This function
720
+ // assumes that the subcomponent implements the `configure()` method.
721
+ bool configure(const Json::Value &updates, vector<ConfigKit::Error> &errors) {
722
+ using namespace ConfigKit;
723
+ const Schema &schema = static_cast<const Schema &>(config.getSchema());
724
+
725
+ previewConfigUpdate(updates, errors);
726
+
727
+ if (errors.empty()) {
728
+ configureSubComponent(securityChecker, updates,
729
+ schema.securityChecker.translator, errors);
730
+ configureSubComponent(dnsQuerier, updates,
731
+ schema.dnsQuerier.translator, errors);
732
+ config.update(updates, errors);
733
+ }
734
+
735
+ if (errors.empty()) {
736
+ // In addition to updating the subcomponents and the
737
+ // internal configuration store, this is the right
738
+ // place for performing any other operations
739
+ // necessary for applying a configuration change.
740
+ }
741
+
742
+ return errors.empty();
743
+ }
744
+
745
+ // As explained, simply returning our internal configuration store
746
+ // is enough to expose all the subcomponents' configuration values too.
747
+ Json::Value inspectConfig() const {
748
+ return config.inspect();
749
+ }
750
+ };
751
+ ~~~
752
+
753
+ ### Main function example
754
+
755
+ To close this section, here is an example of how the main function would look like to utilize the aforementioned components:
756
+
757
+ ~~~c++
758
+ int
759
+ main() {
760
+ // Set configuration
761
+ Json::Value config;
762
+ config["url"] = "http://www.google.com";
763
+ config["security_checker_db_path"] = "/db";
764
+ config["dns_timeout"] = 30;
765
+ config["download_timeout"] = 20;
766
+
767
+ // Instantiate and print schema
768
+ Downloader::Schema schema;
769
+ cout << "Configuration schema:" << endl;
770
+ cout << schema.inspect().toStyledString() << endl;
771
+
772
+ // Instantiate a Downloader and perform a download
773
+ Downloader downloader(schema, config);
774
+ downloader.download();
775
+
776
+ // Change configuration, perform another download
777
+ cout << "Changing configuration" << endl;
778
+ vector<ConfigKit::Error> errors;
779
+ config["url"] = "http://www.slashdot.org";
780
+ if (!downloader.configure(config, errors)) {
781
+ cout << "Configure failed!" << endl;
782
+ }
783
+ downloader.download();
784
+
785
+ // Print final configuration
786
+ cout << "Final configuration:" << endl;
787
+ cout << downloader.inspectConfig().toStyledString() << endl;
788
+
789
+ return 0;
790
+ }
791
+ ~~~
792
+
793
+ ## Putting it all together: asynchronous version
794
+
795
+ The above examples demonstrate how things would work with synchronous components. What about components that deal with asynchronous I/O? They usually run inside an event loop, and all access to their internal data should be performed from the event loop.
796
+
797
+ Our recommendation is that you implement synchronous as well as asynchronous versions of the `previewConfigUpdate()`, `configure()`, and `inspectConfig()` methods. The synchronous versions must be called from the event loop. The asynchronous versions...
798
+
799
+ - accept a callback which is to be called with the result.
800
+ - schedule an operation via the event loop the perform the equivalent synchronous operation and call the callback.
801
+ - are to be thread-safe.
802
+
803
+ The following example demonstrates how SecurityChecker would look like if introduces asynchronous methods as described above. Other classes, like Downloader, should also be modified in a similar manner.
804
+
805
+ ~~~c++
806
+ class SecurityChecker {
807
+ private:
808
+ EventLoop &eventLoop;
809
+
810
+ // No change from synchronous version.
811
+ ConfigKit::Store config;
812
+
813
+ public:
814
+ // No change from synchronous version.
815
+ struct Schema: public ConfigKit::Schema {
816
+ Schema() {
817
+ using namespace ConfigKit;
818
+ add("db_path", STRING_TYPE, REQUIRED);
819
+ add("url", STRING_TYPE, REQUIRED);
820
+ add("timeout", INTEGER_TYPE, OPTIONAL, 60);
821
+ finalize();
822
+ }
823
+ };
824
+
825
+ // Only change from synchronous version is that we now accept
826
+ // an event loop object.
827
+ SecurityChecker(const Schema &schema, const EventLoopType &_eventLoop,
828
+ const Json::Value &initialConfig)
829
+ : eventLoop(eventLoop),
830
+ config(schema)
831
+ {
832
+ // ...code omitted for sake of brevity...
833
+ }
834
+
835
+ // No change from synchronous version.
836
+ Json::Value previewConfigUpdate(const Json::Value &updates,
837
+ vector<ConfigKit::Error> &errors)
838
+ {
839
+ // ...code omitted for sake of brevity...
840
+ }
841
+
842
+ // No change from synchronous version.
843
+ bool configure(const Json::Value &updates, vector<ConfigKit::Error> &errors) {
844
+ // ...code omitted for sake of brevity...
845
+ }
846
+
847
+ // No change from synchronous version.
848
+ Json::Value inspectConfig() const {
849
+ // ...code omitted for sake of brevity...
850
+ }
851
+
852
+
853
+ /****** Introduction of asynchronous methods below ******/
854
+
855
+ // Performs the same thing as the synchronous version, but
856
+ // over the event loop.
857
+ void asyncPreviewConfigUpdate(const Json::Value &updates,
858
+ const ConfigKit::ConfigCallback &callback)
859
+ {
860
+ // The exact API depends on which event loop implementation
861
+ // you use. When using libev, use SafeLibev::runLater().
862
+ // When using Boost Asio, use io_service.post().
863
+ //
864
+ // We use the utility function ConfigKit::callPreviewConfigUpdateAndCallback.
865
+ // This function assumes that SecurityChecker supports previewConfigUpdate().
866
+ eventLoop.threadSafeRunInNextTick(boost::bind(
867
+ ConfigKit::callPreviewConfigUpdateAndCallback<SecurityChecker>,
868
+ this, updates, callback));
869
+ }
870
+
871
+ // Performs the same thing as the synchronous version, but
872
+ // over the event loop.
873
+ void asyncConfigure(const Json::Value &updates,
874
+ const ConfigKit::ConfigCallback &callback)
875
+ {
876
+ // We use the utility function ConfigKit::callPreviewConfigUpdateAndCallback.
877
+ // This function assumes that SecurityChecker supports configure().
878
+ eventLoop.threadSafeRunInNextTick(boost::bind(
879
+ ConfigKit::callConfigureAndCallback<SecurityChecker>,
880
+ this, updates, callback));
881
+ }
882
+
883
+ // Performs the same thing as the synchronous version, but
884
+ // over the event loop.
885
+ void asyncInspectConfig(const ConfigKit::InspectCallback &callback) const {
886
+ // We use the utility function ConfigKit::callPreviewConfigUpdateAndCallback.
887
+ // This function assumes that SecurityChecker supports inspectConfig().
888
+ eventLoop.threadSafeRunInNextTick(boost::bind(
889
+ ConfigKit::callInspectConfigAndCallback<SecurityChecker>,
890
+ this, callback));
891
+ }
892
+
893
+ // ...further fictional code here for performing the lookup...
894
+ };
895
+ ~~~