passenger 3.0.21 → 3.9.1.beta

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 (835) hide show
  1. data/DEVELOPERS.TXT +4 -10
  2. data/NEWS +19 -27
  3. data/Rakefile +20 -19
  4. data/bin/passenger +3 -2
  5. data/bin/passenger-config +35 -5
  6. data/bin/passenger-install-apache2-module +12 -12
  7. data/bin/passenger-install-nginx-module +55 -38
  8. data/bin/passenger-memory-stats +3 -1
  9. data/bin/passenger-status +7 -35
  10. data/build/agents.rb +107 -21
  11. data/build/apache2.rb +11 -46
  12. data/build/basics.rb +61 -9
  13. data/build/common_library.rb +59 -142
  14. data/build/cxx_tests.rb +111 -110
  15. data/build/documentation.rb +33 -0
  16. data/build/misc.rb +30 -12
  17. data/build/nginx.rb +10 -39
  18. data/build/oxt_tests.rb +1 -0
  19. data/build/ruby_extension.rb +1 -5
  20. data/build/test_basics.rb +3 -2
  21. data/dev/copy_boost_headers.rb +2 -1
  22. data/doc/Architectural overview.html +49 -90
  23. data/doc/DebuggingAndStressTesting.txt.md +49 -0
  24. data/doc/Packaging.txt.md +254 -0
  25. data/doc/Security of user switching support.html +35 -66
  26. data/doc/Users guide Apache.html +588 -758
  27. data/doc/Users guide Apache.idmap.txt +253 -136
  28. data/doc/Users guide Apache.txt +154 -109
  29. data/doc/Users guide Nginx.html +544 -660
  30. data/doc/Users guide Nginx.idmap.txt +179 -91
  31. data/doc/Users guide Nginx.txt +192 -118
  32. data/doc/Users guide Standalone.html +65 -48
  33. data/doc/Users guide Standalone.idmap.txt +10 -2
  34. data/doc/Users guide Standalone.txt +4 -0
  35. data/doc/images/glyphicons-halflings-white.png +0 -0
  36. data/doc/images/glyphicons-halflings.png +0 -0
  37. data/doc/images/phusion_banner_small.png +0 -0
  38. data/doc/images/{smart-lv2.png → smart.png} +0 -0
  39. data/doc/images/{smart-lv2.svg → smart.svg} +0 -0
  40. data/doc/templates/bootstrap.min.css +397 -0
  41. data/doc/templates/markdown.html.erb +117 -0
  42. data/doc/users_guide_snippets/analysis_and_system_maintenance.txt +2 -1
  43. data/doc/users_guide_snippets/appendix_c_spawning_methods.txt +26 -48
  44. data/doc/users_guide_snippets/passenger_spawn_method.txt +18 -30
  45. data/doc/users_guide_snippets/support_information.txt +30 -0
  46. data/ext/apache2/Bucket.cpp +9 -26
  47. data/ext/apache2/Bucket.h +13 -10
  48. data/ext/apache2/Configuration.cpp +70 -58
  49. data/ext/apache2/Configuration.hpp +19 -47
  50. data/ext/apache2/DirectoryMapper.h +7 -7
  51. data/ext/apache2/Hooks.cpp +150 -313
  52. data/ext/boost/algorithm/string/detail/case_conv.hpp +4 -2
  53. data/ext/boost/algorithm/string/detail/find_format.hpp +20 -20
  54. data/ext/boost/algorithm/string/detail/find_format_all.hpp +23 -23
  55. data/ext/boost/algorithm/string/detail/find_format_store.hpp +2 -2
  56. data/ext/boost/algorithm/string/detail/formatter.hpp +25 -0
  57. data/ext/boost/algorithm/string/formatter.hpp +20 -3
  58. data/ext/boost/assert.hpp +85 -4
  59. data/ext/boost/bind/bind.hpp +1 -1
  60. data/ext/boost/concept/detail/backward_compatibility.hpp +1 -1
  61. data/ext/boost/concept_check.hpp +140 -64
  62. data/ext/boost/config.hpp +1 -1
  63. data/ext/boost/config/auto_link.hpp +8 -6
  64. data/ext/boost/config/compiler/borland.hpp +12 -2
  65. data/ext/boost/config/compiler/clang.hpp +89 -30
  66. data/ext/boost/config/compiler/codegear.hpp +3 -2
  67. data/ext/boost/config/compiler/common_edg.hpp +7 -5
  68. data/ext/boost/config/compiler/cray.hpp +61 -0
  69. data/ext/boost/config/compiler/digitalmars.hpp +9 -1
  70. data/ext/boost/config/compiler/gcc.hpp +33 -24
  71. data/ext/boost/config/compiler/gcc_xml.hpp +4 -0
  72. data/ext/boost/config/compiler/hp_acc.hpp +12 -1
  73. data/ext/boost/config/compiler/intel.hpp +78 -4
  74. data/ext/boost/config/compiler/metrowerks.hpp +4 -1
  75. data/ext/boost/config/compiler/mpw.hpp +4 -1
  76. data/ext/boost/config/compiler/nvcc.hpp +8 -66
  77. data/ext/boost/config/compiler/pathscale.hpp +80 -0
  78. data/ext/boost/config/compiler/pgi.hpp +5 -5
  79. data/ext/boost/config/compiler/sunpro_cc.hpp +4 -1
  80. data/ext/boost/config/compiler/vacpp.hpp +37 -13
  81. data/ext/boost/config/compiler/visualc.hpp +24 -11
  82. data/ext/boost/config/platform/bsd.hpp +1 -1
  83. data/ext/boost/config/platform/cray.hpp +18 -0
  84. data/ext/boost/config/platform/cygwin.hpp +10 -0
  85. data/ext/boost/config/platform/linux.hpp +5 -0
  86. data/ext/boost/config/platform/macos.hpp +5 -4
  87. data/ext/boost/config/platform/symbian.hpp +5 -2
  88. data/ext/boost/config/platform/vms.hpp +25 -0
  89. data/ext/boost/config/platform/win32.hpp +7 -1
  90. data/ext/boost/config/select_compiler_config.hpp +8 -25
  91. data/ext/boost/config/select_platform_config.hpp +8 -1
  92. data/ext/boost/config/select_stdlib_config.hpp +9 -1
  93. data/ext/boost/config/stdlib/dinkumware.hpp +6 -9
  94. data/ext/boost/config/stdlib/libcomo.hpp +1 -4
  95. data/ext/boost/config/stdlib/libcpp.hpp +36 -0
  96. data/ext/boost/config/stdlib/libstdcpp3.hpp +37 -11
  97. data/ext/boost/config/stdlib/modena.hpp +1 -4
  98. data/ext/boost/config/stdlib/msl.hpp +1 -4
  99. data/ext/boost/config/stdlib/roguewave.hpp +9 -6
  100. data/ext/boost/config/stdlib/sgi.hpp +12 -4
  101. data/ext/boost/config/stdlib/stlport.hpp +11 -4
  102. data/ext/boost/config/stdlib/vacpp.hpp +11 -4
  103. data/ext/boost/config/suffix.hpp +71 -6
  104. data/ext/boost/config/warning_disable.hpp +1 -1
  105. data/ext/boost/container/container_fwd.hpp +177 -0
  106. data/ext/boost/cstdint.hpp +17 -12
  107. data/ext/boost/current_function.hpp +2 -1
  108. data/ext/boost/date_time/c_time.hpp +17 -1
  109. data/ext/boost/date_time/compiler_config.hpp +13 -15
  110. data/ext/boost/date_time/date_formatting.hpp +7 -1
  111. data/ext/boost/date_time/filetime_functions.hpp +4 -4
  112. data/ext/boost/date_time/gregorian_calendar.ipp +2 -2
  113. data/ext/boost/date_time/strings_from_facet.hpp +3 -3
  114. data/ext/boost/date_time/time_facet.hpp +101 -101
  115. data/ext/boost/detail/endian.hpp +4 -2
  116. data/ext/boost/detail/fenv.hpp +74 -0
  117. data/ext/boost/detail/sp_typeinfo.hpp +6 -0
  118. data/ext/boost/exception/detail/clone_current_exception.hpp +47 -0
  119. data/ext/boost/exception/detail/exception_ptr.hpp +194 -122
  120. data/ext/boost/exception/detail/type_info.hpp +3 -3
  121. data/ext/boost/exception/diagnostic_information.hpp +37 -21
  122. data/ext/boost/exception/exception.hpp +21 -1
  123. data/ext/boost/exception/info.hpp +0 -1
  124. data/ext/boost/function.hpp +2 -2
  125. data/ext/boost/function/function_base.hpp +15 -9
  126. data/ext/boost/function/function_template.hpp +26 -48
  127. data/ext/boost/integer_fwd.hpp +0 -16
  128. data/ext/boost/integer_traits.hpp +2 -2
  129. data/ext/boost/iterator.hpp +1 -1
  130. data/ext/boost/iterator/iterator_adaptor.hpp +1 -7
  131. data/ext/boost/iterator/iterator_facade.hpp +13 -13
  132. data/ext/boost/iterator/transform_iterator.hpp +5 -20
  133. data/ext/boost/lexical_cast.hpp +1655 -673
  134. data/ext/boost/math/policies/policy.hpp +982 -0
  135. data/ext/boost/math/special_functions/detail/fp_traits.hpp +570 -0
  136. data/ext/boost/math/special_functions/detail/round_fwd.hpp +80 -0
  137. data/ext/boost/math/special_functions/fpclassify.hpp +533 -0
  138. data/ext/boost/math/special_functions/math_fwd.hpp +1070 -0
  139. data/ext/boost/math/special_functions/sign.hpp +145 -0
  140. data/ext/boost/math/tools/config.hpp +321 -0
  141. data/ext/boost/math/tools/promotion.hpp +150 -0
  142. data/ext/boost/math/tools/real_cast.hpp +29 -0
  143. data/ext/boost/math/tools/user.hpp +97 -0
  144. data/ext/boost/move/move.hpp +1222 -0
  145. data/ext/boost/mpl/O1_size.hpp +40 -0
  146. data/ext/boost/mpl/O1_size_fwd.hpp +24 -0
  147. data/ext/boost/mpl/advance.hpp +76 -0
  148. data/ext/boost/mpl/advance_fwd.hpp +28 -0
  149. data/ext/boost/mpl/at.hpp +52 -0
  150. data/ext/boost/mpl/at_fwd.hpp +24 -0
  151. data/ext/boost/mpl/aux_/O1_size_impl.hpp +87 -0
  152. data/ext/boost/mpl/aux_/advance_backward.hpp +128 -0
  153. data/ext/boost/mpl/aux_/advance_forward.hpp +127 -0
  154. data/ext/boost/mpl/aux_/arithmetic_op.hpp +92 -0
  155. data/ext/boost/mpl/aux_/at_impl.hpp +45 -0
  156. data/ext/boost/mpl/aux_/begin_end_impl.hpp +101 -0
  157. data/ext/boost/mpl/aux_/clear_impl.hpp +35 -0
  158. data/ext/boost/mpl/aux_/comparison_op.hpp +83 -0
  159. data/ext/boost/mpl/aux_/config/forwarding.hpp +27 -0
  160. data/ext/boost/mpl/aux_/config/typeof.hpp +38 -0
  161. data/ext/boost/mpl/aux_/contains_impl.hpp +61 -0
  162. data/ext/boost/mpl/aux_/find_if_pred.hpp +31 -0
  163. data/ext/boost/mpl/aux_/fold_impl.hpp +43 -0
  164. data/ext/boost/mpl/aux_/has_begin.hpp +23 -0
  165. data/ext/boost/mpl/aux_/has_size.hpp +23 -0
  166. data/ext/boost/mpl/aux_/has_tag.hpp +23 -0
  167. data/ext/boost/mpl/aux_/inserter_algorithm.hpp +159 -0
  168. data/ext/boost/mpl/aux_/is_msvc_eti_arg.hpp +64 -0
  169. data/ext/boost/mpl/aux_/iter_apply.hpp +47 -0
  170. data/ext/boost/mpl/aux_/iter_fold_if_impl.hpp +210 -0
  171. data/ext/boost/mpl/aux_/iter_fold_impl.hpp +42 -0
  172. data/ext/boost/mpl/aux_/lambda_spec.hpp +49 -0
  173. data/ext/boost/mpl/aux_/largest_int.hpp +63 -0
  174. data/ext/boost/mpl/aux_/msvc_eti_base.hpp +77 -0
  175. data/ext/boost/mpl/aux_/msvc_type.hpp +62 -0
  176. data/ext/boost/mpl/aux_/numeric_cast_utils.hpp +77 -0
  177. data/ext/boost/mpl/aux_/numeric_op.hpp +315 -0
  178. data/ext/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp +97 -0
  179. data/ext/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp +97 -0
  180. data/ext/boost/mpl/aux_/preprocessed/gcc/equal_to.hpp +94 -0
  181. data/ext/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp +180 -0
  182. data/ext/boost/mpl/aux_/preprocessed/gcc/greater.hpp +94 -0
  183. data/ext/boost/mpl/aux_/preprocessed/gcc/greater_equal.hpp +94 -0
  184. data/ext/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp +133 -0
  185. data/ext/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp +180 -0
  186. data/ext/boost/mpl/aux_/preprocessed/gcc/less.hpp +94 -0
  187. data/ext/boost/mpl/aux_/preprocessed/gcc/less_equal.hpp +94 -0
  188. data/ext/boost/mpl/aux_/preprocessed/gcc/list.hpp +323 -0
  189. data/ext/boost/mpl/aux_/preprocessed/gcc/minus.hpp +146 -0
  190. data/ext/boost/mpl/aux_/preprocessed/gcc/not_equal_to.hpp +94 -0
  191. data/ext/boost/mpl/aux_/preprocessed/gcc/plus.hpp +146 -0
  192. data/ext/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp +231 -0
  193. data/ext/boost/mpl/aux_/preprocessed/gcc/times.hpp +146 -0
  194. data/ext/boost/mpl/aux_/preprocessed/gcc/vector.hpp +323 -0
  195. data/ext/boost/mpl/aux_/preprocessor/default_params.hpp +67 -0
  196. data/ext/boost/mpl/aux_/push_back_impl.hpp +70 -0
  197. data/ext/boost/mpl/aux_/push_front_impl.hpp +71 -0
  198. data/ext/boost/mpl/aux_/reverse_fold_impl.hpp +44 -0
  199. data/ext/boost/mpl/aux_/size_impl.hpp +52 -0
  200. data/ext/boost/mpl/aux_/traits_lambda_spec.hpp +63 -0
  201. data/ext/boost/mpl/back_fwd.hpp +24 -0
  202. data/ext/boost/mpl/back_inserter.hpp +34 -0
  203. data/ext/boost/mpl/begin_end.hpp +57 -0
  204. data/ext/boost/mpl/begin_end_fwd.hpp +27 -0
  205. data/ext/boost/mpl/clear.hpp +39 -0
  206. data/ext/boost/mpl/clear_fwd.hpp +24 -0
  207. data/ext/boost/mpl/comparison.hpp +24 -0
  208. data/ext/boost/mpl/contains.hpp +41 -0
  209. data/ext/boost/mpl/contains_fwd.hpp +25 -0
  210. data/ext/boost/mpl/deref.hpp +41 -0
  211. data/ext/boost/mpl/distance.hpp +78 -0
  212. data/ext/boost/mpl/distance_fwd.hpp +28 -0
  213. data/ext/boost/mpl/empty_fwd.hpp +24 -0
  214. data/ext/boost/mpl/equal_to.hpp +21 -0
  215. data/ext/boost/mpl/find.hpp +38 -0
  216. data/ext/boost/mpl/find_if.hpp +50 -0
  217. data/ext/boost/mpl/fold.hpp +48 -0
  218. data/ext/boost/mpl/front_fwd.hpp +24 -0
  219. data/ext/boost/mpl/front_inserter.hpp +33 -0
  220. data/ext/boost/mpl/greater.hpp +21 -0
  221. data/ext/boost/mpl/greater_equal.hpp +21 -0
  222. data/ext/boost/mpl/inserter.hpp +32 -0
  223. data/ext/boost/mpl/iter_fold.hpp +49 -0
  224. data/ext/boost/mpl/iter_fold_if.hpp +117 -0
  225. data/ext/boost/mpl/iterator_range.hpp +42 -0
  226. data/ext/boost/mpl/iterator_tags.hpp +27 -0
  227. data/ext/boost/mpl/less.hpp +21 -0
  228. data/ext/boost/mpl/less_equal.hpp +21 -0
  229. data/ext/boost/mpl/limits/list.hpp +21 -0
  230. data/ext/boost/mpl/limits/vector.hpp +21 -0
  231. data/ext/boost/mpl/list.hpp +57 -0
  232. data/ext/boost/mpl/list/aux_/O1_size.hpp +33 -0
  233. data/ext/boost/mpl/list/aux_/begin_end.hpp +44 -0
  234. data/ext/boost/mpl/list/aux_/clear.hpp +34 -0
  235. data/ext/boost/mpl/list/aux_/empty.hpp +34 -0
  236. data/ext/boost/mpl/list/aux_/front.hpp +33 -0
  237. data/ext/boost/mpl/list/aux_/include_preprocessed.hpp +35 -0
  238. data/ext/boost/mpl/list/aux_/item.hpp +55 -0
  239. data/ext/boost/mpl/list/aux_/iterator.hpp +76 -0
  240. data/ext/boost/mpl/list/aux_/pop_front.hpp +34 -0
  241. data/ext/boost/mpl/list/aux_/preprocessed/plain/list10.hpp +149 -0
  242. data/ext/boost/mpl/list/aux_/preprocessed/plain/list20.hpp +169 -0
  243. data/ext/boost/mpl/list/aux_/push_back.hpp +36 -0
  244. data/ext/boost/mpl/list/aux_/push_front.hpp +39 -0
  245. data/ext/boost/mpl/list/aux_/size.hpp +33 -0
  246. data/ext/boost/mpl/list/aux_/tag.hpp +24 -0
  247. data/ext/boost/mpl/list/list0.hpp +42 -0
  248. data/ext/boost/mpl/list/list10.hpp +43 -0
  249. data/ext/boost/mpl/list/list20.hpp +43 -0
  250. data/ext/boost/mpl/long.hpp +22 -0
  251. data/ext/boost/mpl/long_fwd.hpp +27 -0
  252. data/ext/boost/mpl/minus.hpp +21 -0
  253. data/ext/boost/mpl/multiplies.hpp +53 -0
  254. data/ext/boost/mpl/negate.hpp +81 -0
  255. data/ext/boost/mpl/not_equal_to.hpp +21 -0
  256. data/ext/boost/mpl/numeric_cast.hpp +41 -0
  257. data/ext/boost/mpl/pair.hpp +70 -0
  258. data/ext/boost/mpl/plus.hpp +21 -0
  259. data/ext/boost/mpl/pop_back_fwd.hpp +24 -0
  260. data/ext/boost/mpl/pop_front_fwd.hpp +24 -0
  261. data/ext/boost/mpl/prior.hpp +19 -0
  262. data/ext/boost/mpl/push_back.hpp +53 -0
  263. data/ext/boost/mpl/push_back_fwd.hpp +24 -0
  264. data/ext/boost/mpl/push_front.hpp +52 -0
  265. data/ext/boost/mpl/push_front_fwd.hpp +24 -0
  266. data/ext/boost/mpl/remove_if.hpp +83 -0
  267. data/ext/boost/mpl/reverse_fold.hpp +50 -0
  268. data/ext/boost/mpl/same_as.hpp +55 -0
  269. data/ext/boost/mpl/sequence_tag.hpp +124 -0
  270. data/ext/boost/mpl/sequence_tag_fwd.hpp +26 -0
  271. data/ext/boost/mpl/size.hpp +42 -0
  272. data/ext/boost/mpl/size_fwd.hpp +24 -0
  273. data/ext/boost/mpl/tag.hpp +52 -0
  274. data/ext/boost/mpl/times.hpp +21 -0
  275. data/ext/boost/mpl/vector.hpp +57 -0
  276. data/ext/boost/mpl/vector/aux_/O1_size.hpp +56 -0
  277. data/ext/boost/mpl/vector/aux_/at.hpp +116 -0
  278. data/ext/boost/mpl/vector/aux_/back.hpp +59 -0
  279. data/ext/boost/mpl/vector/aux_/begin_end.hpp +49 -0
  280. data/ext/boost/mpl/vector/aux_/clear.hpp +55 -0
  281. data/ext/boost/mpl/vector/aux_/empty.hpp +68 -0
  282. data/ext/boost/mpl/vector/aux_/front.hpp +56 -0
  283. data/ext/boost/mpl/vector/aux_/include_preprocessed.hpp +55 -0
  284. data/ext/boost/mpl/vector/aux_/item.hpp +103 -0
  285. data/ext/boost/mpl/vector/aux_/iterator.hpp +130 -0
  286. data/ext/boost/mpl/vector/aux_/pop_back.hpp +40 -0
  287. data/ext/boost/mpl/vector/aux_/pop_front.hpp +40 -0
  288. data/ext/boost/mpl/vector/aux_/preprocessed/plain/vector10.hpp +829 -0
  289. data/ext/boost/mpl/vector/aux_/preprocessed/plain/vector20.hpp +1144 -0
  290. data/ext/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10.hpp +139 -0
  291. data/ext/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20.hpp +159 -0
  292. data/ext/boost/mpl/vector/aux_/push_back.hpp +40 -0
  293. data/ext/boost/mpl/vector/aux_/push_front.hpp +40 -0
  294. data/ext/boost/mpl/vector/aux_/size.hpp +49 -0
  295. data/ext/boost/mpl/vector/aux_/tag.hpp +32 -0
  296. data/ext/boost/mpl/vector/aux_/vector0.hpp +52 -0
  297. data/ext/boost/mpl/vector/vector0.hpp +34 -0
  298. data/ext/boost/mpl/vector/vector10.hpp +45 -0
  299. data/ext/boost/mpl/vector/vector20.hpp +45 -0
  300. data/ext/boost/none.hpp +1 -1
  301. data/ext/boost/numeric/conversion/bounds.hpp +24 -0
  302. data/ext/boost/numeric/conversion/cast.hpp +61 -0
  303. data/ext/boost/numeric/conversion/conversion_traits.hpp +39 -0
  304. data/ext/boost/numeric/conversion/converter.hpp +68 -0
  305. data/ext/boost/numeric/conversion/converter_policies.hpp +186 -0
  306. data/ext/boost/numeric/conversion/detail/bounds.hpp +58 -0
  307. data/ext/boost/numeric/conversion/detail/conversion_traits.hpp +97 -0
  308. data/ext/boost/numeric/conversion/detail/converter.hpp +602 -0
  309. data/ext/boost/numeric/conversion/detail/int_float_mixture.hpp +72 -0
  310. data/ext/boost/numeric/conversion/detail/is_subranged.hpp +234 -0
  311. data/ext/boost/numeric/conversion/detail/meta.hpp +120 -0
  312. data/ext/boost/numeric/conversion/detail/numeric_cast_traits.hpp +138 -0
  313. data/ext/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_common.hpp +1741 -0
  314. data/ext/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_long_long.hpp +347 -0
  315. data/ext/boost/numeric/conversion/detail/sign_mixture.hpp +72 -0
  316. data/ext/boost/numeric/conversion/detail/udt_builtin_mixture.hpp +69 -0
  317. data/ext/boost/numeric/conversion/int_float_mixture_enum.hpp +29 -0
  318. data/ext/boost/numeric/conversion/numeric_cast_traits.hpp +31 -0
  319. data/ext/boost/numeric/conversion/sign_mixture_enum.hpp +29 -0
  320. data/ext/boost/numeric/conversion/udt_builtin_mixture_enum.hpp +26 -0
  321. data/ext/boost/operators.hpp +3 -1
  322. data/ext/boost/optional/optional.hpp +146 -79
  323. data/ext/boost/optional/optional_fwd.hpp +8 -1
  324. data/ext/boost/preprocessor/cat.hpp +2 -2
  325. data/ext/boost/preprocessor/config/config.hpp +39 -4
  326. data/ext/boost/preprocessor/facilities/intercept.hpp +277 -0
  327. data/ext/boost/preprocessor/facilities/overload.hpp +25 -0
  328. data/ext/boost/preprocessor/iteration/detail/iter/forward1.hpp +3 -3
  329. data/ext/boost/preprocessor/iteration/iterate.hpp +3 -3
  330. data/ext/boost/preprocessor/punctuation/paren.hpp +23 -0
  331. data/ext/boost/preprocessor/repetition/enum_shifted_params.hpp +44 -0
  332. data/ext/boost/preprocessor/seq/cat.hpp +5 -4
  333. data/ext/boost/preprocessor/seq/size.hpp +0 -1
  334. data/ext/boost/preprocessor/tuple/eat.hpp +83 -34
  335. data/ext/boost/preprocessor/tuple/elem.hpp +161 -355
  336. data/ext/boost/preprocessor/tuple/rem.hpp +110 -48
  337. data/ext/boost/preprocessor/tuple/to_list.hpp +90 -36
  338. data/ext/boost/preprocessor/variadic/elem.hpp +94 -0
  339. data/ext/boost/preprocessor/variadic/size.hpp +30 -0
  340. data/ext/boost/range/begin.hpp +17 -6
  341. data/ext/boost/range/concepts.hpp +37 -2
  342. data/ext/boost/range/detail/safe_bool.hpp +72 -0
  343. data/ext/boost/range/end.hpp +14 -9
  344. data/ext/boost/range/iterator_range_core.hpp +120 -12
  345. data/ext/boost/range/size.hpp +21 -5
  346. data/ext/boost/smart_ptr/detail/shared_count.hpp +88 -0
  347. data/ext/boost/smart_ptr/detail/sp_counted_base.hpp +3 -0
  348. data/ext/boost/smart_ptr/detail/sp_counted_base_aix.hpp +142 -0
  349. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +9 -0
  350. data/ext/boost/smart_ptr/detail/sp_counted_impl.hpp +10 -2
  351. data/ext/boost/smart_ptr/detail/sp_has_sync.hpp +5 -1
  352. data/ext/boost/smart_ptr/detail/spinlock.hpp +4 -1
  353. data/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +20 -3
  354. data/ext/boost/smart_ptr/detail/spinlock_pool.hpp +4 -0
  355. data/ext/boost/smart_ptr/make_shared.hpp +591 -22
  356. data/ext/boost/smart_ptr/shared_array.hpp +29 -1
  357. data/ext/boost/smart_ptr/shared_ptr.hpp +29 -13
  358. data/ext/boost/smart_ptr/weak_ptr.hpp +24 -12
  359. data/ext/boost/src/pthread/once.cpp +9 -7
  360. data/ext/boost/src/pthread/thread.cpp +32 -28
  361. data/ext/boost/src/pthread/timeconv.inl +4 -5
  362. data/ext/boost/src/tss_null.cpp +5 -1
  363. data/ext/boost/static_assert.hpp +8 -2
  364. data/ext/boost/thread/detail/config.hpp +19 -4
  365. data/ext/boost/thread/detail/move.hpp +11 -5
  366. data/ext/boost/thread/detail/thread.hpp +59 -43
  367. data/ext/boost/thread/exceptions.hpp +9 -9
  368. data/ext/boost/thread/future.hpp +150 -82
  369. data/ext/boost/thread/locks.hpp +101 -60
  370. data/ext/boost/thread/pthread/condition_variable.hpp +79 -32
  371. data/ext/boost/thread/pthread/condition_variable_fwd.hpp +12 -3
  372. data/ext/boost/thread/pthread/mutex.hpp +17 -14
  373. data/ext/boost/thread/pthread/once.hpp +3 -4
  374. data/ext/boost/thread/pthread/pthread_mutex_scoped_lock.hpp +12 -2
  375. data/ext/boost/thread/pthread/recursive_mutex.hpp +19 -19
  376. data/ext/boost/thread/pthread/shared_mutex.hpp +13 -13
  377. data/ext/boost/thread/pthread/thread_data.hpp +40 -12
  378. data/ext/boost/thread/thread_time.hpp +5 -0
  379. data/ext/boost/throw_exception.hpp +1 -1
  380. data/ext/boost/token_functions.hpp +34 -10
  381. data/ext/boost/type_traits/add_rvalue_reference.hpp +66 -0
  382. data/ext/boost/type_traits/alignment_of.hpp +1 -1
  383. data/ext/boost/type_traits/detail/bool_trait_def.hpp +26 -3
  384. data/ext/boost/type_traits/detail/bool_trait_undef.hpp +3 -2
  385. data/ext/boost/type_traits/detail/cv_traits_impl.hpp +1 -1
  386. data/ext/boost/type_traits/detail/size_t_trait_def.hpp +6 -4
  387. data/ext/boost/type_traits/detail/type_trait_def.hpp +8 -2
  388. data/ext/boost/type_traits/function_traits.hpp +1 -1
  389. data/ext/boost/type_traits/has_nothrow_constructor.hpp +53 -0
  390. data/ext/boost/type_traits/has_nothrow_copy.hpp +19 -5
  391. data/ext/boost/type_traits/has_trivial_constructor.hpp +51 -0
  392. data/ext/boost/type_traits/has_trivial_copy.hpp +20 -5
  393. data/ext/boost/type_traits/has_trivial_destructor.hpp +12 -5
  394. data/ext/boost/type_traits/intrinsics.hpp +119 -71
  395. data/ext/boost/type_traits/is_const.hpp +5 -5
  396. data/ext/boost/type_traits/is_convertible.hpp +14 -13
  397. data/ext/boost/type_traits/is_enum.hpp +1 -1
  398. data/ext/boost/type_traits/is_floating_point.hpp +27 -0
  399. data/ext/boost/type_traits/is_function.hpp +3 -3
  400. data/ext/boost/type_traits/is_fundamental.hpp +1 -1
  401. data/ext/boost/type_traits/is_member_function_pointer.hpp +2 -2
  402. data/ext/boost/type_traits/is_member_pointer.hpp +2 -2
  403. data/ext/boost/type_traits/is_pod.hpp +11 -3
  404. data/ext/boost/type_traits/is_pointer.hpp +2 -2
  405. data/ext/boost/type_traits/is_signed.hpp +8 -3
  406. data/ext/boost/type_traits/is_union.hpp +8 -0
  407. data/ext/boost/type_traits/is_unsigned.hpp +9 -4
  408. data/ext/boost/type_traits/is_volatile.hpp +5 -5
  409. data/ext/boost/type_traits/remove_cv.hpp +4 -3
  410. data/ext/boost/type_traits/remove_pointer.hpp +51 -2
  411. data/ext/boost/type_traits/remove_reference.hpp +2 -2
  412. data/ext/boost/type_traits/type_with_alignment.hpp +8 -2
  413. data/ext/boost/utility/declval.hpp +44 -0
  414. data/ext/boost/utility/detail/in_place_factory_prefix.hpp +36 -0
  415. data/ext/boost/utility/detail/in_place_factory_suffix.hpp +23 -0
  416. data/ext/boost/utility/detail/result_of_iterate.hpp +142 -0
  417. data/ext/boost/utility/in_place_factory.hpp +88 -0
  418. data/ext/boost/utility/result_of.hpp +103 -0
  419. data/ext/boost/utility/swap.hpp +55 -0
  420. data/ext/common/AnsiColorConstants.h +36 -0
  421. data/ext/common/ApplicationPool2/Common.h +87 -0
  422. data/ext/common/ApplicationPool2/ComponentInfo.h +53 -0
  423. data/ext/common/ApplicationPool2/Group.h +648 -0
  424. data/ext/common/ApplicationPool2/Implementation.cpp +580 -0
  425. data/ext/common/ApplicationPool2/Options.h +576 -0
  426. data/ext/common/ApplicationPool2/PipeWatcher.h +61 -0
  427. data/ext/common/ApplicationPool2/Pool.h +1181 -0
  428. data/ext/common/ApplicationPool2/Process.h +425 -0
  429. data/ext/common/ApplicationPool2/README.md +96 -0
  430. data/ext/common/ApplicationPool2/Session.h +158 -0
  431. data/ext/common/ApplicationPool2/Socket.h +246 -0
  432. data/ext/common/ApplicationPool2/Spawner.h +2212 -0
  433. data/ext/common/ApplicationPool2/SuperGroup.h +749 -0
  434. data/ext/common/BackgroundEventLoop.cpp +129 -0
  435. data/ext/common/BackgroundEventLoop.h +61 -0
  436. data/ext/common/Constants.h +3 -1
  437. data/ext/common/EventedBufferedInput.h +331 -0
  438. data/ext/common/EventedMessageServer.h +17 -34
  439. data/ext/common/EventedServer.h +2 -2
  440. data/ext/common/Exceptions.h +71 -19
  441. data/ext/common/FileDescriptor.h +8 -6
  442. data/ext/common/HttpConstants.h +167 -0
  443. data/ext/common/IniFile.h +24 -0
  444. data/ext/common/Logging.h +62 -849
  445. data/ext/common/MessageReadersWriters.h +19 -0
  446. data/ext/common/MessageServer.h +11 -14
  447. data/ext/common/MultiLibeio.cpp +198 -0
  448. data/ext/common/MultiLibeio.h +67 -0
  449. data/ext/common/ResourceLocator.h +24 -41
  450. data/ext/common/SafeLibev.h +186 -14
  451. data/ext/common/StaticString.h +23 -3
  452. data/ext/common/UnionStation.h +972 -0
  453. data/ext/common/Utils.cpp +168 -24
  454. data/ext/common/Utils.h +25 -3
  455. data/ext/common/Utils/CachedFileStat.hpp +4 -3
  456. data/ext/common/Utils/FileChangeChecker.h +2 -2
  457. data/ext/common/Utils/HashMap.h +50 -0
  458. data/ext/common/Utils/IOUtils.cpp +229 -68
  459. data/ext/common/Utils/IOUtils.h +134 -3
  460. data/ext/common/Utils/Lock.h +28 -0
  461. data/ext/common/Utils/MemoryBarrier.h +52 -0
  462. data/ext/common/Utils/PriorityQueue.h +54 -0
  463. data/ext/common/Utils/ProcessMetricsCollector.h +9 -11
  464. data/ext/common/Utils/ScopeGuard.h +50 -1
  465. data/ext/common/Utils/SmallVector.h +653 -0
  466. data/ext/common/Utils/StrIntUtils.cpp +26 -2
  467. data/ext/common/Utils/StrIntUtils.h +18 -2
  468. data/ext/common/Utils/StringMap.h +125 -8
  469. data/ext/common/Utils/Template.h +212 -0
  470. data/ext/common/Utils/fib.c +699 -0
  471. data/ext/common/Utils/fib.h +101 -0
  472. data/ext/common/Utils/fibpriv.h +67 -0
  473. data/ext/common/Utils/json-forwards.h +249 -0
  474. data/ext/common/Utils/json.h +1855 -0
  475. data/ext/common/Utils/jsoncpp.cpp +4230 -0
  476. data/ext/common/agents/Base.cpp +1126 -0
  477. data/ext/common/{AgentBase.h → agents/Base.h} +5 -1
  478. data/ext/common/agents/EnvPrinter.c +16 -0
  479. data/ext/common/agents/HelperAgent/AgentOptions.h +81 -0
  480. data/ext/common/{HelperAgent → agents/HelperAgent}/BacktracesServer.h +3 -2
  481. data/ext/common/agents/HelperAgent/FileBackedPipe.h +732 -0
  482. data/ext/common/agents/HelperAgent/Main.cpp +497 -0
  483. data/ext/common/agents/HelperAgent/RequestHandler.cpp +283 -0
  484. data/ext/common/agents/HelperAgent/RequestHandler.h +2139 -0
  485. data/ext/common/agents/HelperAgent/ScgiRequestParser.h +451 -0
  486. data/ext/common/{LoggingAgent → agents/LoggingAgent}/DataStoreId.h +1 -1
  487. data/ext/common/{LoggingAgent → agents/LoggingAgent}/FilterSupport.cpp +1 -1
  488. data/ext/common/{LoggingAgent → agents/LoggingAgent}/FilterSupport.h +0 -0
  489. data/ext/common/{LoggingAgent → agents/LoggingAgent}/LoggingServer.h +18 -16
  490. data/ext/common/{LoggingAgent → agents/LoggingAgent}/Main.cpp +15 -13
  491. data/ext/common/{LoggingAgent → agents/LoggingAgent}/RemoteSender.h +6 -6
  492. data/ext/common/agents/SpawnPreparer.cpp +127 -0
  493. data/ext/common/{Watchdog.cpp → agents/Watchdog/Main.cpp} +63 -25
  494. data/ext/libeio/Changes +72 -0
  495. data/ext/{google/COPYING → libeio/LICENSE} +17 -9
  496. data/ext/libeio/Makefile.am +15 -0
  497. data/ext/libeio/Makefile.in +694 -0
  498. data/ext/libeio/aclocal.m4 +9418 -0
  499. data/ext/libeio/autogen.sh +3 -0
  500. data/ext/libeio/config.guess +1501 -0
  501. data/ext/libeio/config.h.in +136 -0
  502. data/ext/libeio/config.sub +1705 -0
  503. data/ext/libeio/configure +14822 -0
  504. data/ext/libeio/configure.ac +22 -0
  505. data/ext/libeio/demo.c +194 -0
  506. data/ext/libeio/ecb.h +457 -0
  507. data/ext/libeio/eio.c +2816 -0
  508. data/ext/libeio/eio.h +411 -0
  509. data/ext/libeio/install-sh +520 -0
  510. data/ext/libeio/libeio.m4 +211 -0
  511. data/ext/libeio/ltmain.sh +9636 -0
  512. data/ext/libeio/missing +376 -0
  513. data/ext/libeio/xthread.h +166 -0
  514. data/ext/libev/Changes +125 -7
  515. data/ext/libev/Makefile.am +5 -3
  516. data/ext/libev/Makefile.in +209 -120
  517. data/ext/libev/aclocal.m4 +6027 -4619
  518. data/ext/libev/autogen.sh +1 -4
  519. data/ext/libev/config.h.in +11 -7
  520. data/ext/libev/configure +7312 -14993
  521. data/ext/libev/configure.ac +12 -5
  522. data/ext/libev/depcomp +630 -0
  523. data/ext/libev/ev++.h +48 -32
  524. data/ext/libev/ev.c +1173 -391
  525. data/ext/libev/ev.h +315 -181
  526. data/ext/libev/ev_epoll.c +66 -15
  527. data/ext/libev/ev_kqueue.c +20 -18
  528. data/ext/libev/ev_poll.c +27 -23
  529. data/ext/libev/ev_port.c +39 -19
  530. data/ext/libev/ev_select.c +23 -17
  531. data/ext/libev/ev_vars.h +25 -8
  532. data/ext/libev/ev_win32.c +6 -6
  533. data/ext/libev/ev_wrap.h +22 -2
  534. data/ext/libev/event.c +18 -17
  535. data/ext/libev/event.h +16 -4
  536. data/ext/libev/libev.m4 +10 -6
  537. data/ext/libev/ltmain.sh +7353 -5811
  538. data/ext/nginx/Configuration.c +74 -42
  539. data/ext/nginx/Configuration.h +3 -5
  540. data/ext/nginx/ContentHandler.c +26 -83
  541. data/ext/nginx/ContentHandler.h +1 -1
  542. data/ext/nginx/config +13 -9
  543. data/ext/nginx/ngx_http_passenger_module.c +3 -7
  544. data/ext/oxt/detail/backtrace_enabled.hpp +5 -102
  545. data/ext/oxt/detail/context.hpp +90 -0
  546. data/ext/oxt/detail/spin_lock_darwin.hpp +4 -0
  547. data/ext/oxt/detail/spin_lock_gcc_x86.hpp +4 -0
  548. data/ext/oxt/detail/spin_lock_pthreads.hpp +14 -0
  549. data/ext/oxt/detail/tracable_exception_enabled.hpp +2 -2
  550. data/ext/oxt/dynamic_thread_group.hpp +27 -1
  551. data/ext/oxt/implementation.cpp +415 -0
  552. data/ext/oxt/{thread.cpp → initialize.hpp} +13 -6
  553. data/ext/oxt/macros.hpp +32 -1
  554. data/ext/oxt/spin_lock.hpp +6 -11
  555. data/ext/oxt/system_calls.cpp +204 -16
  556. data/ext/oxt/system_calls.hpp +85 -45
  557. data/ext/oxt/thread.hpp +13 -117
  558. data/ext/ruby/passenger_native_support.c +82 -237
  559. data/helper-scripts/backtrace-sanitizer.rb +114 -0
  560. data/helper-scripts/classic-rails-loader.rb +135 -0
  561. data/helper-scripts/classic-rails-preloader.rb +161 -0
  562. data/helper-scripts/node-loader.js +314 -0
  563. data/helper-scripts/rack-loader.rb +104 -0
  564. data/helper-scripts/rack-preloader.rb +132 -0
  565. data/helper-scripts/wsgi-loader.py +231 -0
  566. data/helper-scripts/wsgi-preloader.py +1 -0
  567. data/lib/phusion_passenger.rb +159 -61
  568. data/lib/phusion_passenger/abstract_installer.rb +182 -87
  569. data/lib/phusion_passenger/admin_tools/server_instance.rb +25 -19
  570. data/lib/phusion_passenger/analytics_logger.rb +5 -4
  571. data/lib/phusion_passenger/classic_rails/{request_handler.rb → thread_handler_extension.rb} +4 -40
  572. data/lib/phusion_passenger/classic_rails_extensions/init.rb +5 -3
  573. data/lib/phusion_passenger/common_library.rb +441 -0
  574. data/lib/phusion_passenger/console_text_template.rb +4 -16
  575. data/lib/phusion_passenger/constants.rb +1 -8
  576. data/lib/phusion_passenger/debug_logging.rb +5 -2
  577. data/lib/phusion_passenger/dependencies.rb +51 -13
  578. data/lib/phusion_passenger/loader_shared_helpers.rb +318 -0
  579. data/lib/phusion_passenger/message_channel.rb +3 -47
  580. data/lib/phusion_passenger/message_client.rb +2 -2
  581. data/lib/phusion_passenger/native_support.rb +36 -15
  582. data/lib/phusion_passenger/packaging.rb +8 -11
  583. data/lib/phusion_passenger/platform_info.rb +25 -17
  584. data/lib/phusion_passenger/platform_info/apache.rb +10 -7
  585. data/lib/phusion_passenger/platform_info/binary_compatibility.rb +10 -30
  586. data/lib/phusion_passenger/platform_info/compiler.rb +93 -34
  587. data/lib/phusion_passenger/platform_info/ruby.rb +37 -97
  588. data/lib/phusion_passenger/preloader_shared_helpers.rb +121 -0
  589. data/lib/phusion_passenger/public_api.rb +1 -4
  590. data/lib/phusion_passenger/rack/{request_handler.rb → thread_handler_extension.rb} +14 -63
  591. data/lib/phusion_passenger/rails3_extensions/init.rb +9 -8
  592. data/lib/phusion_passenger/request_handler.rb +500 -0
  593. data/lib/phusion_passenger/request_handler/thread_handler.rb +360 -0
  594. data/lib/phusion_passenger/ruby_core_enhancements.rb +142 -0
  595. data/lib/phusion_passenger/standalone/command.rb +36 -15
  596. data/lib/phusion_passenger/standalone/package_runtime_command.rb +16 -8
  597. data/lib/phusion_passenger/standalone/runtime_installer.rb +169 -72
  598. data/lib/phusion_passenger/standalone/start_command.rb +44 -39
  599. data/lib/phusion_passenger/standalone/utils.rb +5 -5
  600. data/lib/phusion_passenger/utils.rb +35 -914
  601. data/lib/phusion_passenger/utils/ansi_colors.rb +59 -0
  602. data/lib/phusion_passenger/utils/file_system_watcher.rb +1 -1
  603. data/lib/phusion_passenger/utils/robust_interruption.rb +134 -0
  604. data/lib/phusion_passenger/utils/tee_input.rb +174 -0
  605. data/lib/phusion_passenger/utils/tmpio.rb +33 -0
  606. data/lib/phusion_passenger/utils/unseekable_socket.rb +6 -0
  607. data/resources/mime.types +5 -1
  608. data/{lib/phusion_passenger/templates → resources}/standalone_default_root/index.html +0 -0
  609. data/{lib/phusion_passenger → resources}/templates/apache2/apache_must_be_compiled_with_compatible_mpm.txt.erb +0 -0
  610. data/{lib/phusion_passenger → resources}/templates/apache2/config_snippets.txt.erb +0 -0
  611. data/{lib/phusion_passenger → resources}/templates/apache2/deployment_example.txt.erb +0 -0
  612. data/{lib/phusion_passenger → resources}/templates/apache2/no_write_permission_to_passenger_root.txt.erb +0 -0
  613. data/{lib/phusion_passenger → resources}/templates/apache2/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  614. data/{lib/phusion_passenger → resources}/templates/apache2/run_installer_as_root.txt.erb +0 -0
  615. data/{lib/phusion_passenger → resources}/templates/apache2/welcome.txt.erb +0 -0
  616. data/{lib/phusion_passenger → resources}/templates/error_layout.css +6 -0
  617. data/resources/templates/error_layout.html.template +89 -0
  618. data/resources/templates/general_error.html.template +1 -0
  619. data/resources/templates/general_error_with_html.html.template +1 -0
  620. data/{lib/phusion_passenger → resources}/templates/nginx/ask_for_extra_configure_flags.txt.erb +0 -0
  621. data/{lib/phusion_passenger → resources}/templates/nginx/cannot_write_to_dir.txt.erb +0 -0
  622. data/{lib/phusion_passenger → resources}/templates/nginx/config_snippets.txt.erb +0 -0
  623. data/{lib/phusion_passenger → resources}/templates/nginx/config_snippets_inserted.txt.erb +0 -0
  624. data/{lib/phusion_passenger → resources}/templates/nginx/confirm_extra_configure_flags.txt.erb +0 -0
  625. data/{lib/phusion_passenger → resources}/templates/nginx/deployment_example.txt.erb +0 -0
  626. data/resources/templates/nginx/not_available_when_natively_packaged.txt.erb +8 -0
  627. data/{lib/phusion_passenger → resources}/templates/nginx/pcre_could_not_be_downloaded.txt.erb +0 -0
  628. data/{lib/phusion_passenger → resources}/templates/nginx/pcre_could_not_be_extracted.txt.erb +0 -0
  629. data/{lib/phusion_passenger → resources}/templates/nginx/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  630. data/{lib/phusion_passenger → resources}/templates/nginx/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -0
  631. data/{lib/phusion_passenger → resources}/templates/nginx/query_download_and_install.txt.erb +0 -0
  632. data/{lib/phusion_passenger → resources}/templates/nginx/run_installer_as_root.txt.erb +0 -0
  633. data/{lib/phusion_passenger → resources}/templates/nginx/welcome.txt.erb +0 -0
  634. data/{lib/phusion_passenger → resources}/templates/standalone/cannot_write_to_dir.txt.erb +0 -0
  635. data/{lib/phusion_passenger → resources}/templates/standalone/config.erb +26 -5
  636. data/{lib/phusion_passenger → resources}/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -0
  637. data/{lib/phusion_passenger → resources}/templates/standalone/run_installer_as_root.txt.erb +0 -0
  638. data/{lib/phusion_passenger → resources}/templates/standalone/welcome.txt.erb +0 -0
  639. data/resources/templates/undisclosed_error.html.template +25 -0
  640. data/test/config.json.example +42 -0
  641. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +86 -0
  642. data/test/cxx/ApplicationPool2/OptionsTest.cpp +44 -0
  643. data/test/cxx/ApplicationPool2/PoolTest.cpp +1234 -0
  644. data/test/cxx/ApplicationPool2/ProcessTest.cpp +131 -0
  645. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +229 -0
  646. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +744 -0
  647. data/test/cxx/BufferedIOTest.cpp +7 -7
  648. data/test/cxx/CxxTestMain.cpp +65 -2
  649. data/test/cxx/FileBackedPipeTest.cpp +626 -0
  650. data/test/cxx/FileChangeCheckerTest.cpp +20 -18
  651. data/test/cxx/FilterSupportTest.cpp +5 -5
  652. data/test/cxx/IOUtilsTest.cpp +11 -4
  653. data/test/cxx/MessageReadersWritersTest.cpp +1 -1
  654. data/test/cxx/MessageServerTest.cpp +31 -30
  655. data/test/cxx/RequestHandlerTest.cpp +777 -0
  656. data/test/cxx/ScgiRequestParserTest.cpp +36 -16
  657. data/test/cxx/ServerInstanceDirTest.cpp +1 -1
  658. data/test/cxx/StringMapTest.cpp +61 -0
  659. data/test/cxx/TemplateTest.cpp +118 -0
  660. data/test/cxx/TestSupport.cpp +25 -68
  661. data/test/cxx/TestSupport.h +81 -41
  662. data/test/cxx/{LoggingTest.cpp → UnionStationTest.cpp} +79 -74
  663. data/test/cxx/UtilsTest.cpp +59 -5
  664. data/test/integration_tests/apache2_tests.rb +2 -2
  665. data/test/integration_tests/nginx_tests.rb +1 -1
  666. data/test/integration_tests/spec_helper.rb +7 -5
  667. data/test/oxt/oxt_test_main.cpp +2 -0
  668. data/test/oxt/syscall_interruption_test.cpp +1 -0
  669. data/test/ruby/classic_rails/loader_spec.rb +48 -0
  670. data/test/ruby/classic_rails/preloader_spec.rb +54 -0
  671. data/test/ruby/rack/loader_spec.rb +62 -0
  672. data/test/ruby/rack/preloader_spec.rb +74 -0
  673. data/test/ruby/{abstract_request_handler_spec.rb → request_handler_spec.rb} +31 -68
  674. data/test/ruby/shared/loader_spec.rb +241 -0
  675. data/test/ruby/shared/rails/analytics_logging_extensions_spec.rb +141 -182
  676. data/test/ruby/shared/ruby_loader_spec.rb +55 -0
  677. data/test/ruby/spec_helper.rb +8 -53
  678. data/test/ruby/utils/file_system_watcher_spec.rb +9 -1
  679. data/test/ruby/utils_spec.rb +10 -683
  680. data/test/stub/rack/config.ru +28 -3
  681. data/test/stub/rack/start.rb +47 -0
  682. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/Rakefile +0 -0
  683. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/application_controller.rb +0 -2
  684. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/bar_controller_1.rb +0 -0
  685. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/bar_controller_2.rb +0 -0
  686. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/foo_controller.rb +0 -0
  687. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/helpers/application_helper.rb +0 -0
  688. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/boot.rb +0 -0
  689. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/database.yml +3 -3
  690. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environment.rb +5 -2
  691. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/development.rb +0 -0
  692. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/production.rb +0 -0
  693. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/staging.rb +0 -0
  694. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/initializers/inflections.rb +0 -0
  695. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/initializers/mime_types.rb +0 -0
  696. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/routes.rb +1 -0
  697. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/about +0 -0
  698. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/console +0 -0
  699. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/dbconsole +0 -0
  700. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/destroy +0 -0
  701. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/generate +0 -0
  702. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/benchmarker +0 -0
  703. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/profiler +0 -0
  704. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/request +0 -0
  705. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/plugin +0 -0
  706. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/inspector +0 -0
  707. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/reaper +0 -0
  708. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/spawner +0 -0
  709. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/runner +0 -0
  710. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/server +0 -0
  711. data/test/stub/{rails_apps/3.0/empty → rails3.0}/Gemfile +0 -0
  712. data/test/stub/rails3.0/Gemfile.lock +80 -0
  713. data/test/stub/{rails_apps/3.0/empty → rails3.0}/Rakefile +0 -0
  714. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/controllers/application_controller.rb +0 -0
  715. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/helpers/application_helper.rb +0 -0
  716. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/views/layouts/application.html.erb +0 -0
  717. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config.ru +0 -0
  718. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/application.rb +0 -0
  719. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/boot.rb +0 -0
  720. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/database.yml +0 -0
  721. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environment.rb +0 -0
  722. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/development.rb +0 -0
  723. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/production.rb +0 -0
  724. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/test.rb +0 -0
  725. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/backtrace_silencers.rb +0 -0
  726. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/inflections.rb +0 -0
  727. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/mime_types.rb +0 -0
  728. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/passenger.rb +0 -0
  729. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/secret_token.rb +0 -0
  730. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/session_store.rb +0 -0
  731. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/locales/en.yml +0 -0
  732. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/routes.rb +0 -0
  733. data/test/stub/{rails_apps/3.0/empty → rails3.0}/db/seeds.rb +0 -0
  734. data/test/stub/{rails_apps/3.0/empty → rails3.0}/doc/README_FOR_APP +0 -0
  735. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/404.html +0 -0
  736. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/422.html +0 -0
  737. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/500.html +0 -0
  738. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/favicon.ico +0 -0
  739. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/index.html +0 -0
  740. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/robots.txt +0 -0
  741. data/test/stub/{rails_apps/3.0/empty → rails3.0}/script/rails +0 -0
  742. data/test/stub/{rails_apps/3.0/empty → rails3.0}/test/performance/browsing_test.rb +0 -0
  743. data/test/stub/{rails_apps/3.0/empty → rails3.0}/test/test_helper.rb +0 -0
  744. data/test/stub/start_error.pl +24 -0
  745. data/test/stub/wsgi/passenger_wsgi.py +71 -3
  746. data/test/support/apache2_controller.rb +2 -2
  747. data/test/support/placebo-preloader.rb +88 -0
  748. data/test/support/test_helper.rb +1 -14
  749. data/test/tut/tut.h +11 -4
  750. metadata +590 -326
  751. data.tar.gz.asc +0 -12
  752. data/PACKAGING.TXT +0 -25
  753. data/build/config.rb +0 -46
  754. data/ext/apache2/HelperAgent.cpp +0 -364
  755. data/ext/boost/call_traits.hpp +0 -24
  756. data/ext/boost/detail/call_traits.hpp +0 -164
  757. data/ext/common/AbstractSpawnManager.h +0 -110
  758. data/ext/common/AgentBase.cpp +0 -432
  759. data/ext/common/ApplicationPool/Client.h +0 -788
  760. data/ext/common/ApplicationPool/Interface.h +0 -295
  761. data/ext/common/ApplicationPool/Pool.h +0 -1327
  762. data/ext/common/ApplicationPool/Server.h +0 -479
  763. data/ext/common/MessageChannel.h +0 -494
  764. data/ext/common/PoolOptions.h +0 -518
  765. data/ext/common/Process.h +0 -253
  766. data/ext/common/Session.h +0 -436
  767. data/ext/common/SpawnManager.h +0 -611
  768. data/ext/google/ChangeLog +0 -167
  769. data/ext/google/dense_hash_map +0 -310
  770. data/ext/google/dense_hash_set +0 -287
  771. data/ext/google/sparse_hash_map +0 -294
  772. data/ext/google/sparse_hash_set +0 -275
  773. data/ext/google/sparsehash/densehashtable.h +0 -1062
  774. data/ext/google/sparsehash/sparseconfig.h +0 -55
  775. data/ext/google/sparsehash/sparsehashtable.h +0 -1015
  776. data/ext/google/sparsetable +0 -1468
  777. data/ext/google/type_traits.h +0 -250
  778. data/ext/nginx/HelperAgent.cpp +0 -1355
  779. data/ext/nginx/ScgiRequestParser.h +0 -375
  780. data/ext/oxt/backtrace.cpp +0 -185
  781. data/ext/oxt/tracable_exception.cpp +0 -89
  782. data/helper-scripts/passenger-spawn-server +0 -106
  783. data/lib/phusion_passenger/abstract_request_handler.rb +0 -766
  784. data/lib/phusion_passenger/abstract_server.rb +0 -372
  785. data/lib/phusion_passenger/abstract_server_collection.rb +0 -335
  786. data/lib/phusion_passenger/app_process.rb +0 -174
  787. data/lib/phusion_passenger/classic_rails/application_spawner.rb +0 -344
  788. data/lib/phusion_passenger/classic_rails/framework_spawner.rb +0 -311
  789. data/lib/phusion_passenger/exceptions.rb +0 -103
  790. data/lib/phusion_passenger/html_template.rb +0 -107
  791. data/lib/phusion_passenger/rack/application_spawner.rb +0 -231
  792. data/lib/phusion_passenger/spawn_manager.rb +0 -359
  793. data/lib/phusion_passenger/templates/app_exited_during_initialization.html.erb +0 -38
  794. data/lib/phusion_passenger/templates/app_init_error.html.erb +0 -64
  795. data/lib/phusion_passenger/templates/database_error.html.erb +0 -66
  796. data/lib/phusion_passenger/templates/error_layout.html.erb +0 -39
  797. data/lib/phusion_passenger/templates/framework_init_error.html.erb +0 -39
  798. data/lib/phusion_passenger/templates/general_error.html.erb +0 -22
  799. data/lib/phusion_passenger/templates/load_error.html.erb +0 -46
  800. data/lib/phusion_passenger/templates/version_not_found.html.erb +0 -34
  801. data/lib/phusion_passenger/utils/rewindable_input.rb +0 -125
  802. data/lib/phusion_passenger/wsgi/application_spawner.rb +0 -108
  803. data/test/config.yml.example +0 -41
  804. data/test/cxx/ApplicationPool_PoolTest.cpp +0 -33
  805. data/test/cxx/ApplicationPool_PoolTestCases.cpp +0 -1029
  806. data/test/cxx/ApplicationPool_ServerTest.cpp +0 -308
  807. data/test/cxx/ApplicationPool_Server_PoolTest.cpp +0 -80
  808. data/test/cxx/MessageChannelTest.cpp +0 -557
  809. data/test/cxx/PoolOptionsTest.cpp +0 -116
  810. data/test/cxx/SpawnManagerTest.cpp +0 -161
  811. data/test/ruby/abstract_server_collection_spec.rb +0 -247
  812. data/test/ruby/abstract_server_spec.rb +0 -61
  813. data/test/ruby/app_process_spec.rb +0 -43
  814. data/test/ruby/classic_rails/application_spawner_spec.rb +0 -89
  815. data/test/ruby/classic_rails/framework_spawner_spec.rb +0 -92
  816. data/test/ruby/rack/application_spawner_spec.rb +0 -116
  817. data/test/ruby/shared/abstract_server_spec.rb +0 -23
  818. data/test/ruby/shared/spawners/classic_rails/framework_spawner_spec.rb +0 -38
  819. data/test/ruby/shared/spawners/classic_rails/lack_of_rails_gem_version_spec.rb +0 -19
  820. data/test/ruby/shared/spawners/classic_rails/spawner_spec.rb +0 -15
  821. data/test/ruby/shared/spawners/non_preloading_spawner_spec.rb +0 -27
  822. data/test/ruby/shared/spawners/preloading_spawner_spec.rb +0 -29
  823. data/test/ruby/shared/spawners/reload_all_spec.rb +0 -36
  824. data/test/ruby/shared/spawners/reload_single_spec.rb +0 -52
  825. data/test/ruby/shared/spawners/spawn_server_spec.rb +0 -28
  826. data/test/ruby/shared/spawners/spawner_spec.rb +0 -273
  827. data/test/ruby/shared/utils/pseudo_io_spec.rb +0 -60
  828. data/test/ruby/spawn_manager_spec.rb +0 -134
  829. data/test/ruby/wsgi/application_spawner_spec.rb +0 -50
  830. data/test/stub/message_channel.rb +0 -11
  831. data/test/stub/message_channel_2.rb +0 -12
  832. data/test/stub/message_channel_3.rb +0 -19
  833. data/test/stub/rails_apps/3.0/empty/Gemfile.lock +0 -73
  834. data/test/stub/spawn_server.rb +0 -22
  835. metadata.gz.asc +0 -12
@@ -1,19 +1,19 @@
1
1
  /*
2
2
  * libev simple C++ wrapper classes
3
3
  *
4
- * Copyright (c) 2007,2008 Marc Alexander Lehmann <libev@schmorp.de>
4
+ * Copyright (c) 2007,2008,2010 Marc Alexander Lehmann <libev@schmorp.de>
5
5
  * All rights reserved.
6
6
  *
7
7
  * Redistribution and use in source and binary forms, with or without modifica-
8
8
  * tion, are permitted provided that the following conditions are met:
9
- *
9
+ *
10
10
  * 1. Redistributions of source code must retain the above copyright notice,
11
11
  * this list of conditions and the following disclaimer.
12
- *
12
+ *
13
13
  * 2. Redistributions in binary form must reproduce the above copyright
14
14
  * notice, this list of conditions and the following disclaimer in the
15
15
  * documentation and/or other materials provided with the distribution.
16
- *
16
+ *
17
17
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18
18
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19
19
  * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
@@ -58,13 +58,15 @@ namespace ev {
58
58
 
59
59
  typedef ev_tstamp tstamp;
60
60
 
61
- enum
62
- {
61
+ enum {
63
62
  UNDEF = EV_UNDEF,
64
63
  NONE = EV_NONE,
65
64
  READ = EV_READ,
66
65
  WRITE = EV_WRITE,
66
+ #if EV_COMPAT3
67
67
  TIMEOUT = EV_TIMEOUT,
68
+ #endif
69
+ TIMER = EV_TIMER,
68
70
  PERIODIC = EV_PERIODIC,
69
71
  SIGNAL = EV_SIGNAL,
70
72
  CHILD = EV_CHILD,
@@ -76,7 +78,7 @@ namespace ev {
76
78
  ASYNC = EV_ASYNC,
77
79
  EMBED = EV_EMBED,
78
80
  # undef ERROR // some systems stupidly #define ERROR
79
- ERROR = EV_ERROR,
81
+ ERROR = EV_ERROR
80
82
  };
81
83
 
82
84
  enum
@@ -95,14 +97,18 @@ namespace ev {
95
97
 
96
98
  enum
97
99
  {
100
+ #if EV_COMPAT3
98
101
  NONBLOCK = EVLOOP_NONBLOCK,
99
- ONESHOT = EVLOOP_ONESHOT
102
+ ONESHOT = EVLOOP_ONESHOT,
103
+ #endif
104
+ NOWAIT = EVRUN_NOWAIT,
105
+ ONCE = EVRUN_ONCE
100
106
  };
101
107
 
102
108
  enum how_t
103
109
  {
104
- ONE = EVUNLOOP_ONE,
105
- ALL = EVUNLOOP_ALL
110
+ ONE = EVBREAK_ONE,
111
+ ALL = EVBREAK_ALL
106
112
  };
107
113
 
108
114
  struct bad_loop
@@ -188,23 +194,31 @@ namespace ev {
188
194
  }
189
195
  #endif
190
196
 
197
+ #if EV_COMPAT3
191
198
  void loop (int flags = 0)
192
199
  {
193
- ev_loop (EV_AX_ flags);
200
+ ev_run (EV_AX_ flags);
194
201
  }
195
202
 
196
203
  void unloop (how_t how = ONE) throw ()
197
204
  {
198
- ev_unloop (EV_AX_ how);
205
+ ev_break (EV_AX_ how);
206
+ }
207
+ #endif
208
+
209
+ void run (int flags = 0)
210
+ {
211
+ ev_run (EV_AX_ flags);
212
+ }
213
+
214
+ void break_loop (how_t how = ONE) throw ()
215
+ {
216
+ ev_break (EV_AX_ how);
199
217
  }
200
218
 
201
219
  void post_fork () throw ()
202
220
  {
203
- #if EV_MULTIPLICITY
204
221
  ev_loop_fork (EV_AX);
205
- #else
206
- ev_default_fork ();
207
- #endif
208
222
  }
209
223
 
210
224
  unsigned int backend () const throw ()
@@ -227,15 +241,15 @@ namespace ev {
227
241
  ev_unref (EV_AX);
228
242
  }
229
243
 
230
- #if EV_MINIMAL < 2
231
- unsigned int count () const throw ()
244
+ #if EV_FEATURE_API
245
+ unsigned int iteration () const throw ()
232
246
  {
233
- return ev_loop_count (EV_AX);
247
+ return ev_iteration (EV_AX);
234
248
  }
235
249
 
236
250
  unsigned int depth () const throw ()
237
251
  {
238
- return ev_loop_depth (EV_AX);
252
+ return ev_depth (EV_AX);
239
253
  }
240
254
 
241
255
  void set_io_collect_interval (tstamp interval) throw ()
@@ -377,11 +391,6 @@ namespace ev {
377
391
  throw bad_loop ();
378
392
  }
379
393
 
380
- ~default_loop () throw ()
381
- {
382
- ev_default_destroy ();
383
- }
384
-
385
394
  private:
386
395
  default_loop (const default_loop &);
387
396
  default_loop &operator = (const default_loop &);
@@ -415,6 +424,7 @@ namespace ev {
415
424
  #if EV_MULTIPLICITY
416
425
  EV_PX;
417
426
 
427
+ // loop set
418
428
  void set (EV_P) throw ()
419
429
  {
420
430
  this->EV_A = EV_A;
@@ -480,7 +490,7 @@ namespace ev {
480
490
  template<class K, void (K::*method)()>
481
491
  static void method_noargs_thunk (EV_P_ ev_watcher *w, int revents)
482
492
  {
483
- static_cast<K *>(w->data)->*method
493
+ (static_cast<K *>(w->data)->*method)
484
494
  ();
485
495
  }
486
496
 
@@ -507,9 +517,9 @@ namespace ev {
507
517
  }
508
518
  };
509
519
 
510
- inline tstamp now () throw ()
520
+ inline tstamp now (EV_P) throw ()
511
521
  {
512
- return ev_time ();
522
+ return ev_now (EV_A);
513
523
  }
514
524
 
515
525
  inline void delay (tstamp interval) throw ()
@@ -674,6 +684,7 @@ namespace ev {
674
684
  EV_END_WATCHER (periodic, periodic)
675
685
  #endif
676
686
 
687
+ #if EV_SIGNAL_ENABLE
677
688
  EV_BEGIN_WATCHER (sig, signal)
678
689
  void set (int signum) throw ()
679
690
  {
@@ -689,7 +700,9 @@ namespace ev {
689
700
  start ();
690
701
  }
691
702
  EV_END_WATCHER (sig, signal)
703
+ #endif
692
704
 
705
+ #if EV_CHILD_ENABLE
693
706
  EV_BEGIN_WATCHER (child, child)
694
707
  void set (int pid, int trace = 0) throw ()
695
708
  {
@@ -705,6 +718,7 @@ namespace ev {
705
718
  start ();
706
719
  }
707
720
  EV_END_WATCHER (child, child)
721
+ #endif
708
722
 
709
723
  #if EV_STAT_ENABLE
710
724
  EV_BEGIN_WATCHER (stat, stat)
@@ -730,19 +744,23 @@ namespace ev {
730
744
  EV_END_WATCHER (stat, stat)
731
745
  #endif
732
746
 
733
- #if EV_IDLE_ENABLE
747
+ #if EV_IDLE_ENABLE
734
748
  EV_BEGIN_WATCHER (idle, idle)
735
749
  void set () throw () { }
736
750
  EV_END_WATCHER (idle, idle)
737
- #endif
751
+ #endif
738
752
 
753
+ #if EV_PREPARE_ENABLE
739
754
  EV_BEGIN_WATCHER (prepare, prepare)
740
755
  void set () throw () { }
741
756
  EV_END_WATCHER (prepare, prepare)
757
+ #endif
742
758
 
759
+ #if EV_CHECK_ENABLE
743
760
  EV_BEGIN_WATCHER (check, check)
744
761
  void set () throw () { }
745
762
  EV_END_WATCHER (check, check)
763
+ #endif
746
764
 
747
765
  #if EV_EMBED_ENABLE
748
766
  EV_BEGIN_WATCHER (embed, embed)
@@ -775,8 +793,6 @@ namespace ev {
775
793
 
776
794
  #if EV_ASYNC_ENABLE
777
795
  EV_BEGIN_WATCHER (async, async)
778
- void set () throw () { }
779
-
780
796
  void send () throw ()
781
797
  {
782
798
  ev_async_send (EV_A_ static_cast<ev_async *>(this));
@@ -1,19 +1,19 @@
1
1
  /*
2
2
  * libev event processing core, watcher management
3
3
  *
4
- * Copyright (c) 2007,2008,2009 Marc Alexander Lehmann <libev@schmorp.de>
4
+ * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
5
5
  * All rights reserved.
6
6
  *
7
7
  * Redistribution and use in source and binary forms, with or without modifica-
8
8
  * tion, are permitted provided that the following conditions are met:
9
- *
9
+ *
10
10
  * 1. Redistributions of source code must retain the above copyright notice,
11
11
  * this list of conditions and the following disclaimer.
12
- *
12
+ *
13
13
  * 2. Redistributions in binary form must reproduce the above copyright
14
14
  * notice, this list of conditions and the following disclaimer in the
15
15
  * documentation and/or other materials provided with the distribution.
16
- *
16
+ *
17
17
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18
18
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19
19
  * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
@@ -37,10 +37,6 @@
37
37
  * either the BSD or the GPL.
38
38
  */
39
39
 
40
- #ifdef __cplusplus
41
- extern "C" {
42
- #endif
43
-
44
40
  /* this big block deduces configuration from config.h */
45
41
  #ifndef EV_STANDALONE
46
42
  # ifdef EV_CONFIG_H
@@ -49,6 +45,12 @@ extern "C" {
49
45
  # include "config.h"
50
46
  # endif
51
47
 
48
+ #if HAVE_FLOOR
49
+ # ifndef EV_USE_FLOOR
50
+ # define EV_USE_FLOOR 1
51
+ # endif
52
+ #endif
53
+
52
54
  # if HAVE_CLOCK_SYSCALL
53
55
  # ifndef EV_USE_CLOCK_SYSCALL
54
56
  # define EV_USE_CLOCK_SYSCALL 1
@@ -79,81 +81,89 @@ extern "C" {
79
81
  # endif
80
82
  # endif
81
83
 
82
- # ifndef EV_USE_NANOSLEEP
83
- # if HAVE_NANOSLEEP
84
- # define EV_USE_NANOSLEEP 1
85
- # else
86
- # define EV_USE_NANOSLEEP 0
84
+ # if HAVE_NANOSLEEP
85
+ # ifndef EV_USE_NANOSLEEP
86
+ # define EV_USE_NANOSLEEP EV_FEATURE_OS
87
87
  # endif
88
+ # else
89
+ # undef EV_USE_NANOSLEEP
90
+ # define EV_USE_NANOSLEEP 0
88
91
  # endif
89
92
 
90
- # ifndef EV_USE_SELECT
91
- # if HAVE_SELECT && HAVE_SYS_SELECT_H
92
- # define EV_USE_SELECT 1
93
- # else
94
- # define EV_USE_SELECT 0
93
+ # if HAVE_SELECT && HAVE_SYS_SELECT_H
94
+ # ifndef EV_USE_SELECT
95
+ # define EV_USE_SELECT EV_FEATURE_BACKENDS
95
96
  # endif
97
+ # else
98
+ # undef EV_USE_SELECT
99
+ # define EV_USE_SELECT 0
96
100
  # endif
97
101
 
98
- # ifndef EV_USE_POLL
99
- # if HAVE_POLL && HAVE_POLL_H
100
- # define EV_USE_POLL 1
101
- # else
102
- # define EV_USE_POLL 0
102
+ # if HAVE_POLL && HAVE_POLL_H
103
+ # ifndef EV_USE_POLL
104
+ # define EV_USE_POLL EV_FEATURE_BACKENDS
103
105
  # endif
106
+ # else
107
+ # undef EV_USE_POLL
108
+ # define EV_USE_POLL 0
104
109
  # endif
105
110
 
106
- # ifndef EV_USE_EPOLL
107
- # if HAVE_EPOLL_CTL && HAVE_SYS_EPOLL_H
108
- # define EV_USE_EPOLL 1
109
- # else
110
- # define EV_USE_EPOLL 0
111
+ # if HAVE_EPOLL_CTL && HAVE_SYS_EPOLL_H
112
+ # ifndef EV_USE_EPOLL
113
+ # define EV_USE_EPOLL EV_FEATURE_BACKENDS
111
114
  # endif
115
+ # else
116
+ # undef EV_USE_EPOLL
117
+ # define EV_USE_EPOLL 0
112
118
  # endif
113
119
 
114
- # ifndef EV_USE_KQUEUE
115
- # if HAVE_KQUEUE && HAVE_SYS_EVENT_H && HAVE_SYS_QUEUE_H
116
- # define EV_USE_KQUEUE 1
117
- # else
118
- # define EV_USE_KQUEUE 0
120
+ # if HAVE_KQUEUE && HAVE_SYS_EVENT_H
121
+ # ifndef EV_USE_KQUEUE
122
+ # define EV_USE_KQUEUE EV_FEATURE_BACKENDS
119
123
  # endif
124
+ # else
125
+ # undef EV_USE_KQUEUE
126
+ # define EV_USE_KQUEUE 0
120
127
  # endif
121
128
 
122
- # ifndef EV_USE_PORT
123
- # if HAVE_PORT_H && HAVE_PORT_CREATE
124
- # define EV_USE_PORT 1
125
- # else
126
- # define EV_USE_PORT 0
129
+ # if HAVE_PORT_H && HAVE_PORT_CREATE
130
+ # ifndef EV_USE_PORT
131
+ # define EV_USE_PORT EV_FEATURE_BACKENDS
127
132
  # endif
133
+ # else
134
+ # undef EV_USE_PORT
135
+ # define EV_USE_PORT 0
128
136
  # endif
129
137
 
130
- # ifndef EV_USE_INOTIFY
131
- # if HAVE_INOTIFY_INIT && HAVE_SYS_INOTIFY_H
132
- # define EV_USE_INOTIFY 1
133
- # else
134
- # define EV_USE_INOTIFY 0
138
+ # if HAVE_INOTIFY_INIT && HAVE_SYS_INOTIFY_H
139
+ # ifndef EV_USE_INOTIFY
140
+ # define EV_USE_INOTIFY EV_FEATURE_OS
135
141
  # endif
142
+ # else
143
+ # undef EV_USE_INOTIFY
144
+ # define EV_USE_INOTIFY 0
136
145
  # endif
137
146
 
138
- # ifndef EV_USE_SIGNALFD
139
- # if HAVE_SIGNALFD && HAVE_SYS_SIGNALFD_H
140
- # define EV_USE_SIGNALFD 1
141
- # else
142
- # define EV_USE_SIGNALFD 0
147
+ # if HAVE_SIGNALFD && HAVE_SYS_SIGNALFD_H
148
+ # ifndef EV_USE_SIGNALFD
149
+ # define EV_USE_SIGNALFD EV_FEATURE_OS
143
150
  # endif
151
+ # else
152
+ # undef EV_USE_SIGNALFD
153
+ # define EV_USE_SIGNALFD 0
144
154
  # endif
145
155
 
146
- # ifndef EV_USE_EVENTFD
147
- # if HAVE_EVENTFD
148
- # define EV_USE_EVENTFD 1
149
- # else
150
- # define EV_USE_EVENTFD 0
156
+ # if HAVE_EVENTFD
157
+ # ifndef EV_USE_EVENTFD
158
+ # define EV_USE_EVENTFD EV_FEATURE_OS
151
159
  # endif
160
+ # else
161
+ # undef EV_USE_EVENTFD
162
+ # define EV_USE_EVENTFD 0
152
163
  # endif
153
164
 
154
165
  #endif
155
166
 
156
- #include <math.h>
157
167
  #include <stdlib.h>
158
168
  #include <string.h>
159
169
  #include <fcntl.h>
@@ -165,6 +175,7 @@ extern "C" {
165
175
  #include <errno.h>
166
176
  #include <sys/types.h>
167
177
  #include <time.h>
178
+ #include <limits.h>
168
179
 
169
180
  #include <signal.h>
170
181
 
@@ -174,6 +185,17 @@ extern "C" {
174
185
  # include "ev.h"
175
186
  #endif
176
187
 
188
+ #if EV_NO_THREADS
189
+ # undef EV_NO_SMP
190
+ # define EV_NO_SMP 1
191
+ # undef ECB_NO_THREADS
192
+ # define ECB_NO_THREADS 1
193
+ #endif
194
+ #if EV_NO_SMP
195
+ # undef EV_NO_SMP
196
+ # define ECB_NO_SMP 1
197
+ #endif
198
+
177
199
  #ifndef _WIN32
178
200
  # include <sys/time.h>
179
201
  # include <sys/wait.h>
@@ -185,8 +207,17 @@ extern "C" {
185
207
  # ifndef EV_SELECT_IS_WINSOCKET
186
208
  # define EV_SELECT_IS_WINSOCKET 1
187
209
  # endif
210
+ # undef EV_AVOID_STDIO
188
211
  #endif
189
212
 
213
+ /* OS X, in its infinite idiocy, actually HARDCODES
214
+ * a limit of 1024 into their select. Where people have brains,
215
+ * OS X engineers apparently have a vacuum. Or maybe they were
216
+ * ordered to have a vacuum, or they do anything for money.
217
+ * This might help. Or not.
218
+ */
219
+ #define _DARWIN_UNLIMITED_SELECT 1
220
+
190
221
  /* this block tries to deduce configuration from header-defined symbols and defaults */
191
222
 
192
223
  /* try to deduce the maximum number of signals on this platform */
@@ -207,18 +238,23 @@ extern "C" {
207
238
  #elif defined (MAX_SIG)
208
239
  # define EV_NSIG (MAX_SIG+1)
209
240
  #elif defined (SIGARRAYSIZE)
210
- # define EV_NSIG SIGARRAYSIZE /* Assume ary[SIGARRAYSIZE] */
241
+ # define EV_NSIG (SIGARRAYSIZE) /* Assume ary[SIGARRAYSIZE] */
211
242
  #elif defined (_sys_nsig)
212
243
  # define EV_NSIG (_sys_nsig) /* Solaris 2.5 */
213
244
  #else
214
245
  # error "unable to find value for NSIG, please report"
215
- /* to make it compile regardless, just remove the above line */
246
+ /* to make it compile regardless, just remove the above line, */
247
+ /* but consider reporting it, too! :) */
216
248
  # define EV_NSIG 65
217
249
  #endif
218
250
 
251
+ #ifndef EV_USE_FLOOR
252
+ # define EV_USE_FLOOR 0
253
+ #endif
254
+
219
255
  #ifndef EV_USE_CLOCK_SYSCALL
220
256
  # if __linux && __GLIBC__ >= 2
221
- # define EV_USE_CLOCK_SYSCALL 1
257
+ # define EV_USE_CLOCK_SYSCALL EV_FEATURE_OS
222
258
  # else
223
259
  # define EV_USE_CLOCK_SYSCALL 0
224
260
  # endif
@@ -226,7 +262,7 @@ extern "C" {
226
262
 
227
263
  #ifndef EV_USE_MONOTONIC
228
264
  # if defined (_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
229
- # define EV_USE_MONOTONIC 1
265
+ # define EV_USE_MONOTONIC EV_FEATURE_OS
230
266
  # else
231
267
  # define EV_USE_MONOTONIC 0
232
268
  # endif
@@ -238,27 +274,27 @@ extern "C" {
238
274
 
239
275
  #ifndef EV_USE_NANOSLEEP
240
276
  # if _POSIX_C_SOURCE >= 199309L
241
- # define EV_USE_NANOSLEEP 1
277
+ # define EV_USE_NANOSLEEP EV_FEATURE_OS
242
278
  # else
243
279
  # define EV_USE_NANOSLEEP 0
244
280
  # endif
245
281
  #endif
246
282
 
247
283
  #ifndef EV_USE_SELECT
248
- # define EV_USE_SELECT 1
284
+ # define EV_USE_SELECT EV_FEATURE_BACKENDS
249
285
  #endif
250
286
 
251
287
  #ifndef EV_USE_POLL
252
288
  # ifdef _WIN32
253
289
  # define EV_USE_POLL 0
254
290
  # else
255
- # define EV_USE_POLL 1
291
+ # define EV_USE_POLL EV_FEATURE_BACKENDS
256
292
  # endif
257
293
  #endif
258
294
 
259
295
  #ifndef EV_USE_EPOLL
260
296
  # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4))
261
- # define EV_USE_EPOLL 1
297
+ # define EV_USE_EPOLL EV_FEATURE_BACKENDS
262
298
  # else
263
299
  # define EV_USE_EPOLL 0
264
300
  # endif
@@ -274,31 +310,23 @@ extern "C" {
274
310
 
275
311
  #ifndef EV_USE_INOTIFY
276
312
  # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4))
277
- # define EV_USE_INOTIFY 1
313
+ # define EV_USE_INOTIFY EV_FEATURE_OS
278
314
  # else
279
315
  # define EV_USE_INOTIFY 0
280
316
  # endif
281
317
  #endif
282
318
 
283
319
  #ifndef EV_PID_HASHSIZE
284
- # if EV_MINIMAL
285
- # define EV_PID_HASHSIZE 1
286
- # else
287
- # define EV_PID_HASHSIZE 16
288
- # endif
320
+ # define EV_PID_HASHSIZE EV_FEATURE_DATA ? 16 : 1
289
321
  #endif
290
322
 
291
323
  #ifndef EV_INOTIFY_HASHSIZE
292
- # if EV_MINIMAL
293
- # define EV_INOTIFY_HASHSIZE 1
294
- # else
295
- # define EV_INOTIFY_HASHSIZE 16
296
- # endif
324
+ # define EV_INOTIFY_HASHSIZE EV_FEATURE_DATA ? 16 : 1
297
325
  #endif
298
326
 
299
327
  #ifndef EV_USE_EVENTFD
300
328
  # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))
301
- # define EV_USE_EVENTFD 1
329
+ # define EV_USE_EVENTFD EV_FEATURE_OS
302
330
  # else
303
331
  # define EV_USE_EVENTFD 0
304
332
  # endif
@@ -306,7 +334,7 @@ extern "C" {
306
334
 
307
335
  #ifndef EV_USE_SIGNALFD
308
336
  # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))
309
- # define EV_USE_SIGNALFD 1
337
+ # define EV_USE_SIGNALFD EV_FEATURE_OS
310
338
  # else
311
339
  # define EV_USE_SIGNALFD 0
312
340
  # endif
@@ -319,15 +347,15 @@ extern "C" {
319
347
  #endif
320
348
 
321
349
  #ifndef EV_VERIFY
322
- # define EV_VERIFY !EV_MINIMAL
350
+ # define EV_VERIFY (EV_FEATURE_API ? 1 : 0)
323
351
  #endif
324
352
 
325
353
  #ifndef EV_USE_4HEAP
326
- # define EV_USE_4HEAP !EV_MINIMAL
354
+ # define EV_USE_4HEAP EV_FEATURE_DATA
327
355
  #endif
328
356
 
329
357
  #ifndef EV_HEAP_CACHE_AT
330
- # define EV_HEAP_CACHE_AT !EV_MINIMAL
358
+ # define EV_HEAP_CACHE_AT EV_FEATURE_DATA
331
359
  #endif
332
360
 
333
361
  /* on linux, we can use a (slow) syscall to avoid a dependency on pthread, */
@@ -346,6 +374,12 @@ extern "C" {
346
374
 
347
375
  /* this block fixes any misconfiguration where we know we run into trouble otherwise */
348
376
 
377
+ #ifdef _AIX
378
+ /* AIX has a completely broken poll.h header */
379
+ # undef EV_USE_POLL
380
+ # define EV_USE_POLL 0
381
+ #endif
382
+
349
383
  #ifndef CLOCK_MONOTONIC
350
384
  # undef EV_USE_MONOTONIC
351
385
  # define EV_USE_MONOTONIC 0
@@ -362,13 +396,13 @@ extern "C" {
362
396
  #endif
363
397
 
364
398
  #if !EV_USE_NANOSLEEP
365
- # ifndef _WIN32
399
+ /* hp-ux has it in sys/time.h, which we unconditionally include above */
400
+ # if !defined(_WIN32) && !defined(__hpux)
366
401
  # include <sys/select.h>
367
402
  # endif
368
403
  #endif
369
404
 
370
405
  #if EV_USE_INOTIFY
371
- # include <sys/utsname.h>
372
406
  # include <sys/statfs.h>
373
407
  # include <sys/inotify.h>
374
408
  /* some very old inotify.h headers don't have IN_DONT_FOLLOW */
@@ -395,13 +429,7 @@ extern "C" {
395
429
  # define EFD_CLOEXEC 02000000
396
430
  # endif
397
431
  # endif
398
- # ifdef __cplusplus
399
- extern "C" {
400
- # endif
401
- int eventfd (unsigned int initval, int flags);
402
- # ifdef __cplusplus
403
- }
404
- # endif
432
+ EV_CPP(extern "C") int (eventfd) (unsigned int initval, int flags);
405
433
  #endif
406
434
 
407
435
  #if EV_USE_SIGNALFD
@@ -417,62 +445,518 @@ int eventfd (unsigned int initval, int flags);
417
445
  # define SFD_CLOEXEC 02000000
418
446
  # endif
419
447
  # endif
420
- # ifdef __cplusplus
421
- extern "C" {
422
- # endif
423
- int signalfd (int fd, const sigset_t *mask, int flags);
448
+ EV_CPP (extern "C") int signalfd (int fd, const sigset_t *mask, int flags);
424
449
 
425
450
  struct signalfd_siginfo
426
451
  {
427
452
  uint32_t ssi_signo;
428
453
  char pad[128 - sizeof (uint32_t)];
429
454
  };
430
- # ifdef __cplusplus
431
- }
432
- # endif
433
455
  #endif
434
456
 
435
-
436
457
  /**/
437
458
 
438
459
  #if EV_VERIFY >= 3
439
- # define EV_FREQUENT_CHECK ev_loop_verify (EV_A)
460
+ # define EV_FREQUENT_CHECK ev_verify (EV_A)
440
461
  #else
441
462
  # define EV_FREQUENT_CHECK do { } while (0)
442
463
  #endif
443
464
 
444
465
  /*
445
- * This is used to avoid floating point rounding problems.
446
- * It is added to ev_rt_now when scheduling periodics
447
- * to ensure progress, time-wise, even when rounding
448
- * errors are against us.
466
+ * This is used to work around floating point rounding problems.
449
467
  * This value is good at least till the year 4000.
450
- * Better solutions welcome.
451
468
  */
452
- #define TIME_EPSILON 0.0001220703125 /* 1/8192 */
469
+ #define MIN_INTERVAL 0.0001220703125 /* 1/2**13, good till 4000 */
470
+ /*#define MIN_INTERVAL 0.00000095367431640625 /* 1/2**20, good till 2200 */
453
471
 
454
472
  #define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */
455
473
  #define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */
456
474
 
457
- #if __GNUC__ >= 4
458
- # define expect(expr,value) __builtin_expect ((expr),(value))
459
- # define noinline __attribute__ ((noinline))
475
+ #define EV_TV_SET(tv,t) do { tv.tv_sec = (long)t; tv.tv_usec = (long)((t - tv.tv_sec) * 1e6); } while (0)
476
+ #define EV_TS_SET(ts,t) do { ts.tv_sec = (long)t; ts.tv_nsec = (long)((t - ts.tv_sec) * 1e9); } while (0)
477
+
478
+ /* the following is ecb.h embedded into libev - use update_ev_c to update from an external copy */
479
+ /* ECB.H BEGIN */
480
+ /*
481
+ * libecb - http://software.schmorp.de/pkg/libecb
482
+ *
483
+ * Copyright (©) 2009-2012 Marc Alexander Lehmann <libecb@schmorp.de>
484
+ * Copyright (©) 2011 Emanuele Giaquinta
485
+ * All rights reserved.
486
+ *
487
+ * Redistribution and use in source and binary forms, with or without modifica-
488
+ * tion, are permitted provided that the following conditions are met:
489
+ *
490
+ * 1. Redistributions of source code must retain the above copyright notice,
491
+ * this list of conditions and the following disclaimer.
492
+ *
493
+ * 2. Redistributions in binary form must reproduce the above copyright
494
+ * notice, this list of conditions and the following disclaimer in the
495
+ * documentation and/or other materials provided with the distribution.
496
+ *
497
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
498
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
499
+ * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
500
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
501
+ * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
502
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
503
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
504
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
505
+ * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
506
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
507
+ */
508
+
509
+ #ifndef ECB_H
510
+ #define ECB_H
511
+
512
+ #ifdef _WIN32
513
+ typedef signed char int8_t;
514
+ typedef unsigned char uint8_t;
515
+ typedef signed short int16_t;
516
+ typedef unsigned short uint16_t;
517
+ typedef signed int int32_t;
518
+ typedef unsigned int uint32_t;
519
+ #if __GNUC__
520
+ typedef signed long long int64_t;
521
+ typedef unsigned long long uint64_t;
522
+ #else /* _MSC_VER || __BORLANDC__ */
523
+ typedef signed __int64 int64_t;
524
+ typedef unsigned __int64 uint64_t;
525
+ #endif
460
526
  #else
461
- # define expect(expr,value) (expr)
462
- # define noinline
463
- # if __STDC_VERSION__ < 199901L && __GNUC__ < 2
464
- # define inline
465
- # endif
527
+ #include <inttypes.h>
466
528
  #endif
467
529
 
468
- #define expect_false(expr) expect ((expr) != 0, 0)
469
- #define expect_true(expr) expect ((expr) != 0, 1)
470
- #define inline_size static inline
530
+ /* many compilers define _GNUC_ to some versions but then only implement
531
+ * what their idiot authors think are the "more important" extensions,
532
+ * causing enormous grief in return for some better fake benchmark numbers.
533
+ * or so.
534
+ * we try to detect these and simply assume they are not gcc - if they have
535
+ * an issue with that they should have done it right in the first place.
536
+ */
537
+ #ifndef ECB_GCC_VERSION
538
+ #if !defined(__GNUC_MINOR__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__llvm__) || defined(__clang__)
539
+ #define ECB_GCC_VERSION(major,minor) 0
540
+ #else
541
+ #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
542
+ #endif
543
+ #endif
471
544
 
472
- #if EV_MINIMAL
473
- # define inline_speed static noinline
545
+ /*****************************************************************************/
546
+
547
+ /* ECB_NO_THREADS - ecb is not used by multiple threads, ever */
548
+ /* ECB_NO_SMP - ecb might be used in multiple threads, but only on a single cpu */
549
+
550
+ #if ECB_NO_THREADS
551
+ # define ECB_NO_SMP 1
552
+ #endif
553
+
554
+ #if ECB_NO_THREADS || ECB_NO_SMP
555
+ #define ECB_MEMORY_FENCE do { } while (0)
556
+ #endif
557
+
558
+ #ifndef ECB_MEMORY_FENCE
559
+ #if ECB_GCC_VERSION(2,5) || defined(__INTEL_COMPILER) || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
560
+ #if __i386 || __i386__
561
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory")
562
+ #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE /* non-lock xchg might be enough */
563
+ #define ECB_MEMORY_FENCE_RELEASE do { } while (0) /* unlikely to change in future cpus */
564
+ #elif __amd64 || __amd64__ || __x86_64 || __x86_64__
565
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mfence" : : : "memory")
566
+ #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("lfence" : : : "memory")
567
+ #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("sfence") /* play safe - not needed in any current cpu */
568
+ #elif __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__
569
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory")
570
+ #elif defined(__ARM_ARCH_6__ ) || defined(__ARM_ARCH_6J__ ) \
571
+ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__)
572
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mcr p15,0,%0,c7,c10,5" : : "r" (0) : "memory")
573
+ #elif defined(__ARM_ARCH_7__ ) || defined(__ARM_ARCH_7A__ ) \
574
+ || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7R__ )
575
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb" : : : "memory")
576
+ #elif __sparc || __sparc__
577
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad | #StoreStore | #StoreLoad | " : : : "memory")
578
+ #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad" : : : "memory")
579
+ #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("membar #LoadStore | #StoreStore")
580
+ #elif defined(__s390__) || defined(__s390x__)
581
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("bcr 15,0" : : : "memory")
582
+ #endif
583
+ #endif
584
+ #endif
585
+
586
+ #ifndef ECB_MEMORY_FENCE
587
+ #if ECB_GCC_VERSION(4,4) || defined(__INTEL_COMPILER) || defined(__clang__)
588
+ #define ECB_MEMORY_FENCE __sync_synchronize ()
589
+ /*#define ECB_MEMORY_FENCE_ACQUIRE ({ char dummy = 0; __sync_lock_test_and_set (&dummy, 1); }) */
590
+ /*#define ECB_MEMORY_FENCE_RELEASE ({ char dummy = 1; __sync_lock_release (&dummy ); }) */
591
+ #elif _MSC_VER >= 1400 /* VC++ 2005 */
592
+ #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
593
+ #define ECB_MEMORY_FENCE _ReadWriteBarrier ()
594
+ #define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier () /* according to msdn, _ReadBarrier is not a load fence */
595
+ #define ECB_MEMORY_FENCE_RELEASE _WriteBarrier ()
596
+ #elif defined(_WIN32)
597
+ #include <WinNT.h>
598
+ #define ECB_MEMORY_FENCE MemoryBarrier () /* actually just xchg on x86... scary */
599
+ #elif __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
600
+ #include <mbarrier.h>
601
+ #define ECB_MEMORY_FENCE __machine_rw_barrier ()
602
+ #define ECB_MEMORY_FENCE_ACQUIRE __machine_r_barrier ()
603
+ #define ECB_MEMORY_FENCE_RELEASE __machine_w_barrier ()
604
+ #endif
605
+ #endif
606
+
607
+ #ifndef ECB_MEMORY_FENCE
608
+ #if !ECB_AVOID_PTHREADS
609
+ /*
610
+ * if you get undefined symbol references to pthread_mutex_lock,
611
+ * or failure to find pthread.h, then you should implement
612
+ * the ECB_MEMORY_FENCE operations for your cpu/compiler
613
+ * OR provide pthread.h and link against the posix thread library
614
+ * of your system.
615
+ */
616
+ #include <pthread.h>
617
+ #define ECB_NEEDS_PTHREADS 1
618
+ #define ECB_MEMORY_FENCE_NEEDS_PTHREADS 1
619
+
620
+ static pthread_mutex_t ecb_mf_lock = PTHREAD_MUTEX_INITIALIZER;
621
+ #define ECB_MEMORY_FENCE do { pthread_mutex_lock (&ecb_mf_lock); pthread_mutex_unlock (&ecb_mf_lock); } while (0)
622
+ #endif
623
+ #endif
624
+
625
+ #if !defined(ECB_MEMORY_FENCE_ACQUIRE) && defined(ECB_MEMORY_FENCE)
626
+ #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
627
+ #endif
628
+
629
+ #if !defined(ECB_MEMORY_FENCE_RELEASE) && defined(ECB_MEMORY_FENCE)
630
+ #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
631
+ #endif
632
+
633
+ /*****************************************************************************/
634
+
635
+ #define ECB_C99 (__STDC_VERSION__ >= 199901L)
636
+
637
+ #if __cplusplus
638
+ #define ecb_inline static inline
639
+ #elif ECB_GCC_VERSION(2,5)
640
+ #define ecb_inline static __inline__
641
+ #elif ECB_C99
642
+ #define ecb_inline static inline
643
+ #else
644
+ #define ecb_inline static
645
+ #endif
646
+
647
+ #if ECB_GCC_VERSION(3,3)
648
+ #define ecb_restrict __restrict__
649
+ #elif ECB_C99
650
+ #define ecb_restrict restrict
651
+ #else
652
+ #define ecb_restrict
653
+ #endif
654
+
655
+ typedef int ecb_bool;
656
+
657
+ #define ECB_CONCAT_(a, b) a ## b
658
+ #define ECB_CONCAT(a, b) ECB_CONCAT_(a, b)
659
+ #define ECB_STRINGIFY_(a) # a
660
+ #define ECB_STRINGIFY(a) ECB_STRINGIFY_(a)
661
+
662
+ #define ecb_function_ ecb_inline
663
+
664
+ #if ECB_GCC_VERSION(3,1)
665
+ #define ecb_attribute(attrlist) __attribute__(attrlist)
666
+ #define ecb_is_constant(expr) __builtin_constant_p (expr)
667
+ #define ecb_expect(expr,value) __builtin_expect ((expr),(value))
668
+ #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality)
669
+ #else
670
+ #define ecb_attribute(attrlist)
671
+ #define ecb_is_constant(expr) 0
672
+ #define ecb_expect(expr,value) (expr)
673
+ #define ecb_prefetch(addr,rw,locality)
674
+ #endif
675
+
676
+ /* no emulation for ecb_decltype */
677
+ #if ECB_GCC_VERSION(4,5)
678
+ #define ecb_decltype(x) __decltype(x)
679
+ #elif ECB_GCC_VERSION(3,0)
680
+ #define ecb_decltype(x) __typeof(x)
681
+ #endif
682
+
683
+ #define ecb_noinline ecb_attribute ((__noinline__))
684
+ #define ecb_noreturn ecb_attribute ((__noreturn__))
685
+ #define ecb_unused ecb_attribute ((__unused__))
686
+ #define ecb_const ecb_attribute ((__const__))
687
+ #define ecb_pure ecb_attribute ((__pure__))
688
+
689
+ #if ECB_GCC_VERSION(4,3)
690
+ #define ecb_artificial ecb_attribute ((__artificial__))
691
+ #define ecb_hot ecb_attribute ((__hot__))
692
+ #define ecb_cold ecb_attribute ((__cold__))
693
+ #else
694
+ #define ecb_artificial
695
+ #define ecb_hot
696
+ #define ecb_cold
697
+ #endif
698
+
699
+ /* put around conditional expressions if you are very sure that the */
700
+ /* expression is mostly true or mostly false. note that these return */
701
+ /* booleans, not the expression. */
702
+ #define ecb_expect_false(expr) ecb_expect (!!(expr), 0)
703
+ #define ecb_expect_true(expr) ecb_expect (!!(expr), 1)
704
+ /* for compatibility to the rest of the world */
705
+ #define ecb_likely(expr) ecb_expect_true (expr)
706
+ #define ecb_unlikely(expr) ecb_expect_false (expr)
707
+
708
+ /* count trailing zero bits and count # of one bits */
709
+ #if ECB_GCC_VERSION(3,4)
710
+ /* we assume int == 32 bit, long == 32 or 64 bit and long long == 64 bit */
711
+ #define ecb_ld32(x) (__builtin_clz (x) ^ 31)
712
+ #define ecb_ld64(x) (__builtin_clzll (x) ^ 63)
713
+ #define ecb_ctz32(x) __builtin_ctz (x)
714
+ #define ecb_ctz64(x) __builtin_ctzll (x)
715
+ #define ecb_popcount32(x) __builtin_popcount (x)
716
+ /* no popcountll */
717
+ #else
718
+ ecb_function_ int ecb_ctz32 (uint32_t x) ecb_const;
719
+ ecb_function_ int
720
+ ecb_ctz32 (uint32_t x)
721
+ {
722
+ int r = 0;
723
+
724
+ x &= ~x + 1; /* this isolates the lowest bit */
725
+
726
+ #if ECB_branchless_on_i386
727
+ r += !!(x & 0xaaaaaaaa) << 0;
728
+ r += !!(x & 0xcccccccc) << 1;
729
+ r += !!(x & 0xf0f0f0f0) << 2;
730
+ r += !!(x & 0xff00ff00) << 3;
731
+ r += !!(x & 0xffff0000) << 4;
732
+ #else
733
+ if (x & 0xaaaaaaaa) r += 1;
734
+ if (x & 0xcccccccc) r += 2;
735
+ if (x & 0xf0f0f0f0) r += 4;
736
+ if (x & 0xff00ff00) r += 8;
737
+ if (x & 0xffff0000) r += 16;
738
+ #endif
739
+
740
+ return r;
741
+ }
742
+
743
+ ecb_function_ int ecb_ctz64 (uint64_t x) ecb_const;
744
+ ecb_function_ int
745
+ ecb_ctz64 (uint64_t x)
746
+ {
747
+ int shift = x & 0xffffffffU ? 0 : 32;
748
+ return ecb_ctz32 (x >> shift) + shift;
749
+ }
750
+
751
+ ecb_function_ int ecb_popcount32 (uint32_t x) ecb_const;
752
+ ecb_function_ int
753
+ ecb_popcount32 (uint32_t x)
754
+ {
755
+ x -= (x >> 1) & 0x55555555;
756
+ x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
757
+ x = ((x >> 4) + x) & 0x0f0f0f0f;
758
+ x *= 0x01010101;
759
+
760
+ return x >> 24;
761
+ }
762
+
763
+ ecb_function_ int ecb_ld32 (uint32_t x) ecb_const;
764
+ ecb_function_ int ecb_ld32 (uint32_t x)
765
+ {
766
+ int r = 0;
767
+
768
+ if (x >> 16) { x >>= 16; r += 16; }
769
+ if (x >> 8) { x >>= 8; r += 8; }
770
+ if (x >> 4) { x >>= 4; r += 4; }
771
+ if (x >> 2) { x >>= 2; r += 2; }
772
+ if (x >> 1) { r += 1; }
773
+
774
+ return r;
775
+ }
776
+
777
+ ecb_function_ int ecb_ld64 (uint64_t x) ecb_const;
778
+ ecb_function_ int ecb_ld64 (uint64_t x)
779
+ {
780
+ int r = 0;
781
+
782
+ if (x >> 32) { x >>= 32; r += 32; }
783
+
784
+ return r + ecb_ld32 (x);
785
+ }
786
+ #endif
787
+
788
+ ecb_function_ uint8_t ecb_bitrev8 (uint8_t x) ecb_const;
789
+ ecb_function_ uint8_t ecb_bitrev8 (uint8_t x)
790
+ {
791
+ return ( (x * 0x0802U & 0x22110U)
792
+ | (x * 0x8020U & 0x88440U)) * 0x10101U >> 16;
793
+ }
794
+
795
+ ecb_function_ uint16_t ecb_bitrev16 (uint16_t x) ecb_const;
796
+ ecb_function_ uint16_t ecb_bitrev16 (uint16_t x)
797
+ {
798
+ x = ((x >> 1) & 0x5555) | ((x & 0x5555) << 1);
799
+ x = ((x >> 2) & 0x3333) | ((x & 0x3333) << 2);
800
+ x = ((x >> 4) & 0x0f0f) | ((x & 0x0f0f) << 4);
801
+ x = ( x >> 8 ) | ( x << 8);
802
+
803
+ return x;
804
+ }
805
+
806
+ ecb_function_ uint32_t ecb_bitrev32 (uint32_t x) ecb_const;
807
+ ecb_function_ uint32_t ecb_bitrev32 (uint32_t x)
808
+ {
809
+ x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);
810
+ x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
811
+ x = ((x >> 4) & 0x0f0f0f0f) | ((x & 0x0f0f0f0f) << 4);
812
+ x = ((x >> 8) & 0x00ff00ff) | ((x & 0x00ff00ff) << 8);
813
+ x = ( x >> 16 ) | ( x << 16);
814
+
815
+ return x;
816
+ }
817
+
818
+ /* popcount64 is only available on 64 bit cpus as gcc builtin */
819
+ /* so for this version we are lazy */
820
+ ecb_function_ int ecb_popcount64 (uint64_t x) ecb_const;
821
+ ecb_function_ int
822
+ ecb_popcount64 (uint64_t x)
823
+ {
824
+ return ecb_popcount32 (x) + ecb_popcount32 (x >> 32);
825
+ }
826
+
827
+ ecb_inline uint8_t ecb_rotl8 (uint8_t x, unsigned int count) ecb_const;
828
+ ecb_inline uint8_t ecb_rotr8 (uint8_t x, unsigned int count) ecb_const;
829
+ ecb_inline uint16_t ecb_rotl16 (uint16_t x, unsigned int count) ecb_const;
830
+ ecb_inline uint16_t ecb_rotr16 (uint16_t x, unsigned int count) ecb_const;
831
+ ecb_inline uint32_t ecb_rotl32 (uint32_t x, unsigned int count) ecb_const;
832
+ ecb_inline uint32_t ecb_rotr32 (uint32_t x, unsigned int count) ecb_const;
833
+ ecb_inline uint64_t ecb_rotl64 (uint64_t x, unsigned int count) ecb_const;
834
+ ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) ecb_const;
835
+
836
+ ecb_inline uint8_t ecb_rotl8 (uint8_t x, unsigned int count) { return (x >> ( 8 - count)) | (x << count); }
837
+ ecb_inline uint8_t ecb_rotr8 (uint8_t x, unsigned int count) { return (x << ( 8 - count)) | (x >> count); }
838
+ ecb_inline uint16_t ecb_rotl16 (uint16_t x, unsigned int count) { return (x >> (16 - count)) | (x << count); }
839
+ ecb_inline uint16_t ecb_rotr16 (uint16_t x, unsigned int count) { return (x << (16 - count)) | (x >> count); }
840
+ ecb_inline uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); }
841
+ ecb_inline uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); }
842
+ ecb_inline uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); }
843
+ ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); }
844
+
845
+ #if ECB_GCC_VERSION(4,3)
846
+ #define ecb_bswap16(x) (__builtin_bswap32 (x) >> 16)
847
+ #define ecb_bswap32(x) __builtin_bswap32 (x)
848
+ #define ecb_bswap64(x) __builtin_bswap64 (x)
849
+ #else
850
+ ecb_function_ uint16_t ecb_bswap16 (uint16_t x) ecb_const;
851
+ ecb_function_ uint16_t
852
+ ecb_bswap16 (uint16_t x)
853
+ {
854
+ return ecb_rotl16 (x, 8);
855
+ }
856
+
857
+ ecb_function_ uint32_t ecb_bswap32 (uint32_t x) ecb_const;
858
+ ecb_function_ uint32_t
859
+ ecb_bswap32 (uint32_t x)
860
+ {
861
+ return (((uint32_t)ecb_bswap16 (x)) << 16) | ecb_bswap16 (x >> 16);
862
+ }
863
+
864
+ ecb_function_ uint64_t ecb_bswap64 (uint64_t x) ecb_const;
865
+ ecb_function_ uint64_t
866
+ ecb_bswap64 (uint64_t x)
867
+ {
868
+ return (((uint64_t)ecb_bswap32 (x)) << 32) | ecb_bswap32 (x >> 32);
869
+ }
870
+ #endif
871
+
872
+ #if ECB_GCC_VERSION(4,5)
873
+ #define ecb_unreachable() __builtin_unreachable ()
874
+ #else
875
+ /* this seems to work fine, but gcc always emits a warning for it :/ */
876
+ ecb_inline void ecb_unreachable (void) ecb_noreturn;
877
+ ecb_inline void ecb_unreachable (void) { }
878
+ #endif
879
+
880
+ /* try to tell the compiler that some condition is definitely true */
881
+ #define ecb_assume(cond) do { if (!(cond)) ecb_unreachable (); } while (0)
882
+
883
+ ecb_inline unsigned char ecb_byteorder_helper (void) ecb_const;
884
+ ecb_inline unsigned char
885
+ ecb_byteorder_helper (void)
886
+ {
887
+ const uint32_t u = 0x11223344;
888
+ return *(unsigned char *)&u;
889
+ }
890
+
891
+ ecb_inline ecb_bool ecb_big_endian (void) ecb_const;
892
+ ecb_inline ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11; }
893
+ ecb_inline ecb_bool ecb_little_endian (void) ecb_const;
894
+ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44; }
895
+
896
+ #if ECB_GCC_VERSION(3,0) || ECB_C99
897
+ #define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0))
898
+ #else
899
+ #define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n)))
900
+ #endif
901
+
902
+ #if __cplusplus
903
+ template<typename T>
904
+ static inline T ecb_div_rd (T val, T div)
905
+ {
906
+ return val < 0 ? - ((-val + div - 1) / div) : (val ) / div;
907
+ }
908
+ template<typename T>
909
+ static inline T ecb_div_ru (T val, T div)
910
+ {
911
+ return val < 0 ? - ((-val ) / div) : (val + div - 1) / div;
912
+ }
913
+ #else
914
+ #define ecb_div_rd(val,div) ((val) < 0 ? - ((-(val) + (div) - 1) / (div)) : ((val) ) / (div))
915
+ #define ecb_div_ru(val,div) ((val) < 0 ? - ((-(val) ) / (div)) : ((val) + (div) - 1) / (div))
916
+ #endif
917
+
918
+ #if ecb_cplusplus_does_not_suck
919
+ /* does not work for local types (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm) */
920
+ template<typename T, int N>
921
+ static inline int ecb_array_length (const T (&arr)[N])
922
+ {
923
+ return N;
924
+ }
925
+ #else
926
+ #define ecb_array_length(name) (sizeof (name) / sizeof (name [0]))
927
+ #endif
928
+
929
+ #endif
930
+
931
+ /* ECB.H END */
932
+
933
+ #if ECB_MEMORY_FENCE_NEEDS_PTHREADS
934
+ /* if your architecture doesn't need memory fences, e.g. because it is
935
+ * single-cpu/core, or if you use libev in a project that doesn't use libev
936
+ * from multiple threads, then you can define ECB_AVOID_PTHREADS when compiling
937
+ * libev, in which cases the memory fences become nops.
938
+ * alternatively, you can remove this #error and link against libpthread,
939
+ * which will then provide the memory fences.
940
+ */
941
+ # error "memory fences not defined for your architecture, please report"
942
+ #endif
943
+
944
+ #ifndef ECB_MEMORY_FENCE
945
+ # define ECB_MEMORY_FENCE do { } while (0)
946
+ # define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
947
+ # define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
948
+ #endif
949
+
950
+ #define expect_false(cond) ecb_expect_false (cond)
951
+ #define expect_true(cond) ecb_expect_true (cond)
952
+ #define noinline ecb_noinline
953
+
954
+ #define inline_size ecb_inline
955
+
956
+ #if EV_FEATURE_CODE
957
+ # define inline_speed ecb_inline
474
958
  #else
475
- # define inline_speed static inline
959
+ # define inline_speed static noinline
476
960
  #endif
477
961
 
478
962
  #define NUMPRI (EV_MAXPRI - EV_MINPRI + 1)
@@ -495,7 +979,7 @@ typedef ev_watcher_time *WT;
495
979
 
496
980
  #if EV_USE_REALTIME
497
981
  /* sig_atomic_t is used to avoid per-thread variables or locking but still */
498
- /* giving it a reasonably high chance of working on typical architetcures */
982
+ /* giving it a reasonably high chance of working on typical architectures */
499
983
  static EV_ATOMIC_T have_realtime; /* did clock_gettime (CLOCK_REALTIME) work? */
500
984
  #endif
501
985
 
@@ -507,7 +991,7 @@ static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work?
507
991
  # define EV_FD_TO_WIN32_HANDLE(fd) _get_osfhandle (fd)
508
992
  #endif
509
993
  #ifndef EV_WIN32_HANDLE_TO_FD
510
- # define EV_WIN32_HANDLE_TO_FD(handle) _open_osfhandle (fd, 0)
994
+ # define EV_WIN32_HANDLE_TO_FD(handle) _open_osfhandle (handle, 0)
511
995
  #endif
512
996
  #ifndef EV_WIN32_CLOSE_FD
513
997
  # define EV_WIN32_CLOSE_FD(fd) close (fd)
@@ -519,15 +1003,113 @@ static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work?
519
1003
 
520
1004
  /*****************************************************************************/
521
1005
 
1006
+ /* define a suitable floor function (only used by periodics atm) */
1007
+
1008
+ #if EV_USE_FLOOR
1009
+ # include <math.h>
1010
+ # define ev_floor(v) floor (v)
1011
+ #else
1012
+
1013
+ #include <float.h>
1014
+
1015
+ /* a floor() replacement function, should be independent of ev_tstamp type */
1016
+ static ev_tstamp noinline
1017
+ ev_floor (ev_tstamp v)
1018
+ {
1019
+ /* the choice of shift factor is not terribly important */
1020
+ #if FLT_RADIX != 2 /* assume FLT_RADIX == 10 */
1021
+ const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 10000000000000000000. : 1000000000.;
1022
+ #else
1023
+ const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 18446744073709551616. : 4294967296.;
1024
+ #endif
1025
+
1026
+ /* argument too large for an unsigned long? */
1027
+ if (expect_false (v >= shift))
1028
+ {
1029
+ ev_tstamp f;
1030
+
1031
+ if (v == v - 1.)
1032
+ return v; /* very large number */
1033
+
1034
+ f = shift * ev_floor (v * (1. / shift));
1035
+ return f + ev_floor (v - f);
1036
+ }
1037
+
1038
+ /* special treatment for negative args? */
1039
+ if (expect_false (v < 0.))
1040
+ {
1041
+ ev_tstamp f = -ev_floor (-v);
1042
+
1043
+ return f - (f == v ? 0 : 1);
1044
+ }
1045
+
1046
+ /* fits into an unsigned long */
1047
+ return (unsigned long)v;
1048
+ }
1049
+
1050
+ #endif
1051
+
1052
+ /*****************************************************************************/
1053
+
1054
+ #ifdef __linux
1055
+ # include <sys/utsname.h>
1056
+ #endif
1057
+
1058
+ static unsigned int noinline ecb_cold
1059
+ ev_linux_version (void)
1060
+ {
1061
+ #ifdef __linux
1062
+ unsigned int v = 0;
1063
+ struct utsname buf;
1064
+ int i;
1065
+ char *p = buf.release;
1066
+
1067
+ if (uname (&buf))
1068
+ return 0;
1069
+
1070
+ for (i = 3+1; --i; )
1071
+ {
1072
+ unsigned int c = 0;
1073
+
1074
+ for (;;)
1075
+ {
1076
+ if (*p >= '0' && *p <= '9')
1077
+ c = c * 10 + *p++ - '0';
1078
+ else
1079
+ {
1080
+ p += *p == '.';
1081
+ break;
1082
+ }
1083
+ }
1084
+
1085
+ v = (v << 8) | c;
1086
+ }
1087
+
1088
+ return v;
1089
+ #else
1090
+ return 0;
1091
+ #endif
1092
+ }
1093
+
1094
+ /*****************************************************************************/
1095
+
1096
+ #if EV_AVOID_STDIO
1097
+ static void noinline ecb_cold
1098
+ ev_printerr (const char *msg)
1099
+ {
1100
+ write (STDERR_FILENO, msg, strlen (msg));
1101
+ }
1102
+ #endif
1103
+
522
1104
  static void (*syserr_cb)(const char *msg);
523
1105
 
524
- void
1106
+ void ecb_cold
525
1107
  ev_set_syserr_cb (void (*cb)(const char *msg))
526
1108
  {
527
1109
  syserr_cb = cb;
528
1110
  }
529
1111
 
530
- static void noinline
1112
+ static void noinline ecb_cold
531
1113
  ev_syserr (const char *msg)
532
1114
  {
533
1115
  if (!msg)
@@ -537,7 +1119,14 @@ ev_syserr (const char *msg)
537
1119
  syserr_cb (msg);
538
1120
  else
539
1121
  {
1122
+ #if EV_AVOID_STDIO
1123
+ ev_printerr (msg);
1124
+ ev_printerr (": ");
1125
+ ev_printerr (strerror (errno));
1126
+ ev_printerr ("\n");
1127
+ #else
540
1128
  perror (msg);
1129
+ #endif
541
1130
  abort ();
542
1131
  }
543
1132
  }
@@ -545,8 +1134,11 @@ ev_syserr (const char *msg)
545
1134
  static void *
546
1135
  ev_realloc_emul (void *ptr, long size)
547
1136
  {
1137
+ #if __GLIBC__
1138
+ return realloc (ptr, size);
1139
+ #else
548
1140
  /* some systems, notably openbsd and darwin, fail to properly
549
- * implement realloc (x, 0) (as required by both ansi c-98 and
1141
+ * implement realloc (x, 0) (as required by both ansi c-89 and
550
1142
  * the single unix specification, so work around them here.
551
1143
  */
552
1144
 
@@ -555,11 +1147,12 @@ ev_realloc_emul (void *ptr, long size)
555
1147
 
556
1148
  free (ptr);
557
1149
  return 0;
1150
+ #endif
558
1151
  }
559
1152
 
560
1153
  static void *(*alloc)(void *ptr, long size) = ev_realloc_emul;
561
1154
 
562
- void
1155
+ void ecb_cold
563
1156
  ev_set_allocator (void *(*cb)(void *ptr, long size))
564
1157
  {
565
1158
  alloc = cb;
@@ -572,7 +1165,11 @@ ev_realloc (void *ptr, long size)
572
1165
 
573
1166
  if (!ptr && size)
574
1167
  {
575
- fprintf (stderr, "libev: cannot allocate %ld bytes, aborting.", size);
1168
+ #if EV_AVOID_STDIO
1169
+ ev_printerr ("(libev) memory allocation failed, aborting.\n");
1170
+ #else
1171
+ fprintf (stderr, "(libev) cannot allocate %ld bytes, aborting.", size);
1172
+ #endif
576
1173
  abort ();
577
1174
  }
578
1175
 
@@ -598,9 +1195,12 @@ typedef struct
598
1195
  #if EV_USE_EPOLL
599
1196
  unsigned int egen; /* generation counter to counter epoll bugs */
600
1197
  #endif
601
- #if EV_SELECT_IS_WINSOCKET
1198
+ #if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP
602
1199
  SOCKET handle;
603
1200
  #endif
1201
+ #if EV_USE_IOCP
1202
+ OVERLAPPED or, ow;
1203
+ #endif
604
1204
  } ANFD;
605
1205
 
606
1206
  /* stores the pending event set for a given watcher */
@@ -651,11 +1251,11 @@ typedef struct
651
1251
  #include "ev_wrap.h"
652
1252
 
653
1253
  static struct ev_loop default_loop_struct;
654
- struct ev_loop *ev_default_loop_ptr;
1254
+ EV_API_DECL struct ev_loop *ev_default_loop_ptr = 0; /* needs to be initialised to make it a definition despite extern */
655
1255
 
656
1256
  #else
657
1257
 
658
- ev_tstamp ev_rt_now;
1258
+ EV_API_DECL ev_tstamp ev_rt_now = 0; /* needs to be initialised to make it a definition despite extern */
659
1259
  #define VAR(name,decl) static decl;
660
1260
  #include "ev_vars.h"
661
1261
  #undef VAR
@@ -664,7 +1264,7 @@ typedef struct
664
1264
 
665
1265
  #endif
666
1266
 
667
- #if EV_MINIMAL < 2
1267
+ #if EV_FEATURE_API
668
1268
  # define EV_RELEASE_CB if (expect_false (release_cb)) release_cb (EV_A)
669
1269
  # define EV_ACQUIRE_CB if (expect_false (acquire_cb)) acquire_cb (EV_A)
670
1270
  # define EV_INVOKE_PENDING invoke_cb (EV_A)
@@ -674,7 +1274,7 @@ typedef struct
674
1274
  # define EV_INVOKE_PENDING ev_invoke_pending (EV_A)
675
1275
  #endif
676
1276
 
677
- #define EVUNLOOP_RECURSE 0x80
1277
+ #define EVBREAK_RECURSE 0x80
678
1278
 
679
1279
  /*****************************************************************************/
680
1280
 
@@ -728,21 +1328,17 @@ ev_sleep (ev_tstamp delay)
728
1328
  #if EV_USE_NANOSLEEP
729
1329
  struct timespec ts;
730
1330
 
731
- ts.tv_sec = (time_t)delay;
732
- ts.tv_nsec = (long)((delay - (ev_tstamp)(ts.tv_sec)) * 1e9);
733
-
1331
+ EV_TS_SET (ts, delay);
734
1332
  nanosleep (&ts, 0);
735
1333
  #elif defined(_WIN32)
736
1334
  Sleep ((unsigned long)(delay * 1e3));
737
1335
  #else
738
1336
  struct timeval tv;
739
1337
 
740
- tv.tv_sec = (time_t)delay;
741
- tv.tv_usec = (long)((delay - (ev_tstamp)(tv.tv_sec)) * 1e6);
742
-
743
1338
  /* here we rely on sys/time.h + sys/types.h + unistd.h providing select */
744
1339
  /* something not guaranteed by newer posix versions, but guaranteed */
745
1340
  /* by older ones */
1341
+ EV_TV_SET (tv, delay);
746
1342
  select (0, 0, 0, 0, &tv);
747
1343
  #endif
748
1344
  }
@@ -753,7 +1349,7 @@ ev_sleep (ev_tstamp delay)
753
1349
  #define MALLOC_ROUND 4096 /* prefer to allocate in chunks of this size, must be 2**n and >> 4 longs */
754
1350
 
755
1351
  /* find a suitable new size for the given array, */
756
- /* hopefully by rounding to a ncie-to-malloc size */
1352
+ /* hopefully by rounding to a nice-to-malloc size */
757
1353
  inline_size int
758
1354
  array_nextsize (int elem, int cur, int cnt)
759
1355
  {
@@ -763,7 +1359,7 @@ array_nextsize (int elem, int cur, int cnt)
763
1359
  ncur <<= 1;
764
1360
  while (cnt > ncur);
765
1361
 
766
- /* if size is large, round to MALLOC_ROUND - 4 * longs to accomodate malloc overhead */
1362
+ /* if size is large, round to MALLOC_ROUND - 4 * longs to accommodate malloc overhead */
767
1363
  if (elem * ncur > MALLOC_ROUND - sizeof (void *) * 4)
768
1364
  {
769
1365
  ncur *= elem;
@@ -775,7 +1371,7 @@ array_nextsize (int elem, int cur, int cnt)
775
1371
  return ncur;
776
1372
  }
777
1373
 
778
- static noinline void *
1374
+ static void * noinline ecb_cold
779
1375
  array_realloc (int elem, void *base, int *cur, int cnt)
780
1376
  {
781
1377
  *cur = array_nextsize (elem, *cur, cnt);
@@ -788,7 +1384,7 @@ array_realloc (int elem, void *base, int *cur, int cnt)
788
1384
  #define array_needsize(type,base,cur,cnt,init) \
789
1385
  if (expect_false ((cnt) > (cur))) \
790
1386
  { \
791
- int ocur_ = (cur); \
1387
+ int ecb_unused ocur_ = (cur); \
792
1388
  (base) = (type *)array_realloc \
793
1389
  (sizeof (type), (base), &(cur), (cnt)); \
794
1390
  init ((base) + (ocur_), (cur) - ocur_); \
@@ -859,7 +1455,7 @@ queue_events (EV_P_ W *events, int eventcnt, int type)
859
1455
  /*****************************************************************************/
860
1456
 
861
1457
  inline_speed void
862
- fd_event_nc (EV_P_ int fd, int revents)
1458
+ fd_event_nocheck (EV_P_ int fd, int revents)
863
1459
  {
864
1460
  ANFD *anfd = anfds + fd;
865
1461
  ev_io *w;
@@ -881,14 +1477,14 @@ fd_event (EV_P_ int fd, int revents)
881
1477
  ANFD *anfd = anfds + fd;
882
1478
 
883
1479
  if (expect_true (!anfd->reify))
884
- fd_event_nc (EV_A_ fd, revents);
1480
+ fd_event_nocheck (EV_A_ fd, revents);
885
1481
  }
886
1482
 
887
1483
  void
888
1484
  ev_feed_fd_event (EV_P_ int fd, int revents)
889
1485
  {
890
1486
  if (fd >= 0 && fd < anfdmax)
891
- fd_event_nc (EV_A_ fd, revents);
1487
+ fd_event_nocheck (EV_A_ fd, revents);
892
1488
  }
893
1489
 
894
1490
  /* make sure the external fd watch events are in-sync */
@@ -898,36 +1494,55 @@ fd_reify (EV_P)
898
1494
  {
899
1495
  int i;
900
1496
 
1497
+ #if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP
901
1498
  for (i = 0; i < fdchangecnt; ++i)
902
1499
  {
903
1500
  int fd = fdchanges [i];
904
1501
  ANFD *anfd = anfds + fd;
905
- ev_io *w;
906
1502
 
907
- unsigned char events = 0;
1503
+ if (anfd->reify & EV__IOFDSET && anfd->head)
1504
+ {
1505
+ SOCKET handle = EV_FD_TO_WIN32_HANDLE (fd);
1506
+
1507
+ if (handle != anfd->handle)
1508
+ {
1509
+ unsigned long arg;
908
1510
 
909
- for (w = (ev_io *)anfd->head; w; w = (ev_io *)((WL)w)->next)
910
- events |= (unsigned char)w->events;
1511
+ assert (("libev: only socket fds supported in this configuration", ioctlsocket (handle, FIONREAD, &arg) == 0));
911
1512
 
912
- #if EV_SELECT_IS_WINSOCKET
913
- if (events)
914
- {
915
- unsigned long arg;
916
- anfd->handle = EV_FD_TO_WIN32_HANDLE (fd);
917
- assert (("libev: only socket fds supported in this configuration", ioctlsocket (anfd->handle, FIONREAD, &arg) == 0));
1513
+ /* handle changed, but fd didn't - we need to do it in two steps */
1514
+ backend_modify (EV_A_ fd, anfd->events, 0);
1515
+ anfd->events = 0;
1516
+ anfd->handle = handle;
1517
+ }
918
1518
  }
1519
+ }
919
1520
  #endif
920
1521
 
921
- {
922
- unsigned char o_events = anfd->events;
923
- unsigned char o_reify = anfd->reify;
1522
+ for (i = 0; i < fdchangecnt; ++i)
1523
+ {
1524
+ int fd = fdchanges [i];
1525
+ ANFD *anfd = anfds + fd;
1526
+ ev_io *w;
924
1527
 
925
- anfd->reify = 0;
926
- anfd->events = events;
1528
+ unsigned char o_events = anfd->events;
1529
+ unsigned char o_reify = anfd->reify;
927
1530
 
928
- if (o_events != events || o_reify & EV__IOFDSET)
929
- backend_modify (EV_A_ fd, o_events, events);
930
- }
1531
+ anfd->reify = 0;
1532
+
1533
+ /*if (expect_true (o_reify & EV_ANFD_REIFY)) probably a deoptimisation */
1534
+ {
1535
+ anfd->events = 0;
1536
+
1537
+ for (w = (ev_io *)anfd->head; w; w = (ev_io *)((WL)w)->next)
1538
+ anfd->events |= (unsigned char)w->events;
1539
+
1540
+ if (o_events != anfd->events)
1541
+ o_reify = EV__IOFDSET; /* actually |= */
1542
+ }
1543
+
1544
+ if (o_reify & EV__IOFDSET)
1545
+ backend_modify (EV_A_ fd, o_events, anfd->events);
931
1546
  }
932
1547
 
933
1548
  fdchangecnt = 0;
@@ -949,7 +1564,7 @@ fd_change (EV_P_ int fd, int flags)
949
1564
  }
950
1565
 
951
1566
  /* the given fd is invalid/unusable, so make sure it doesn't hurt us anymore */
952
- inline_speed void
1567
+ inline_speed void ecb_cold
953
1568
  fd_kill (EV_P_ int fd)
954
1569
  {
955
1570
  ev_io *w;
@@ -961,19 +1576,19 @@ fd_kill (EV_P_ int fd)
961
1576
  }
962
1577
  }
963
1578
 
964
- /* check whether the given fd is atcually valid, for error recovery */
965
- inline_size int
1579
+ /* check whether the given fd is actually valid, for error recovery */
1580
+ inline_size int ecb_cold
966
1581
  fd_valid (int fd)
967
1582
  {
968
1583
  #ifdef _WIN32
969
- return _get_osfhandle (fd) != -1;
1584
+ return EV_FD_TO_WIN32_HANDLE (fd) != -1;
970
1585
  #else
971
1586
  return fcntl (fd, F_GETFD) != -1;
972
1587
  #endif
973
1588
  }
974
1589
 
975
1590
  /* called on EBADF to verify fds */
976
- static void noinline
1591
+ static void noinline ecb_cold
977
1592
  fd_ebadf (EV_P)
978
1593
  {
979
1594
  int fd;
@@ -985,7 +1600,7 @@ fd_ebadf (EV_P)
985
1600
  }
986
1601
 
987
1602
  /* called on ENOMEM in select/poll to kill some fds and retry */
988
- static void noinline
1603
+ static void noinline ecb_cold
989
1604
  fd_enomem (EV_P)
990
1605
  {
991
1606
  int fd;
@@ -1013,10 +1628,24 @@ fd_rearm_all (EV_P)
1013
1628
  }
1014
1629
  }
1015
1630
 
1631
+ /* used to prepare libev internal fd's */
1632
+ /* this is not fork-safe */
1633
+ inline_speed void
1634
+ fd_intern (int fd)
1635
+ {
1636
+ #ifdef _WIN32
1637
+ unsigned long arg = 1;
1638
+ ioctlsocket (EV_FD_TO_WIN32_HANDLE (fd), FIONBIO, &arg);
1639
+ #else
1640
+ fcntl (fd, F_SETFD, FD_CLOEXEC);
1641
+ fcntl (fd, F_SETFL, O_NONBLOCK);
1642
+ #endif
1643
+ }
1644
+
1016
1645
  /*****************************************************************************/
1017
1646
 
1018
1647
  /*
1019
- * the heap functions want a real array index. array index 0 uis guaranteed to not
1648
+ * the heap functions want a real array index. array index 0 is guaranteed to not
1020
1649
  * be in-use at any time. the first heap entry is at array [HEAP0]. DHEAP gives
1021
1650
  * the branching factor of the d-tree.
1022
1651
  */
@@ -1174,26 +1803,14 @@ static ANSIG signals [EV_NSIG - 1];
1174
1803
 
1175
1804
  /*****************************************************************************/
1176
1805
 
1177
- /* used to prepare libev internal fd's */
1178
- /* this is not fork-safe */
1179
- inline_speed void
1180
- fd_intern (int fd)
1181
- {
1182
- #ifdef _WIN32
1183
- unsigned long arg = 1;
1184
- ioctlsocket (_get_osfhandle (fd), FIONBIO, &arg);
1185
- #else
1186
- fcntl (fd, F_SETFD, FD_CLOEXEC);
1187
- fcntl (fd, F_SETFL, O_NONBLOCK);
1188
- #endif
1189
- }
1806
+ #if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
1190
1807
 
1191
- static void noinline
1808
+ static void noinline ecb_cold
1192
1809
  evpipe_init (EV_P)
1193
1810
  {
1194
1811
  if (!ev_is_active (&pipe_w))
1195
1812
  {
1196
- #if EV_USE_EVENTFD
1813
+ # if EV_USE_EVENTFD
1197
1814
  evfd = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC);
1198
1815
  if (evfd < 0 && errno == EINVAL)
1199
1816
  evfd = eventfd (0, 0);
@@ -1205,7 +1822,7 @@ evpipe_init (EV_P)
1205
1822
  ev_io_set (&pipe_w, evfd, EV_READ);
1206
1823
  }
1207
1824
  else
1208
- #endif
1825
+ # endif
1209
1826
  {
1210
1827
  while (pipe (evpipe))
1211
1828
  ev_syserr ("(libev) error creating signal/async pipe");
@@ -1220,14 +1837,27 @@ evpipe_init (EV_P)
1220
1837
  }
1221
1838
  }
1222
1839
 
1223
- inline_size void
1840
+ inline_speed void
1224
1841
  evpipe_write (EV_P_ EV_ATOMIC_T *flag)
1225
1842
  {
1226
- if (!*flag)
1843
+ if (expect_true (*flag))
1844
+ return;
1845
+
1846
+ *flag = 1;
1847
+
1848
+ ECB_MEMORY_FENCE_RELEASE; /* make sure flag is visible before the wakeup */
1849
+
1850
+ pipe_write_skipped = 1;
1851
+
1852
+ ECB_MEMORY_FENCE; /* make sure pipe_write_skipped is visible before we check pipe_write_wanted */
1853
+
1854
+ if (pipe_write_wanted)
1227
1855
  {
1228
- int old_errno = errno; /* save errno because write might clobber it */
1856
+ int old_errno;
1229
1857
 
1230
- *flag = 1;
1858
+ pipe_write_skipped = 0; /* just an optimisation, no fence needed */
1859
+
1860
+ old_errno = errno; /* save errno because write will clobber it */
1231
1861
 
1232
1862
  #if EV_USE_EVENTFD
1233
1863
  if (evfd >= 0)
@@ -1237,7 +1867,14 @@ evpipe_write (EV_P_ EV_ATOMIC_T *flag)
1237
1867
  }
1238
1868
  else
1239
1869
  #endif
1240
- write (evpipe [1], &old_errno, 1);
1870
+ {
1871
+ /* win32 people keep sending patches that change this write() to send() */
1872
+ /* and then run away. but send() is wrong, it wants a socket handle on win32 */
1873
+ /* so when you think this write should be a send instead, please find out */
1874
+ /* where your send() is from - it's definitely not the microsoft send, and */
1875
+ /* tell me. thank you. */
1876
+ write (evpipe [1], &(evpipe [1]), 1);
1877
+ }
1241
1878
 
1242
1879
  errno = old_errno;
1243
1880
  }
@@ -1250,27 +1887,35 @@ pipecb (EV_P_ ev_io *iow, int revents)
1250
1887
  {
1251
1888
  int i;
1252
1889
 
1253
- #if EV_USE_EVENTFD
1254
- if (evfd >= 0)
1890
+ if (revents & EV_READ)
1255
1891
  {
1256
- uint64_t counter;
1257
- read (evfd, &counter, sizeof (uint64_t));
1258
- }
1259
- else
1892
+ #if EV_USE_EVENTFD
1893
+ if (evfd >= 0)
1894
+ {
1895
+ uint64_t counter;
1896
+ read (evfd, &counter, sizeof (uint64_t));
1897
+ }
1898
+ else
1260
1899
  #endif
1261
- {
1262
- char dummy;
1263
- read (evpipe [0], &dummy, 1);
1900
+ {
1901
+ char dummy;
1902
+ /* see discussion in evpipe_write when you think this read should be recv in win32 */
1903
+ read (evpipe [0], &dummy, 1);
1904
+ }
1264
1905
  }
1265
1906
 
1907
+ pipe_write_skipped = 0;
1908
+
1909
+ #if EV_SIGNAL_ENABLE
1266
1910
  if (sig_pending)
1267
- {
1911
+ {
1268
1912
  sig_pending = 0;
1269
1913
 
1270
1914
  for (i = EV_NSIG - 1; i--; )
1271
1915
  if (expect_false (signals [i].pending))
1272
1916
  ev_feed_signal_event (EV_A_ i + 1);
1273
1917
  }
1918
+ #endif
1274
1919
 
1275
1920
  #if EV_ASYNC_ENABLE
1276
1921
  if (async_pending)
@@ -1289,21 +1934,33 @@ pipecb (EV_P_ ev_io *iow, int revents)
1289
1934
 
1290
1935
  /*****************************************************************************/
1291
1936
 
1292
- static void
1293
- ev_sighandler (int signum)
1937
+ void
1938
+ ev_feed_signal (int signum)
1294
1939
  {
1295
1940
  #if EV_MULTIPLICITY
1296
1941
  EV_P = signals [signum - 1].loop;
1297
- #endif
1298
1942
 
1299
- #if _WIN32
1300
- signal (signum, ev_sighandler);
1943
+ if (!EV_A)
1944
+ return;
1301
1945
  #endif
1302
1946
 
1947
+ if (!ev_active (&pipe_w))
1948
+ return;
1949
+
1303
1950
  signals [signum - 1].pending = 1;
1304
1951
  evpipe_write (EV_A_ &sig_pending);
1305
1952
  }
1306
1953
 
1954
+ static void
1955
+ ev_sighandler (int signum)
1956
+ {
1957
+ #ifdef _WIN32
1958
+ signal (signum, ev_sighandler);
1959
+ #endif
1960
+
1961
+ ev_feed_signal (signum);
1962
+ }
1963
+
1307
1964
  void noinline
1308
1965
  ev_feed_signal_event (EV_P_ int signum)
1309
1966
  {
@@ -1348,12 +2005,13 @@ sigfdcb (EV_P_ ev_io *iow, int revents)
1348
2005
  }
1349
2006
  #endif
1350
2007
 
2008
+ #endif
2009
+
1351
2010
  /*****************************************************************************/
1352
2011
 
2012
+ #if EV_CHILD_ENABLE
1353
2013
  static WL childs [EV_PID_HASHSIZE];
1354
2014
 
1355
- #ifndef _WIN32
1356
-
1357
2015
  static ev_signal childev;
1358
2016
 
1359
2017
  #ifndef WIFCONTINUED
@@ -1367,7 +2025,7 @@ child_reap (EV_P_ int chain, int pid, int status)
1367
2025
  ev_child *w;
1368
2026
  int traced = WIFSTOPPED (status) || WIFCONTINUED (status);
1369
2027
 
1370
- for (w = (ev_child *)childs [chain & (EV_PID_HASHSIZE - 1)]; w; w = (ev_child *)((WL)w)->next)
2028
+ for (w = (ev_child *)childs [chain & ((EV_PID_HASHSIZE) - 1)]; w; w = (ev_child *)((WL)w)->next)
1371
2029
  {
1372
2030
  if ((w->pid == pid || !w->pid)
1373
2031
  && (!traced || (w->flags & 1)))
@@ -1402,7 +2060,7 @@ childcb (EV_P_ ev_signal *sw, int revents)
1402
2060
  ev_feed_event (EV_A_ (W)sw, EV_SIGNAL);
1403
2061
 
1404
2062
  child_reap (EV_A_ pid, pid, status);
1405
- if (EV_PID_HASHSIZE > 1)
2063
+ if ((EV_PID_HASHSIZE) > 1)
1406
2064
  child_reap (EV_A_ 0, pid, status); /* this might trigger a watcher twice, but feed_event catches that */
1407
2065
  }
1408
2066
 
@@ -1410,6 +2068,9 @@ childcb (EV_P_ ev_signal *sw, int revents)
1410
2068
 
1411
2069
  /*****************************************************************************/
1412
2070
 
2071
+ #if EV_USE_IOCP
2072
+ # include "ev_iocp.c"
2073
+ #endif
1413
2074
  #if EV_USE_PORT
1414
2075
  # include "ev_port.c"
1415
2076
  #endif
@@ -1426,20 +2087,20 @@ childcb (EV_P_ ev_signal *sw, int revents)
1426
2087
  # include "ev_select.c"
1427
2088
  #endif
1428
2089
 
1429
- int
2090
+ int ecb_cold
1430
2091
  ev_version_major (void)
1431
2092
  {
1432
2093
  return EV_VERSION_MAJOR;
1433
2094
  }
1434
2095
 
1435
- int
2096
+ int ecb_cold
1436
2097
  ev_version_minor (void)
1437
2098
  {
1438
2099
  return EV_VERSION_MINOR;
1439
2100
  }
1440
2101
 
1441
2102
  /* return true if we are running with elevated privileges and should ignore env variables */
1442
- int inline_size
2103
+ int inline_size ecb_cold
1443
2104
  enable_secure (void)
1444
2105
  {
1445
2106
  #ifdef _WIN32
@@ -1450,7 +2111,7 @@ enable_secure (void)
1450
2111
  #endif
1451
2112
  }
1452
2113
 
1453
- unsigned int
2114
+ unsigned int ecb_cold
1454
2115
  ev_supported_backends (void)
1455
2116
  {
1456
2117
  unsigned int flags = 0;
@@ -1464,7 +2125,7 @@ ev_supported_backends (void)
1464
2125
  return flags;
1465
2126
  }
1466
2127
 
1467
- unsigned int
2128
+ unsigned int ecb_cold
1468
2129
  ev_recommended_backends (void)
1469
2130
  {
1470
2131
  unsigned int flags = ev_supported_backends ();
@@ -1479,18 +2140,21 @@ ev_recommended_backends (void)
1479
2140
  flags &= ~EVBACKEND_KQUEUE; /* horribly broken, even for sockets */
1480
2141
  flags &= ~EVBACKEND_POLL; /* poll is based on kqueue from 10.5 onwards */
1481
2142
  #endif
2143
+ #ifdef __FreeBSD__
2144
+ flags &= ~EVBACKEND_POLL; /* poll return value is unusable (http://forums.freebsd.org/archive/index.php/t-10270.html) */
2145
+ #endif
1482
2146
 
1483
2147
  return flags;
1484
2148
  }
1485
2149
 
1486
- unsigned int
2150
+ unsigned int ecb_cold
1487
2151
  ev_embeddable_backends (void)
1488
2152
  {
1489
2153
  int flags = EVBACKEND_EPOLL | EVBACKEND_KQUEUE | EVBACKEND_PORT;
1490
2154
 
1491
2155
  /* epoll embeddability broken on all linux versions up to at least 2.6.23 */
1492
- /* please fix it and tell me how to detect the fix */
1493
- flags &= ~EVBACKEND_EPOLL;
2156
+ if (ev_linux_version () < 0x020620) /* disable it on linux < 2.6.32 */
2157
+ flags &= ~EVBACKEND_EPOLL;
1494
2158
 
1495
2159
  return flags;
1496
2160
  }
@@ -1501,15 +2165,15 @@ ev_backend (EV_P)
1501
2165
  return backend;
1502
2166
  }
1503
2167
 
1504
- #if EV_MINIMAL < 2
2168
+ #if EV_FEATURE_API
1505
2169
  unsigned int
1506
- ev_loop_count (EV_P)
2170
+ ev_iteration (EV_P)
1507
2171
  {
1508
2172
  return loop_count;
1509
2173
  }
1510
2174
 
1511
2175
  unsigned int
1512
- ev_loop_depth (EV_P)
2176
+ ev_depth (EV_P)
1513
2177
  {
1514
2178
  return loop_depth;
1515
2179
  }
@@ -1538,12 +2202,14 @@ ev_userdata (EV_P)
1538
2202
  return userdata;
1539
2203
  }
1540
2204
 
1541
- void ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P))
2205
+ void
2206
+ ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P))
1542
2207
  {
1543
2208
  invoke_cb = invoke_pending_cb;
1544
2209
  }
1545
2210
 
1546
- void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P))
2211
+ void
2212
+ ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P))
1547
2213
  {
1548
2214
  release_cb = release;
1549
2215
  acquire_cb = acquire;
@@ -1551,11 +2217,13 @@ void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P))
1551
2217
  #endif
1552
2218
 
1553
2219
  /* initialise a loop structure, must be zero-initialised */
1554
- static void noinline
2220
+ static void noinline ecb_cold
1555
2221
  loop_init (EV_P_ unsigned int flags)
1556
2222
  {
1557
2223
  if (!backend)
1558
2224
  {
2225
+ origflags = flags;
2226
+
1559
2227
  #if EV_USE_REALTIME
1560
2228
  if (!have_realtime)
1561
2229
  {
@@ -1587,32 +2255,37 @@ loop_init (EV_P_ unsigned int flags)
1587
2255
  && getenv ("LIBEV_FLAGS"))
1588
2256
  flags = atoi (getenv ("LIBEV_FLAGS"));
1589
2257
 
1590
- ev_rt_now = ev_time ();
1591
- mn_now = get_clock ();
1592
- now_floor = mn_now;
1593
- rtmn_diff = ev_rt_now - mn_now;
1594
- #if EV_MINIMAL < 2
1595
- invoke_cb = ev_invoke_pending;
2258
+ ev_rt_now = ev_time ();
2259
+ mn_now = get_clock ();
2260
+ now_floor = mn_now;
2261
+ rtmn_diff = ev_rt_now - mn_now;
2262
+ #if EV_FEATURE_API
2263
+ invoke_cb = ev_invoke_pending;
1596
2264
  #endif
1597
2265
 
1598
- io_blocktime = 0.;
1599
- timeout_blocktime = 0.;
1600
- backend = 0;
1601
- backend_fd = -1;
1602
- sig_pending = 0;
2266
+ io_blocktime = 0.;
2267
+ timeout_blocktime = 0.;
2268
+ backend = 0;
2269
+ backend_fd = -1;
2270
+ sig_pending = 0;
1603
2271
  #if EV_ASYNC_ENABLE
1604
- async_pending = 0;
2272
+ async_pending = 0;
1605
2273
  #endif
2274
+ pipe_write_skipped = 0;
2275
+ pipe_write_wanted = 0;
1606
2276
  #if EV_USE_INOTIFY
1607
- fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2;
2277
+ fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2;
1608
2278
  #endif
1609
2279
  #if EV_USE_SIGNALFD
1610
- sigfd = flags & EVFLAG_SIGNALFD ? -2 : -1;
2280
+ sigfd = flags & EVFLAG_SIGNALFD ? -2 : -1;
1611
2281
  #endif
1612
2282
 
1613
- if (!(flags & 0x0000ffffU))
2283
+ if (!(flags & EVBACKEND_MASK))
1614
2284
  flags |= ev_recommended_backends ();
1615
2285
 
2286
+ #if EV_USE_IOCP
2287
+ if (!backend && (flags & EVBACKEND_IOCP )) backend = iocp_init (EV_A_ flags);
2288
+ #endif
1616
2289
  #if EV_USE_PORT
1617
2290
  if (!backend && (flags & EVBACKEND_PORT )) backend = port_init (EV_A_ flags);
1618
2291
  #endif
@@ -1631,17 +2304,42 @@ loop_init (EV_P_ unsigned int flags)
1631
2304
 
1632
2305
  ev_prepare_init (&pending_w, pendingcb);
1633
2306
 
2307
+ #if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
1634
2308
  ev_init (&pipe_w, pipecb);
1635
2309
  ev_set_priority (&pipe_w, EV_MAXPRI);
2310
+ #endif
1636
2311
  }
1637
2312
  }
1638
2313
 
1639
2314
  /* free up a loop structure */
1640
- static void noinline
1641
- loop_destroy (EV_P)
2315
+ void ecb_cold
2316
+ ev_loop_destroy (EV_P)
1642
2317
  {
1643
2318
  int i;
1644
2319
 
2320
+ #if EV_MULTIPLICITY
2321
+ /* mimic free (0) */
2322
+ if (!EV_A)
2323
+ return;
2324
+ #endif
2325
+
2326
+ #if EV_CLEANUP_ENABLE
2327
+ /* queue cleanup watchers (and execute them) */
2328
+ if (expect_false (cleanupcnt))
2329
+ {
2330
+ queue_events (EV_A_ (W *)cleanups, cleanupcnt, EV_CLEANUP);
2331
+ EV_INVOKE_PENDING;
2332
+ }
2333
+ #endif
2334
+
2335
+ #if EV_CHILD_ENABLE
2336
+ if (ev_is_active (&childev))
2337
+ {
2338
+ ev_ref (EV_A); /* child watcher */
2339
+ ev_signal_stop (EV_A_ &childev);
2340
+ }
2341
+ #endif
2342
+
1645
2343
  if (ev_is_active (&pipe_w))
1646
2344
  {
1647
2345
  /*ev_ref (EV_A);*/
@@ -1672,6 +2370,9 @@ loop_destroy (EV_P)
1672
2370
  if (backend_fd >= 0)
1673
2371
  close (backend_fd);
1674
2372
 
2373
+ #if EV_USE_IOCP
2374
+ if (backend == EVBACKEND_IOCP ) iocp_destroy (EV_A);
2375
+ #endif
1675
2376
  #if EV_USE_PORT
1676
2377
  if (backend == EVBACKEND_PORT ) port_destroy (EV_A);
1677
2378
  #endif
@@ -1707,6 +2408,9 @@ loop_destroy (EV_P)
1707
2408
  #endif
1708
2409
  #if EV_FORK_ENABLE
1709
2410
  array_free (fork, EMPTY);
2411
+ #endif
2412
+ #if EV_CLEANUP_ENABLE
2413
+ array_free (cleanup, EMPTY);
1710
2414
  #endif
1711
2415
  array_free (prepare, EMPTY);
1712
2416
  array_free (check, EMPTY);
@@ -1715,6 +2419,15 @@ loop_destroy (EV_P)
1715
2419
  #endif
1716
2420
 
1717
2421
  backend = 0;
2422
+
2423
+ #if EV_MULTIPLICITY
2424
+ if (ev_is_default_loop (EV_A))
2425
+ #endif
2426
+ ev_default_loop_ptr = 0;
2427
+ #if EV_MULTIPLICITY
2428
+ else
2429
+ ev_free (EV_A);
2430
+ #endif
1718
2431
  }
1719
2432
 
1720
2433
  #if EV_USE_INOTIFY
@@ -1739,12 +2452,7 @@ loop_fork (EV_P)
1739
2452
 
1740
2453
  if (ev_is_active (&pipe_w))
1741
2454
  {
1742
- /* this "locks" the handlers against writing to the pipe */
1743
- /* while we modify the fd vars */
1744
- sig_pending = 1;
1745
- #if EV_ASYNC_ENABLE
1746
- async_pending = 1;
1747
- #endif
2455
+ /* pipe_write_wanted must be false now, so modifying fd vars should be safe */
1748
2456
 
1749
2457
  ev_ref (EV_A);
1750
2458
  ev_io_stop (EV_A_ &pipe_w);
@@ -1760,9 +2468,11 @@ loop_fork (EV_P)
1760
2468
  EV_WIN32_CLOSE_FD (evpipe [1]);
1761
2469
  }
1762
2470
 
2471
+ #if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
1763
2472
  evpipe_init (EV_A);
1764
2473
  /* now iterate over everything, in case we missed something */
1765
2474
  pipecb (EV_A_ &pipe_w, EV_READ);
2475
+ #endif
1766
2476
  }
1767
2477
 
1768
2478
  postfork = 0;
@@ -1770,7 +2480,7 @@ loop_fork (EV_P)
1770
2480
 
1771
2481
  #if EV_MULTIPLICITY
1772
2482
 
1773
- struct ev_loop *
2483
+ struct ev_loop * ecb_cold
1774
2484
  ev_loop_new (unsigned int flags)
1775
2485
  {
1776
2486
  EV_P = (struct ev_loop *)ev_malloc (sizeof (struct ev_loop));
@@ -1781,25 +2491,14 @@ ev_loop_new (unsigned int flags)
1781
2491
  if (ev_backend (EV_A))
1782
2492
  return EV_A;
1783
2493
 
2494
+ ev_free (EV_A);
1784
2495
  return 0;
1785
2496
  }
1786
2497
 
1787
- void
1788
- ev_loop_destroy (EV_P)
1789
- {
1790
- loop_destroy (EV_A);
1791
- ev_free (loop);
1792
- }
1793
-
1794
- void
1795
- ev_loop_fork (EV_P)
1796
- {
1797
- postfork = 1; /* must be in line with ev_default_fork */
1798
- }
1799
2498
  #endif /* multiplicity */
1800
2499
 
1801
2500
  #if EV_VERIFY
1802
- static void noinline
2501
+ static void noinline ecb_cold
1803
2502
  verify_watcher (EV_P_ W w)
1804
2503
  {
1805
2504
  assert (("libev: watcher has invalid priority", ABSPRI (w) >= 0 && ABSPRI (w) < NUMPRI));
@@ -1808,7 +2507,7 @@ verify_watcher (EV_P_ W w)
1808
2507
  assert (("libev: pending watcher not on pending queue", pendings [ABSPRI (w)][w->pending - 1].w == w));
1809
2508
  }
1810
2509
 
1811
- static void noinline
2510
+ static void noinline ecb_cold
1812
2511
  verify_heap (EV_P_ ANHE *heap, int N)
1813
2512
  {
1814
2513
  int i;
@@ -1823,7 +2522,7 @@ verify_heap (EV_P_ ANHE *heap, int N)
1823
2522
  }
1824
2523
  }
1825
2524
 
1826
- static void noinline
2525
+ static void noinline ecb_cold
1827
2526
  array_verify (EV_P_ W *ws, int cnt)
1828
2527
  {
1829
2528
  while (cnt--)
@@ -1834,9 +2533,9 @@ array_verify (EV_P_ W *ws, int cnt)
1834
2533
  }
1835
2534
  #endif
1836
2535
 
1837
- #if EV_MINIMAL < 2
1838
- void
1839
- ev_loop_verify (EV_P)
2536
+ #if EV_FEATURE_API
2537
+ void ecb_cold
2538
+ ev_verify (EV_P)
1840
2539
  {
1841
2540
  #if EV_VERIFY
1842
2541
  int i;
@@ -1880,32 +2579,42 @@ ev_loop_verify (EV_P)
1880
2579
  array_verify (EV_A_ (W *)forks, forkcnt);
1881
2580
  #endif
1882
2581
 
2582
+ #if EV_CLEANUP_ENABLE
2583
+ assert (cleanupmax >= cleanupcnt);
2584
+ array_verify (EV_A_ (W *)cleanups, cleanupcnt);
2585
+ #endif
2586
+
1883
2587
  #if EV_ASYNC_ENABLE
1884
2588
  assert (asyncmax >= asynccnt);
1885
2589
  array_verify (EV_A_ (W *)asyncs, asynccnt);
1886
2590
  #endif
1887
2591
 
2592
+ #if EV_PREPARE_ENABLE
1888
2593
  assert (preparemax >= preparecnt);
1889
2594
  array_verify (EV_A_ (W *)prepares, preparecnt);
2595
+ #endif
1890
2596
 
2597
+ #if EV_CHECK_ENABLE
1891
2598
  assert (checkmax >= checkcnt);
1892
2599
  array_verify (EV_A_ (W *)checks, checkcnt);
2600
+ #endif
1893
2601
 
1894
2602
  # if 0
1895
- for (w = (ev_child *)childs [chain & (EV_PID_HASHSIZE - 1)]; w; w = (ev_child *)((WL)w)->next)
2603
+ #if EV_CHILD_ENABLE
2604
+ for (w = (ev_child *)childs [chain & ((EV_PID_HASHSIZE) - 1)]; w; w = (ev_child *)((WL)w)->next)
1896
2605
  for (signum = EV_NSIG; signum--; ) if (signals [signum].pending)
2606
+ #endif
1897
2607
  # endif
1898
2608
  #endif
1899
2609
  }
1900
2610
  #endif
1901
2611
 
1902
2612
  #if EV_MULTIPLICITY
1903
- struct ev_loop *
1904
- ev_default_loop_init (unsigned int flags)
2613
+ struct ev_loop * ecb_cold
1905
2614
  #else
1906
2615
  int
1907
- ev_default_loop (unsigned int flags)
1908
2616
  #endif
2617
+ ev_default_loop (unsigned int flags)
1909
2618
  {
1910
2619
  if (!ev_default_loop_ptr)
1911
2620
  {
@@ -1919,7 +2628,7 @@ ev_default_loop (unsigned int flags)
1919
2628
 
1920
2629
  if (ev_backend (EV_A))
1921
2630
  {
1922
- #ifndef _WIN32
2631
+ #if EV_CHILD_ENABLE
1923
2632
  ev_signal_init (&childev, childcb, SIGCHLD);
1924
2633
  ev_set_priority (&childev, EV_MAXPRI);
1925
2634
  ev_signal_start (EV_A_ &childev);
@@ -1934,30 +2643,9 @@ ev_default_loop (unsigned int flags)
1934
2643
  }
1935
2644
 
1936
2645
  void
1937
- ev_default_destroy (void)
1938
- {
1939
- #if EV_MULTIPLICITY
1940
- EV_P = ev_default_loop_ptr;
1941
- #endif
1942
-
1943
- ev_default_loop_ptr = 0;
1944
-
1945
- #ifndef _WIN32
1946
- ev_ref (EV_A); /* child watcher */
1947
- ev_signal_stop (EV_A_ &childev);
1948
- #endif
1949
-
1950
- loop_destroy (EV_A);
1951
- }
1952
-
1953
- void
1954
- ev_default_fork (void)
2646
+ ev_loop_fork (EV_P)
1955
2647
  {
1956
- #if EV_MULTIPLICITY
1957
- EV_P = ev_default_loop_ptr;
1958
- #endif
1959
-
1960
- postfork = 1; /* must be in line with ev_loop_fork */
2648
+ postfork = 1; /* must be in line with ev_default_fork */
1961
2649
  }
1962
2650
 
1963
2651
  /*****************************************************************************/
@@ -1990,9 +2678,6 @@ ev_invoke_pending (EV_P)
1990
2678
  {
1991
2679
  ANPENDING *p = pendings [pri] + --pendingcnt [pri];
1992
2680
 
1993
- /*assert (("libev: non-pending watcher on pending list", p->w->pending));*/
1994
- /* ^ this is no longer true, as pending_w could be here */
1995
-
1996
2681
  p->w->pending = 0;
1997
2682
  EV_CB_INVOKE (p->w, p->events);
1998
2683
  EV_FREQUENT_CHECK;
@@ -2058,11 +2743,36 @@ timers_reify (EV_P)
2058
2743
  }
2059
2744
  while (timercnt && ANHE_at (timers [HEAP0]) < mn_now);
2060
2745
 
2061
- feed_reverse_done (EV_A_ EV_TIMEOUT);
2746
+ feed_reverse_done (EV_A_ EV_TIMER);
2062
2747
  }
2063
2748
  }
2064
2749
 
2065
2750
  #if EV_PERIODIC_ENABLE
2751
+
2752
+ static void noinline
2753
+ periodic_recalc (EV_P_ ev_periodic *w)
2754
+ {
2755
+ ev_tstamp interval = w->interval > MIN_INTERVAL ? w->interval : MIN_INTERVAL;
2756
+ ev_tstamp at = w->offset + interval * ev_floor ((ev_rt_now - w->offset) / interval);
2757
+
2758
+ /* the above almost always errs on the low side */
2759
+ while (at <= ev_rt_now)
2760
+ {
2761
+ ev_tstamp nat = at + w->interval;
2762
+
2763
+ /* when resolution fails us, we use ev_rt_now */
2764
+ if (expect_false (nat == at))
2765
+ {
2766
+ at = ev_rt_now;
2767
+ break;
2768
+ }
2769
+
2770
+ at = nat;
2771
+ }
2772
+
2773
+ ev_at (w) = at;
2774
+ }
2775
+
2066
2776
  /* make periodics pending */
2067
2777
  inline_size void
2068
2778
  periodics_reify (EV_P)
@@ -2091,20 +2801,7 @@ periodics_reify (EV_P)
2091
2801
  }
2092
2802
  else if (w->interval)
2093
2803
  {
2094
- ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
2095
- /* if next trigger time is not sufficiently in the future, put it there */
2096
- /* this might happen because of floating point inexactness */
2097
- if (ev_at (w) - ev_rt_now < TIME_EPSILON)
2098
- {
2099
- ev_at (w) += w->interval;
2100
-
2101
- /* if interval is unreasonably low we might still have a time in the past */
2102
- /* so correct this. this will make the periodic very inexact, but the user */
2103
- /* has effectively asked to get triggered more often than possible */
2104
- if (ev_at (w) < ev_rt_now)
2105
- ev_at (w) = ev_rt_now;
2106
- }
2107
-
2804
+ periodic_recalc (EV_A_ w);
2108
2805
  ANHE_at_cache (periodics [HEAP0]);
2109
2806
  downheap (periodics, periodiccnt, HEAP0);
2110
2807
  }
@@ -2121,8 +2818,8 @@ periodics_reify (EV_P)
2121
2818
  }
2122
2819
 
2123
2820
  /* simply recalculate all periodics */
2124
- /* TODO: maybe ensure that at leats one event happens when jumping forward? */
2125
- static void noinline
2821
+ /* TODO: maybe ensure that at least one event happens when jumping forward? */
2822
+ static void noinline ecb_cold
2126
2823
  periodics_reschedule (EV_P)
2127
2824
  {
2128
2825
  int i;
@@ -2135,7 +2832,7 @@ periodics_reschedule (EV_P)
2135
2832
  if (w->reschedule_cb)
2136
2833
  ev_at (w) = w->reschedule_cb (w, ev_rt_now);
2137
2834
  else if (w->interval)
2138
- ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
2835
+ periodic_recalc (EV_A_ w);
2139
2836
 
2140
2837
  ANHE_at_cache (periodics [i]);
2141
2838
  }
@@ -2145,7 +2842,7 @@ periodics_reschedule (EV_P)
2145
2842
  #endif
2146
2843
 
2147
2844
  /* adjust all timers by a given offset */
2148
- static void noinline
2845
+ static void noinline ecb_cold
2149
2846
  timers_reschedule (EV_P_ ev_tstamp adjust)
2150
2847
  {
2151
2848
  int i;
@@ -2159,7 +2856,7 @@ timers_reschedule (EV_P_ ev_tstamp adjust)
2159
2856
  }
2160
2857
 
2161
2858
  /* fetch new monotonic and realtime times from the kernel */
2162
- /* also detetc if there was a timejump, and act accordingly */
2859
+ /* also detect if there was a timejump, and act accordingly */
2163
2860
  inline_speed void
2164
2861
  time_update (EV_P_ ev_tstamp max_block)
2165
2862
  {
@@ -2192,9 +2889,12 @@ time_update (EV_P_ ev_tstamp max_block)
2192
2889
  */
2193
2890
  for (i = 4; --i; )
2194
2891
  {
2892
+ ev_tstamp diff;
2195
2893
  rtmn_diff = ev_rt_now - mn_now;
2196
2894
 
2197
- if (expect_true (fabs (odiff - rtmn_diff) < MIN_TIMEJUMP))
2895
+ diff = odiff - rtmn_diff;
2896
+
2897
+ if (expect_true ((diff < 0. ? -diff : diff) < MIN_TIMEJUMP))
2198
2898
  return; /* all is well */
2199
2899
 
2200
2900
  ev_rt_now = ev_time ();
@@ -2227,22 +2927,22 @@ time_update (EV_P_ ev_tstamp max_block)
2227
2927
  }
2228
2928
 
2229
2929
  void
2230
- ev_loop (EV_P_ int flags)
2930
+ ev_run (EV_P_ int flags)
2231
2931
  {
2232
- #if EV_MINIMAL < 2
2932
+ #if EV_FEATURE_API
2233
2933
  ++loop_depth;
2234
2934
  #endif
2235
2935
 
2236
- assert (("libev: ev_loop recursion during release detected", loop_done != EVUNLOOP_RECURSE));
2936
+ assert (("libev: ev_loop recursion during release detected", loop_done != EVBREAK_RECURSE));
2237
2937
 
2238
- loop_done = EVUNLOOP_CANCEL;
2938
+ loop_done = EVBREAK_CANCEL;
2239
2939
 
2240
2940
  EV_INVOKE_PENDING; /* in case we recurse, ensure ordering stays nice and clean */
2241
2941
 
2242
2942
  do
2243
2943
  {
2244
2944
  #if EV_VERIFY >= 2
2245
- ev_loop_verify (EV_A);
2945
+ ev_verify (EV_A);
2246
2946
  #endif
2247
2947
 
2248
2948
  #ifndef _WIN32
@@ -2264,12 +2964,14 @@ ev_loop (EV_P_ int flags)
2264
2964
  }
2265
2965
  #endif
2266
2966
 
2967
+ #if EV_PREPARE_ENABLE
2267
2968
  /* queue prepare watchers (and execute them) */
2268
2969
  if (expect_false (preparecnt))
2269
2970
  {
2270
2971
  queue_events (EV_A_ (W *)prepares, preparecnt, EV_PREPARE);
2271
2972
  EV_INVOKE_PENDING;
2272
2973
  }
2974
+ #endif
2273
2975
 
2274
2976
  if (expect_false (loop_done))
2275
2977
  break;
@@ -2286,26 +2988,31 @@ ev_loop (EV_P_ int flags)
2286
2988
  ev_tstamp waittime = 0.;
2287
2989
  ev_tstamp sleeptime = 0.;
2288
2990
 
2289
- if (expect_true (!(flags & EVLOOP_NONBLOCK || idleall || !activecnt)))
2290
- {
2291
- /* remember old timestamp for io_blocktime calculation */
2292
- ev_tstamp prev_mn_now = mn_now;
2991
+ /* remember old timestamp for io_blocktime calculation */
2992
+ ev_tstamp prev_mn_now = mn_now;
2993
+
2994
+ /* update time to cancel out callback processing overhead */
2995
+ time_update (EV_A_ 1e100);
2293
2996
 
2294
- /* update time to cancel out callback processing overhead */
2295
- time_update (EV_A_ 1e100);
2997
+ /* from now on, we want a pipe-wake-up */
2998
+ pipe_write_wanted = 1;
2296
2999
 
3000
+ ECB_MEMORY_FENCE; /* make sure pipe_write_wanted is visible before we check for potential skips */
3001
+
3002
+ if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped)))
3003
+ {
2297
3004
  waittime = MAX_BLOCKTIME;
2298
3005
 
2299
3006
  if (timercnt)
2300
3007
  {
2301
- ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now + backend_fudge;
3008
+ ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now;
2302
3009
  if (waittime > to) waittime = to;
2303
3010
  }
2304
3011
 
2305
3012
  #if EV_PERIODIC_ENABLE
2306
3013
  if (periodiccnt)
2307
3014
  {
2308
- ev_tstamp to = ANHE_at (periodics [HEAP0]) - ev_rt_now + backend_fudge;
3015
+ ev_tstamp to = ANHE_at (periodics [HEAP0]) - ev_rt_now;
2309
3016
  if (waittime > to) waittime = to;
2310
3017
  }
2311
3018
  #endif
@@ -2314,13 +3021,18 @@ ev_loop (EV_P_ int flags)
2314
3021
  if (expect_false (waittime < timeout_blocktime))
2315
3022
  waittime = timeout_blocktime;
2316
3023
 
3024
+ /* at this point, we NEED to wait, so we have to ensure */
3025
+ /* to pass a minimum nonzero value to the backend */
3026
+ if (expect_false (waittime < backend_mintime))
3027
+ waittime = backend_mintime;
3028
+
2317
3029
  /* extra check because io_blocktime is commonly 0 */
2318
3030
  if (expect_false (io_blocktime))
2319
3031
  {
2320
3032
  sleeptime = io_blocktime - (mn_now - prev_mn_now);
2321
3033
 
2322
- if (sleeptime > waittime - backend_fudge)
2323
- sleeptime = waittime - backend_fudge;
3034
+ if (sleeptime > waittime - backend_mintime)
3035
+ sleeptime = waittime - backend_mintime;
2324
3036
 
2325
3037
  if (expect_true (sleeptime > 0.))
2326
3038
  {
@@ -2330,12 +3042,21 @@ ev_loop (EV_P_ int flags)
2330
3042
  }
2331
3043
  }
2332
3044
 
2333
- #if EV_MINIMAL < 2
3045
+ #if EV_FEATURE_API
2334
3046
  ++loop_count;
2335
3047
  #endif
2336
- assert ((loop_done = EVUNLOOP_RECURSE, 1)); /* assert for side effect */
3048
+ assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */
2337
3049
  backend_poll (EV_A_ waittime);
2338
- assert ((loop_done = EVUNLOOP_CANCEL, 1)); /* assert for side effect */
3050
+ assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */
3051
+
3052
+ pipe_write_wanted = 0; /* just an optimisation, no fence needed */
3053
+
3054
+ if (pipe_write_skipped)
3055
+ {
3056
+ assert (("libev: pipe_w not active, but pipe not written", ev_is_active (&pipe_w)));
3057
+ ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM);
3058
+ }
3059
+
2339
3060
 
2340
3061
  /* update ev_rt_now, do magic */
2341
3062
  time_update (EV_A_ waittime + sleeptime);
@@ -2352,28 +3073,30 @@ ev_loop (EV_P_ int flags)
2352
3073
  idle_reify (EV_A);
2353
3074
  #endif
2354
3075
 
3076
+ #if EV_CHECK_ENABLE
2355
3077
  /* queue check watchers, to be executed first */
2356
3078
  if (expect_false (checkcnt))
2357
3079
  queue_events (EV_A_ (W *)checks, checkcnt, EV_CHECK);
3080
+ #endif
2358
3081
 
2359
3082
  EV_INVOKE_PENDING;
2360
3083
  }
2361
3084
  while (expect_true (
2362
3085
  activecnt
2363
3086
  && !loop_done
2364
- && !(flags & (EVLOOP_ONESHOT | EVLOOP_NONBLOCK))
3087
+ && !(flags & (EVRUN_ONCE | EVRUN_NOWAIT))
2365
3088
  ));
2366
3089
 
2367
- if (loop_done == EVUNLOOP_ONE)
2368
- loop_done = EVUNLOOP_CANCEL;
3090
+ if (loop_done == EVBREAK_ONE)
3091
+ loop_done = EVBREAK_CANCEL;
2369
3092
 
2370
- #if EV_MINIMAL < 2
3093
+ #if EV_FEATURE_API
2371
3094
  --loop_depth;
2372
3095
  #endif
2373
3096
  }
2374
3097
 
2375
3098
  void
2376
- ev_unloop (EV_P_ int how)
3099
+ ev_break (EV_P_ int how)
2377
3100
  {
2378
3101
  loop_done = how;
2379
3102
  }
@@ -2503,7 +3226,7 @@ ev_io_start (EV_P_ ev_io *w)
2503
3226
  return;
2504
3227
 
2505
3228
  assert (("libev: ev_io_start called with negative fd", fd >= 0));
2506
- assert (("libev: ev_io start called with illegal event mask", !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE))));
3229
+ assert (("libev: ev_io_start called with illegal event mask", !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE))));
2507
3230
 
2508
3231
  EV_FREQUENT_CHECK;
2509
3232
 
@@ -2531,7 +3254,7 @@ ev_io_stop (EV_P_ ev_io *w)
2531
3254
  wlist_del (&anfds[w->fd].head, (WL)w);
2532
3255
  ev_stop (EV_A_ (W)w);
2533
3256
 
2534
- fd_change (EV_A_ w->fd, 1);
3257
+ fd_change (EV_A_ w->fd, EV_ANFD_REIFY);
2535
3258
 
2536
3259
  EV_FREQUENT_CHECK;
2537
3260
  }
@@ -2583,11 +3306,11 @@ ev_timer_stop (EV_P_ ev_timer *w)
2583
3306
  }
2584
3307
  }
2585
3308
 
2586
- EV_FREQUENT_CHECK;
2587
-
2588
3309
  ev_at (w) -= mn_now;
2589
3310
 
2590
3311
  ev_stop (EV_A_ (W)w);
3312
+
3313
+ EV_FREQUENT_CHECK;
2591
3314
  }
2592
3315
 
2593
3316
  void noinline
@@ -2595,6 +3318,8 @@ ev_timer_again (EV_P_ ev_timer *w)
2595
3318
  {
2596
3319
  EV_FREQUENT_CHECK;
2597
3320
 
3321
+ clear_pending (EV_A_ (W)w);
3322
+
2598
3323
  if (ev_is_active (w))
2599
3324
  {
2600
3325
  if (w->repeat)
@@ -2633,8 +3358,7 @@ ev_periodic_start (EV_P_ ev_periodic *w)
2633
3358
  else if (w->interval)
2634
3359
  {
2635
3360
  assert (("libev: ev_periodic_start called with negative interval value", w->interval >= 0.));
2636
- /* this formula differs from the one in periodic_reify because we do not always round up */
2637
- ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
3361
+ periodic_recalc (EV_A_ w);
2638
3362
  }
2639
3363
  else
2640
3364
  ev_at (w) = w->offset;
@@ -2676,9 +3400,9 @@ ev_periodic_stop (EV_P_ ev_periodic *w)
2676
3400
  }
2677
3401
  }
2678
3402
 
2679
- EV_FREQUENT_CHECK;
2680
-
2681
3403
  ev_stop (EV_A_ (W)w);
3404
+
3405
+ EV_FREQUENT_CHECK;
2682
3406
  }
2683
3407
 
2684
3408
  void noinline
@@ -2694,6 +3418,8 @@ ev_periodic_again (EV_P_ ev_periodic *w)
2694
3418
  # define SA_RESTART 0
2695
3419
  #endif
2696
3420
 
3421
+ #if EV_SIGNAL_ENABLE
3422
+
2697
3423
  void noinline
2698
3424
  ev_signal_start (EV_P_ ev_signal *w)
2699
3425
  {
@@ -2749,7 +3475,7 @@ ev_signal_start (EV_P_ ev_signal *w)
2749
3475
  if (sigfd < 0) /*TODO*/
2750
3476
  # endif
2751
3477
  {
2752
- # if _WIN32
3478
+ # ifdef _WIN32
2753
3479
  evpipe_init (EV_A);
2754
3480
 
2755
3481
  signal (w->signum, ev_sighandler);
@@ -2763,9 +3489,12 @@ ev_signal_start (EV_P_ ev_signal *w)
2763
3489
  sa.sa_flags = SA_RESTART; /* if restarting works we save one iteration */
2764
3490
  sigaction (w->signum, &sa, 0);
2765
3491
 
2766
- sigemptyset (&sa.sa_mask);
2767
- sigaddset (&sa.sa_mask, w->signum);
2768
- sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0);
3492
+ if (origflags & EVFLAG_NOSIGMASK)
3493
+ {
3494
+ sigemptyset (&sa.sa_mask);
3495
+ sigaddset (&sa.sa_mask, w->signum);
3496
+ sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0);
3497
+ }
2769
3498
  #endif
2770
3499
  }
2771
3500
 
@@ -2809,6 +3538,10 @@ ev_signal_stop (EV_P_ ev_signal *w)
2809
3538
  EV_FREQUENT_CHECK;
2810
3539
  }
2811
3540
 
3541
+ #endif
3542
+
3543
+ #if EV_CHILD_ENABLE
3544
+
2812
3545
  void
2813
3546
  ev_child_start (EV_P_ ev_child *w)
2814
3547
  {
@@ -2821,7 +3554,7 @@ ev_child_start (EV_P_ ev_child *w)
2821
3554
  EV_FREQUENT_CHECK;
2822
3555
 
2823
3556
  ev_start (EV_A_ (W)w, 1);
2824
- wlist_add (&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w);
3557
+ wlist_add (&childs [w->pid & ((EV_PID_HASHSIZE) - 1)], (WL)w);
2825
3558
 
2826
3559
  EV_FREQUENT_CHECK;
2827
3560
  }
@@ -2835,12 +3568,14 @@ ev_child_stop (EV_P_ ev_child *w)
2835
3568
 
2836
3569
  EV_FREQUENT_CHECK;
2837
3570
 
2838
- wlist_del (&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w);
3571
+ wlist_del (&childs [w->pid & ((EV_PID_HASHSIZE) - 1)], (WL)w);
2839
3572
  ev_stop (EV_A_ (W)w);
2840
3573
 
2841
3574
  EV_FREQUENT_CHECK;
2842
3575
  }
2843
3576
 
3577
+ #endif
3578
+
2844
3579
  #if EV_STAT_ENABLE
2845
3580
 
2846
3581
  # ifdef _WIN32
@@ -2855,7 +3590,9 @@ ev_child_stop (EV_P_ ev_child *w)
2855
3590
  static void noinline stat_timer_cb (EV_P_ ev_timer *w_, int revents);
2856
3591
 
2857
3592
  #if EV_USE_INOTIFY
2858
- # define EV_INOTIFY_BUFSIZE 8192
3593
+
3594
+ /* the * 2 is to allow for alignment padding, which for some reason is >> 8 */
3595
+ # define EV_INOTIFY_BUFSIZE (sizeof (struct inotify_event) * 2 + NAME_MAX)
2859
3596
 
2860
3597
  static void noinline
2861
3598
  infy_add (EV_P_ ev_stat *w)
@@ -2908,13 +3645,13 @@ infy_add (EV_P_ ev_stat *w)
2908
3645
 
2909
3646
  *pend = 0;
2910
3647
  w->wd = inotify_add_watch (fs_fd, path, mask);
2911
- }
3648
+ }
2912
3649
  while (w->wd < 0 && (errno == ENOENT || errno == EACCES));
2913
3650
  }
2914
3651
  }
2915
3652
 
2916
3653
  if (w->wd >= 0)
2917
- wlist_add (&fs_hash [w->wd & (EV_INOTIFY_HASHSIZE - 1)].head, (WL)w);
3654
+ wlist_add (&fs_hash [w->wd & ((EV_INOTIFY_HASHSIZE) - 1)].head, (WL)w);
2918
3655
 
2919
3656
  /* now re-arm timer, if required */
2920
3657
  if (ev_is_active (&w->timer)) ev_ref (EV_A);
@@ -2932,7 +3669,7 @@ infy_del (EV_P_ ev_stat *w)
2932
3669
  return;
2933
3670
 
2934
3671
  w->wd = -2;
2935
- slot = wd & (EV_INOTIFY_HASHSIZE - 1);
3672
+ slot = wd & ((EV_INOTIFY_HASHSIZE) - 1);
2936
3673
  wlist_del (&fs_hash [slot].head, (WL)w);
2937
3674
 
2938
3675
  /* remove this watcher, if others are watching it, they will rearm */
@@ -2944,13 +3681,13 @@ infy_wd (EV_P_ int slot, int wd, struct inotify_event *ev)
2944
3681
  {
2945
3682
  if (slot < 0)
2946
3683
  /* overflow, need to check for all hash slots */
2947
- for (slot = 0; slot < EV_INOTIFY_HASHSIZE; ++slot)
3684
+ for (slot = 0; slot < (EV_INOTIFY_HASHSIZE); ++slot)
2948
3685
  infy_wd (EV_A_ slot, wd, ev);
2949
3686
  else
2950
3687
  {
2951
3688
  WL w_;
2952
3689
 
2953
- for (w_ = fs_hash [slot & (EV_INOTIFY_HASHSIZE - 1)].head; w_; )
3690
+ for (w_ = fs_hash [slot & ((EV_INOTIFY_HASHSIZE) - 1)].head; w_; )
2954
3691
  {
2955
3692
  ev_stat *w = (ev_stat *)w_;
2956
3693
  w_ = w_->next; /* lets us remove this watcher and all before it */
@@ -2959,7 +3696,7 @@ infy_wd (EV_P_ int slot, int wd, struct inotify_event *ev)
2959
3696
  {
2960
3697
  if (ev->mask & (IN_IGNORED | IN_UNMOUNT | IN_DELETE_SELF))
2961
3698
  {
2962
- wlist_del (&fs_hash [slot & (EV_INOTIFY_HASHSIZE - 1)].head, (WL)w);
3699
+ wlist_del (&fs_hash [slot & ((EV_INOTIFY_HASHSIZE) - 1)].head, (WL)w);
2963
3700
  w->wd = -1;
2964
3701
  infy_add (EV_A_ w); /* re-add, no matter what */
2965
3702
  }
@@ -2974,32 +3711,24 @@ static void
2974
3711
  infy_cb (EV_P_ ev_io *w, int revents)
2975
3712
  {
2976
3713
  char buf [EV_INOTIFY_BUFSIZE];
2977
- struct inotify_event *ev = (struct inotify_event *)buf;
2978
3714
  int ofs;
2979
3715
  int len = read (fs_fd, buf, sizeof (buf));
2980
3716
 
2981
- for (ofs = 0; ofs < len; ofs += sizeof (struct inotify_event) + ev->len)
2982
- infy_wd (EV_A_ ev->wd, ev->wd, ev);
3717
+ for (ofs = 0; ofs < len; )
3718
+ {
3719
+ struct inotify_event *ev = (struct inotify_event *)(buf + ofs);
3720
+ infy_wd (EV_A_ ev->wd, ev->wd, ev);
3721
+ ofs += sizeof (struct inotify_event) + ev->len;
3722
+ }
2983
3723
  }
2984
3724
 
2985
- inline_size void
2986
- check_2625 (EV_P)
3725
+ inline_size void ecb_cold
3726
+ ev_check_2625 (EV_P)
2987
3727
  {
2988
3728
  /* kernels < 2.6.25 are borked
2989
3729
  * http://www.ussg.indiana.edu/hypermail/linux/kernel/0711.3/1208.html
2990
3730
  */
2991
- struct utsname buf;
2992
- int major, minor, micro;
2993
-
2994
- if (uname (&buf))
2995
- return;
2996
-
2997
- if (sscanf (buf.release, "%d.%d.%d", &major, &minor, &micro) != 3)
2998
- return;
2999
-
3000
- if (major < 2
3001
- || (major == 2 && minor < 6)
3002
- || (major == 2 && minor == 6 && micro < 25))
3731
+ if (ev_linux_version () < 0x020619)
3003
3732
  return;
3004
3733
 
3005
3734
  fs_2625 = 1;
@@ -3024,7 +3753,7 @@ infy_init (EV_P)
3024
3753
 
3025
3754
  fs_fd = -1;
3026
3755
 
3027
- check_2625 (EV_A);
3756
+ ev_check_2625 (EV_A);
3028
3757
 
3029
3758
  fs_fd = infy_newfd ();
3030
3759
 
@@ -3059,7 +3788,7 @@ infy_fork (EV_P)
3059
3788
  ev_unref (EV_A);
3060
3789
  }
3061
3790
 
3062
- for (slot = 0; slot < EV_INOTIFY_HASHSIZE; ++slot)
3791
+ for (slot = 0; slot < (EV_INOTIFY_HASHSIZE); ++slot)
3063
3792
  {
3064
3793
  WL w_ = fs_hash [slot].head;
3065
3794
  fs_hash [slot].head = 0;
@@ -3244,6 +3973,7 @@ ev_idle_stop (EV_P_ ev_idle *w)
3244
3973
  }
3245
3974
  #endif
3246
3975
 
3976
+ #if EV_PREPARE_ENABLE
3247
3977
  void
3248
3978
  ev_prepare_start (EV_P_ ev_prepare *w)
3249
3979
  {
@@ -3279,7 +4009,9 @@ ev_prepare_stop (EV_P_ ev_prepare *w)
3279
4009
 
3280
4010
  EV_FREQUENT_CHECK;
3281
4011
  }
4012
+ #endif
3282
4013
 
4014
+ #if EV_CHECK_ENABLE
3283
4015
  void
3284
4016
  ev_check_start (EV_P_ ev_check *w)
3285
4017
  {
@@ -3315,12 +4047,13 @@ ev_check_stop (EV_P_ ev_check *w)
3315
4047
 
3316
4048
  EV_FREQUENT_CHECK;
3317
4049
  }
4050
+ #endif
3318
4051
 
3319
4052
  #if EV_EMBED_ENABLE
3320
4053
  void noinline
3321
4054
  ev_embed_sweep (EV_P_ ev_embed *w)
3322
4055
  {
3323
- ev_loop (w->other, EVLOOP_NONBLOCK);
4056
+ ev_run (w->other, EVRUN_NOWAIT);
3324
4057
  }
3325
4058
 
3326
4059
  static void
@@ -3331,7 +4064,7 @@ embed_io_cb (EV_P_ ev_io *io, int revents)
3331
4064
  if (ev_cb (w))
3332
4065
  ev_feed_event (EV_A_ (W)w, EV_EMBED);
3333
4066
  else
3334
- ev_loop (w->other, EVLOOP_NONBLOCK);
4067
+ ev_run (w->other, EVRUN_NOWAIT);
3335
4068
  }
3336
4069
 
3337
4070
  static void
@@ -3345,7 +4078,7 @@ embed_prepare_cb (EV_P_ ev_prepare *prepare, int revents)
3345
4078
  while (fdchangecnt)
3346
4079
  {
3347
4080
  fd_reify (EV_A);
3348
- ev_loop (EV_A_ EVLOOP_NONBLOCK);
4081
+ ev_run (EV_A_ EVRUN_NOWAIT);
3349
4082
  }
3350
4083
  }
3351
4084
  }
@@ -3361,7 +4094,7 @@ embed_fork_cb (EV_P_ ev_fork *fork_w, int revents)
3361
4094
  EV_P = w->other;
3362
4095
 
3363
4096
  ev_loop_fork (EV_A);
3364
- ev_loop (EV_A_ EVLOOP_NONBLOCK);
4097
+ ev_run (EV_A_ EVRUN_NOWAIT);
3365
4098
  }
3366
4099
 
3367
4100
  ev_embed_start (EV_A_ w);
@@ -3419,6 +4152,8 @@ ev_embed_stop (EV_P_ ev_embed *w)
3419
4152
  ev_prepare_stop (EV_A_ &w->prepare);
3420
4153
  ev_fork_stop (EV_A_ &w->fork);
3421
4154
 
4155
+ ev_stop (EV_A_ (W)w);
4156
+
3422
4157
  EV_FREQUENT_CHECK;
3423
4158
  }
3424
4159
  #endif
@@ -3461,6 +4196,47 @@ ev_fork_stop (EV_P_ ev_fork *w)
3461
4196
  }
3462
4197
  #endif
3463
4198
 
4199
+ #if EV_CLEANUP_ENABLE
4200
+ void
4201
+ ev_cleanup_start (EV_P_ ev_cleanup *w)
4202
+ {
4203
+ if (expect_false (ev_is_active (w)))
4204
+ return;
4205
+
4206
+ EV_FREQUENT_CHECK;
4207
+
4208
+ ev_start (EV_A_ (W)w, ++cleanupcnt);
4209
+ array_needsize (ev_cleanup *, cleanups, cleanupmax, cleanupcnt, EMPTY2);
4210
+ cleanups [cleanupcnt - 1] = w;
4211
+
4212
+ /* cleanup watchers should never keep a refcount on the loop */
4213
+ ev_unref (EV_A);
4214
+ EV_FREQUENT_CHECK;
4215
+ }
4216
+
4217
+ void
4218
+ ev_cleanup_stop (EV_P_ ev_cleanup *w)
4219
+ {
4220
+ clear_pending (EV_A_ (W)w);
4221
+ if (expect_false (!ev_is_active (w)))
4222
+ return;
4223
+
4224
+ EV_FREQUENT_CHECK;
4225
+ ev_ref (EV_A);
4226
+
4227
+ {
4228
+ int active = ev_active (w);
4229
+
4230
+ cleanups [active - 1] = cleanups [--cleanupcnt];
4231
+ ev_active (cleanups [active - 1]) = active;
4232
+ }
4233
+
4234
+ ev_stop (EV_A_ (W)w);
4235
+
4236
+ EV_FREQUENT_CHECK;
4237
+ }
4238
+ #endif
4239
+
3464
4240
  #if EV_ASYNC_ENABLE
3465
4241
  void
3466
4242
  ev_async_start (EV_P_ ev_async *w)
@@ -3468,6 +4244,8 @@ ev_async_start (EV_P_ ev_async *w)
3468
4244
  if (expect_false (ev_is_active (w)))
3469
4245
  return;
3470
4246
 
4247
+ w->sent = 0;
4248
+
3471
4249
  evpipe_init (EV_A);
3472
4250
 
3473
4251
  EV_FREQUENT_CHECK;
@@ -3554,7 +4332,7 @@ ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, vo
3554
4332
 
3555
4333
  if (expect_false (!once))
3556
4334
  {
3557
- cb (EV_ERROR | EV_READ | EV_WRITE | EV_TIMEOUT, arg);
4335
+ cb (EV_ERROR | EV_READ | EV_WRITE | EV_TIMER, arg);
3558
4336
  return;
3559
4337
  }
3560
4338
 
@@ -3579,7 +4357,7 @@ ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, vo
3579
4357
  /*****************************************************************************/
3580
4358
 
3581
4359
  #if EV_WALK_ENABLE
3582
- void
4360
+ void ecb_cold
3583
4361
  ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w))
3584
4362
  {
3585
4363
  int i, j;
@@ -3633,7 +4411,7 @@ ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w))
3633
4411
 
3634
4412
  #if EV_IDLE_ENABLE
3635
4413
  if (types & EV_IDLE)
3636
- for (j = NUMPRI; i--; )
4414
+ for (j = NUMPRI; j--; )
3637
4415
  for (i = idlecnt [j]; i--; )
3638
4416
  cb (EV_A_ EV_IDLE, idles [j][i]);
3639
4417
  #endif
@@ -3651,17 +4429,22 @@ ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w))
3651
4429
  cb (EV_A_ EV_ASYNC, asyncs [i]);
3652
4430
  #endif
3653
4431
 
4432
+ #if EV_PREPARE_ENABLE
3654
4433
  if (types & EV_PREPARE)
3655
4434
  for (i = preparecnt; i--; )
3656
- #if EV_EMBED_ENABLE
4435
+ # if EV_EMBED_ENABLE
3657
4436
  if (ev_cb (prepares [i]) != embed_prepare_cb)
3658
- #endif
4437
+ # endif
3659
4438
  cb (EV_A_ EV_PREPARE, prepares [i]);
4439
+ #endif
3660
4440
 
4441
+ #if EV_CHECK_ENABLE
3661
4442
  if (types & EV_CHECK)
3662
4443
  for (i = checkcnt; i--; )
3663
4444
  cb (EV_A_ EV_CHECK, checks [i]);
4445
+ #endif
3664
4446
 
4447
+ #if EV_SIGNAL_ENABLE
3665
4448
  if (types & EV_SIGNAL)
3666
4449
  for (i = 0; i < EV_NSIG - 1; ++i)
3667
4450
  for (wl = signals [i].head; wl; )
@@ -3670,15 +4453,18 @@ ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w))
3670
4453
  cb (EV_A_ EV_SIGNAL, wl);
3671
4454
  wl = wn;
3672
4455
  }
4456
+ #endif
3673
4457
 
4458
+ #if EV_CHILD_ENABLE
3674
4459
  if (types & EV_CHILD)
3675
- for (i = EV_PID_HASHSIZE; i--; )
4460
+ for (i = (EV_PID_HASHSIZE); i--; )
3676
4461
  for (wl = childs [i]; wl; )
3677
4462
  {
3678
4463
  wn = wl->next;
3679
4464
  cb (EV_A_ EV_CHILD, wl);
3680
4465
  wl = wn;
3681
4466
  }
4467
+ #endif
3682
4468
  /* EV_STAT 0x00001000 /* stat data changed */
3683
4469
  /* EV_EMBED 0x00010000 /* embedded event loop needs sweep */
3684
4470
  }
@@ -3688,7 +4474,3 @@ ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w))
3688
4474
  #include "ev_wrap.h"
3689
4475
  #endif
3690
4476
 
3691
- #ifdef __cplusplus
3692
- }
3693
- #endif
3694
-