passenger 4.0.20 → 4.0.21

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (496) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/.gitignore +1 -0
  5. data/.travis.yml +1 -1
  6. data/NEWS +15 -0
  7. data/README.md +5 -3
  8. data/Rakefile +1 -0
  9. data/bin/passenger-config +1 -5
  10. data/bin/passenger-install-apache2-module +53 -5
  11. data/bin/passenger-install-nginx-module +19 -6
  12. data/bin/passenger-memory-stats +3 -3
  13. data/build/agents.rb +11 -8
  14. data/build/apache2.rb +9 -5
  15. data/build/basics.rb +15 -21
  16. data/build/common_library.rb +16 -6
  17. data/build/cplusplus_support.rb +5 -5
  18. data/build/cxx_tests.rb +3 -3
  19. data/build/documentation.rb +1 -1
  20. data/build/misc.rb +4 -37
  21. data/build/node_tests.rb +29 -0
  22. data/build/oxt_tests.rb +1 -1
  23. data/build/packaging.rb +29 -10
  24. data/build/preprocessor.rb +2 -1
  25. data/build/test_basics.rb +15 -6
  26. data/debian.template/locations.ini.template +1 -0
  27. data/debian.template/passenger.install.template +1 -0
  28. data/dev/copy_boost_headers.rb +7 -3
  29. data/dev/run_travis.sh +32 -16
  30. data/doc/Users guide Apache.idmap.txt +22 -34
  31. data/doc/Users guide Apache.txt +20 -234
  32. data/doc/Users guide Nginx.idmap.txt +84 -66
  33. data/doc/Users guide Nginx.txt +50 -1
  34. data/doc/Users guide Standalone.idmap.txt +74 -0
  35. data/doc/Users guide Standalone.txt +22 -9
  36. data/doc/Users guide.txt +51 -0
  37. data/doc/users_guide_snippets/environment_variables.txt +0 -3
  38. data/doc/users_guide_snippets/installation.txt +337 -380
  39. data/doc/users_guide_snippets/installation/run_installer.txt +58 -0
  40. data/doc/users_guide_snippets/installation/verify_running_epilogue.txt +6 -0
  41. data/doc/users_guide_snippets/support_information.txt +2 -9
  42. data/doc/users_guide_snippets/troubleshooting/default.txt +112 -0
  43. data/doc/users_guide_snippets/troubleshooting/rails.txt +56 -0
  44. data/doc/users_guide_snippets/where_to_get_support.txt +9 -0
  45. data/ext/apache2/Bucket.h +1 -1
  46. data/ext/apache2/Configuration.hpp +0 -44
  47. data/ext/apache2/CreateDirConfig.cpp +1 -1
  48. data/ext/apache2/CreateDirConfig.cpp.erb +1 -1
  49. data/ext/apache2/Hooks.cpp +28 -21
  50. data/ext/apache2/MergeDirConfig.cpp +1 -0
  51. data/ext/apache2/MergeDirConfig.cpp.erb +1 -1
  52. data/ext/apache2/SetHeaders.cpp +73 -0
  53. data/ext/apache2/SetHeaders.cpp.erb +88 -0
  54. data/ext/boost/algorithm/string/detail/find_format.hpp +5 -5
  55. data/ext/boost/algorithm/string/detail/find_format_all.hpp +5 -5
  56. data/ext/boost/algorithm/string/detail/finder.hpp +1 -1
  57. data/ext/boost/algorithm/string/formatter.hpp +2 -2
  58. data/ext/boost/assert.hpp +6 -1
  59. data/ext/boost/atomic.hpp +18 -0
  60. data/ext/boost/atomic/atomic.hpp +241 -0
  61. data/ext/boost/atomic/detail/base.hpp +585 -0
  62. data/ext/boost/atomic/detail/cas32strong.hpp +885 -0
  63. data/ext/boost/atomic/detail/cas32weak.hpp +947 -0
  64. data/ext/boost/atomic/detail/cas64strong.hpp +443 -0
  65. data/ext/boost/atomic/detail/config.hpp +54 -0
  66. data/ext/boost/atomic/detail/gcc-alpha.hpp +368 -0
  67. data/ext/boost/atomic/detail/gcc-armv6plus.hpp +252 -0
  68. data/ext/boost/atomic/detail/gcc-cas.hpp +157 -0
  69. data/ext/boost/atomic/detail/gcc-ppc.hpp +2850 -0
  70. data/ext/boost/atomic/detail/gcc-sparcv9.hpp +1259 -0
  71. data/ext/boost/atomic/detail/gcc-x86.hpp +1766 -0
  72. data/ext/boost/atomic/detail/generic-cas.hpp +206 -0
  73. data/ext/boost/atomic/detail/interlocked.hpp +200 -0
  74. data/ext/boost/atomic/detail/linux-arm.hpp +189 -0
  75. data/ext/boost/atomic/detail/lockpool.hpp +97 -0
  76. data/ext/boost/atomic/detail/platform.hpp +62 -0
  77. data/ext/boost/atomic/detail/type-classification.hpp +45 -0
  78. data/ext/boost/chrono/config.hpp +8 -3
  79. data/ext/boost/chrono/duration.hpp +9 -10
  80. data/ext/boost/chrono/system_clocks.hpp +1 -1
  81. data/ext/boost/chrono/time_point.hpp +4 -3
  82. data/ext/boost/config/auto_link.hpp +53 -52
  83. data/ext/boost/config/compiler/borland.hpp +1 -0
  84. data/ext/boost/config/compiler/clang.hpp +24 -1
  85. data/ext/boost/config/compiler/codegear.hpp +1 -0
  86. data/ext/boost/config/compiler/common_edg.hpp +1 -0
  87. data/ext/boost/config/compiler/cray.hpp +1 -0
  88. data/ext/boost/config/compiler/digitalmars.hpp +1 -0
  89. data/ext/boost/config/compiler/gcc.hpp +29 -3
  90. data/ext/boost/config/compiler/gcc_xml.hpp +2 -1
  91. data/ext/boost/config/compiler/hp_acc.hpp +1 -0
  92. data/ext/boost/config/compiler/intel.hpp +1 -1
  93. data/ext/boost/config/compiler/metrowerks.hpp +1 -0
  94. data/ext/boost/config/compiler/mpw.hpp +1 -0
  95. data/ext/boost/config/compiler/pathscale.hpp +1 -0
  96. data/ext/boost/config/compiler/pgi.hpp +1 -0
  97. data/ext/boost/config/compiler/sunpro_cc.hpp +1 -0
  98. data/ext/boost/config/compiler/vacpp.hpp +3 -2
  99. data/ext/boost/config/compiler/visualc.hpp +25 -11
  100. data/ext/boost/config/platform/vxworks.hpp +353 -15
  101. data/ext/boost/config/select_compiler_config.hpp +4 -4
  102. data/ext/boost/config/stdlib/dinkumware.hpp +10 -3
  103. data/ext/boost/config/stdlib/libstdcpp3.hpp +2 -1
  104. data/ext/boost/config/suffix.hpp +45 -19
  105. data/ext/boost/date_time/format_date_parser.hpp +1 -11
  106. data/ext/boost/date_time/strings_from_facet.hpp +5 -3
  107. data/ext/boost/detail/atomic_redef_macros.hpp +19 -0
  108. data/ext/boost/detail/atomic_undef_macros.hpp +39 -0
  109. data/ext/boost/detail/endian.hpp +52 -4
  110. data/ext/boost/detail/scoped_enum_emulation.hpp +10 -10
  111. data/ext/boost/detail/select_type.hpp +36 -0
  112. data/ext/boost/exception/current_exception_cast.hpp +1 -1
  113. data/ext/boost/exception/detail/error_info_impl.hpp +3 -5
  114. data/ext/boost/exception/detail/exception_ptr.hpp +3 -3
  115. data/ext/boost/exception/detail/is_output_streamable.hpp +1 -1
  116. data/ext/boost/exception/detail/object_hex_dump.hpp +1 -1
  117. data/ext/boost/exception/detail/type_info.hpp +1 -1
  118. data/ext/boost/exception/diagnostic_information.hpp +15 -14
  119. data/ext/boost/exception/exception.hpp +1 -1
  120. data/ext/boost/exception/get_error_info.hpp +1 -1
  121. data/ext/boost/exception/info.hpp +12 -13
  122. data/ext/boost/exception/to_string.hpp +6 -1
  123. data/ext/boost/exception/to_string_stub.hpp +9 -1
  124. data/ext/boost/foreach.hpp +5 -5
  125. data/ext/boost/function/function_template.hpp +6 -6
  126. data/ext/boost/functional/hash/detail/float_functions.hpp +90 -0
  127. data/ext/boost/functional/hash/detail/hash_float.hpp +11 -2
  128. data/ext/boost/functional/hash/extensions.hpp +14 -2
  129. data/ext/boost/functional/hash/hash.hpp +26 -5
  130. data/ext/boost/get_pointer.hpp +17 -2
  131. data/ext/boost/integer_traits.hpp +1 -1
  132. data/ext/boost/lexical_cast.hpp +615 -395
  133. data/ext/boost/libs/atomic/lockpool.cpp +24 -0
  134. data/ext/boost/libs/system/src/error_code.cpp +25 -18
  135. data/ext/boost/libs/thread/src/future.cpp +7 -5
  136. data/ext/boost/libs/thread/src/pthread/once.cpp +9 -3
  137. data/ext/boost/libs/thread/src/pthread/once_atomic.cpp +90 -0
  138. data/ext/boost/libs/thread/src/pthread/thread.cpp +129 -95
  139. data/ext/boost/libs/thread/src/pthread/timeconv.inl +20 -1
  140. data/ext/boost/limits.hpp +1 -1
  141. data/ext/boost/math/policies/policy.hpp +10 -0
  142. data/ext/boost/math/special_functions/detail/round_fwd.hpp +17 -4
  143. data/ext/boost/math/special_functions/fpclassify.hpp +114 -45
  144. data/ext/boost/math/special_functions/math_fwd.hpp +195 -83
  145. data/ext/boost/math/special_functions/sign.hpp +13 -8
  146. data/ext/boost/math/tools/config.hpp +38 -16
  147. data/ext/boost/move/algorithm.hpp +275 -0
  148. data/ext/boost/move/core.hpp +332 -0
  149. data/ext/boost/move/detail/config_begin.hpp +23 -0
  150. data/ext/boost/move/detail/config_end.hpp +20 -0
  151. data/ext/boost/move/detail/meta_utils.hpp +158 -0
  152. data/ext/boost/move/iterator.hpp +298 -0
  153. data/ext/boost/move/move.hpp +10 -1256
  154. data/ext/boost/move/traits.hpp +142 -0
  155. data/ext/boost/move/utility.hpp +194 -0
  156. data/ext/boost/mpl/assert.hpp +72 -4
  157. data/ext/boost/noncopyable.hpp +15 -3
  158. data/ext/boost/pointer_to_other.hpp +55 -0
  159. data/ext/boost/range/concepts.hpp +4 -4
  160. data/ext/boost/range/detail/extract_optional_type.hpp +1 -1
  161. data/ext/boost/range/empty.hpp +1 -1
  162. data/ext/boost/range/iterator_range_core.hpp +4 -1
  163. data/ext/boost/range/iterator_range_io.hpp +2 -2
  164. data/ext/boost/ratio/config.hpp +6 -0
  165. data/ext/boost/ratio/detail/overflow_helpers.hpp +2 -2
  166. data/ext/boost/smart_ptr/allocate_shared_array.hpp +250 -0
  167. data/ext/boost/smart_ptr/detail/allocate_array_helper.hpp +169 -0
  168. data/ext/boost/smart_ptr/detail/array_deleter.hpp +124 -0
  169. data/ext/boost/smart_ptr/detail/array_traits.hpp +53 -0
  170. data/ext/boost/smart_ptr/detail/array_utility.hpp +178 -0
  171. data/ext/boost/smart_ptr/detail/make_array_helper.hpp +157 -0
  172. data/ext/boost/smart_ptr/detail/operator_bool.hpp +16 -9
  173. data/ext/boost/smart_ptr/detail/shared_count.hpp +78 -7
  174. data/ext/boost/smart_ptr/detail/sp_convertible.hpp +15 -0
  175. data/ext/boost/smart_ptr/detail/sp_counted_base.hpp +12 -6
  176. data/ext/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp +1 -0
  177. data/ext/boost/smart_ptr/detail/sp_counted_base_aix.hpp +1 -0
  178. data/ext/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp +1 -0
  179. data/ext/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp +1 -0
  180. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp +1 -0
  181. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +1 -0
  182. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp +1 -0
  183. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp +1 -0
  184. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp +1 -0
  185. data/ext/boost/smart_ptr/detail/sp_counted_base_nt.hpp +1 -0
  186. data/ext/boost/smart_ptr/detail/sp_counted_base_pt.hpp +1 -0
  187. data/ext/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp +162 -0
  188. data/ext/boost/smart_ptr/detail/sp_counted_base_solaris.hpp +1 -0
  189. data/ext/boost/smart_ptr/detail/sp_counted_base_spin.hpp +1 -0
  190. data/ext/boost/smart_ptr/detail/sp_counted_base_sync.hpp +1 -0
  191. data/ext/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp +1 -0
  192. data/ext/boost/smart_ptr/detail/sp_counted_impl.hpp +15 -0
  193. data/ext/boost/smart_ptr/detail/sp_forward.hpp +39 -0
  194. data/ext/boost/smart_ptr/detail/sp_has_sync.hpp +19 -3
  195. data/ext/boost/smart_ptr/detail/sp_if_array.hpp +31 -0
  196. data/ext/boost/smart_ptr/detail/sp_nullptr_t.hpp +45 -0
  197. data/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +5 -12
  198. data/ext/boost/smart_ptr/enable_shared_from_this.hpp +4 -4
  199. data/ext/boost/smart_ptr/make_shared.hpp +5 -1060
  200. data/ext/boost/smart_ptr/make_shared_array.hpp +247 -0
  201. data/ext/boost/smart_ptr/make_shared_object.hpp +1128 -0
  202. data/ext/boost/smart_ptr/scoped_array.hpp +32 -7
  203. data/ext/boost/smart_ptr/scoped_ptr.hpp +31 -5
  204. data/ext/boost/smart_ptr/shared_array.hpp +135 -20
  205. data/ext/boost/smart_ptr/shared_ptr.hpp +444 -126
  206. data/ext/boost/smart_ptr/weak_ptr.hpp +39 -28
  207. data/ext/boost/static_assert.hpp +74 -17
  208. data/ext/boost/system/error_code.hpp +76 -68
  209. data/ext/boost/system/system_error.hpp +5 -1
  210. data/ext/boost/thread/barrier.hpp +6 -2
  211. data/ext/boost/thread/completion_latch.hpp +233 -0
  212. data/ext/boost/thread/condition.hpp +6 -1
  213. data/ext/boost/thread/detail/async_func.hpp +571 -0
  214. data/ext/boost/thread/detail/config.hpp +248 -40
  215. data/ext/boost/thread/detail/counter.hpp +93 -0
  216. data/ext/boost/thread/detail/delete.hpp +12 -0
  217. data/ext/boost/thread/detail/invoke.hpp +1351 -0
  218. data/ext/boost/thread/detail/is_convertible.hpp +48 -0
  219. data/ext/boost/thread/detail/lockable_wrapper.hpp +45 -0
  220. data/ext/boost/thread/detail/log.hpp +83 -0
  221. data/ext/boost/thread/detail/make_tuple_indices.hpp +224 -0
  222. data/ext/boost/thread/detail/move.hpp +32 -16
  223. data/ext/boost/thread/detail/thread.hpp +236 -41
  224. data/ext/boost/thread/detail/thread_group.hpp +55 -9
  225. data/ext/boost/thread/detail/thread_interruption.hpp +4 -1
  226. data/ext/boost/thread/exceptions.hpp +2 -0
  227. data/ext/boost/thread/externally_locked.hpp +351 -0
  228. data/ext/boost/thread/externally_locked_stream.hpp +170 -0
  229. data/ext/boost/thread/future.hpp +2517 -455
  230. data/ext/boost/thread/future_error_code.hpp +61 -0
  231. data/ext/boost/thread/is_locked_by_this_thread.hpp +39 -0
  232. data/ext/boost/thread/latch.hpp +142 -0
  233. data/ext/boost/thread/lock_algorithms.hpp +468 -0
  234. data/ext/boost/thread/lock_concepts.hpp +197 -0
  235. data/ext/boost/thread/lock_factories.hpp +78 -0
  236. data/ext/boost/thread/lock_guard.hpp +88 -0
  237. data/ext/boost/thread/lock_options.hpp +31 -0
  238. data/ext/boost/thread/lock_traits.hpp +45 -0
  239. data/ext/boost/thread/lock_types.hpp +1226 -0
  240. data/ext/boost/thread/lockable_adapter.hpp +226 -0
  241. data/ext/boost/thread/lockable_concepts.hpp +157 -0
  242. data/ext/boost/thread/lockable_traits.hpp +207 -0
  243. data/ext/boost/thread/locks.hpp +5 -1816
  244. data/ext/boost/thread/mutex.hpp +33 -1
  245. data/ext/boost/thread/null_mutex.hpp +243 -0
  246. data/ext/boost/thread/once.hpp +10 -1
  247. data/ext/boost/thread/poly_lockable.hpp +68 -0
  248. data/ext/boost/thread/poly_lockable_adapter.hpp +89 -0
  249. data/ext/boost/thread/poly_shared_lockable.hpp +135 -0
  250. data/ext/boost/thread/poly_shared_lockable_adapter.hpp +170 -0
  251. data/ext/boost/thread/pthread/condition_variable.hpp +74 -26
  252. data/ext/boost/thread/pthread/condition_variable_fwd.hpp +54 -27
  253. data/ext/boost/thread/pthread/mutex.hpp +101 -38
  254. data/ext/boost/thread/pthread/once.hpp +459 -44
  255. data/ext/boost/thread/pthread/once_atomic.hpp +313 -0
  256. data/ext/boost/thread/pthread/recursive_mutex.hpp +19 -10
  257. data/ext/boost/thread/pthread/shared_mutex.hpp +226 -61
  258. data/ext/boost/thread/pthread/shared_mutex_assert.hpp +724 -0
  259. data/ext/boost/thread/pthread/thread_data.hpp +53 -50
  260. data/ext/boost/thread/pthread/timespec.hpp +96 -12
  261. data/ext/boost/thread/recursive_mutex.hpp +44 -1
  262. data/ext/boost/thread/reverse_lock.hpp +3 -2
  263. data/ext/boost/thread/scoped_thread.hpp +285 -0
  264. data/ext/boost/thread/shared_lock_guard.hpp +2 -1
  265. data/ext/boost/thread/shared_mutex.hpp +23 -0
  266. data/ext/boost/thread/strict_lock.hpp +235 -0
  267. data/ext/boost/thread/sync_bounded_queue.hpp +594 -0
  268. data/ext/boost/thread/sync_queue.hpp +516 -0
  269. data/ext/boost/thread/synchronized_value.hpp +1001 -0
  270. data/ext/boost/thread/testable_mutex.hpp +148 -0
  271. data/ext/boost/thread/thread.hpp +1 -13
  272. data/ext/boost/thread/thread_functors.hpp +57 -0
  273. data/ext/boost/thread/thread_guard.hpp +46 -0
  274. data/ext/boost/thread/thread_only.hpp +29 -0
  275. data/ext/boost/thread/v2/shared_mutex.hpp +1062 -0
  276. data/ext/boost/thread/v2/thread.hpp +37 -10
  277. data/ext/boost/thread/xtime.hpp +2 -1
  278. data/ext/boost/token_functions.hpp +16 -16
  279. data/ext/boost/type_traits/add_lvalue_reference.hpp +26 -0
  280. data/ext/boost/type_traits/add_reference.hpp +1 -1
  281. data/ext/boost/type_traits/add_rvalue_reference.hpp +4 -4
  282. data/ext/boost/type_traits/aligned_storage.hpp +13 -0
  283. data/ext/boost/type_traits/common_type.hpp +11 -12
  284. data/ext/boost/type_traits/config.hpp +1 -1
  285. data/ext/boost/type_traits/detail/common_type_imp.hpp +1 -1
  286. data/ext/boost/type_traits/detail/has_binary_operator.hpp +1 -1
  287. data/ext/boost/type_traits/detail/is_function_ptr_tester.hpp +1 -1
  288. data/ext/boost/type_traits/has_left_shift.hpp +49 -0
  289. data/ext/boost/type_traits/has_right_shift.hpp +49 -0
  290. data/ext/boost/type_traits/has_trivial_move_assign.hpp +57 -0
  291. data/ext/boost/type_traits/has_trivial_move_constructor.hpp +57 -0
  292. data/ext/boost/type_traits/intrinsics.hpp +18 -2
  293. data/ext/boost/type_traits/is_abstract.hpp +1 -1
  294. data/ext/boost/type_traits/is_array.hpp +1 -1
  295. data/ext/boost/type_traits/is_const.hpp +1 -1
  296. data/ext/boost/type_traits/is_convertible.hpp +78 -17
  297. data/ext/boost/type_traits/is_function.hpp +6 -1
  298. data/ext/boost/type_traits/is_integral.hpp +6 -1
  299. data/ext/boost/type_traits/is_nothrow_move_assignable.hpp +84 -0
  300. data/ext/boost/type_traits/is_nothrow_move_constructible.hpp +84 -0
  301. data/ext/boost/type_traits/is_pod.hpp +3 -1
  302. data/ext/boost/type_traits/is_rvalue_reference.hpp +1 -1
  303. data/ext/boost/type_traits/is_volatile.hpp +1 -1
  304. data/ext/boost/type_traits/make_signed.hpp +153 -0
  305. data/ext/boost/type_traits/make_unsigned.hpp +16 -0
  306. data/ext/boost/type_traits/remove_const.hpp +1 -1
  307. data/ext/boost/type_traits/remove_cv.hpp +1 -1
  308. data/ext/boost/type_traits/remove_reference.hpp +1 -1
  309. data/ext/boost/type_traits/remove_volatile.hpp +1 -1
  310. data/ext/boost/unordered/detail/allocate.hpp +1120 -0
  311. data/ext/boost/unordered/detail/buckets.hpp +876 -0
  312. data/ext/boost/unordered/detail/equivalent.hpp +680 -0
  313. data/ext/boost/unordered/detail/extract_key.hpp +183 -0
  314. data/ext/boost/unordered/detail/fwd.hpp +23 -0
  315. data/ext/boost/unordered/detail/table.hpp +861 -0
  316. data/ext/boost/unordered/detail/unique.hpp +622 -0
  317. data/ext/boost/unordered/detail/util.hpp +260 -0
  318. data/ext/boost/unordered/unordered_map.hpp +1652 -0
  319. data/ext/boost/unordered/unordered_map_fwd.hpp +65 -0
  320. data/ext/boost/unordered/unordered_set.hpp +1549 -0
  321. data/ext/boost/unordered/unordered_set_fwd.hpp +63 -0
  322. data/ext/boost/unordered_map.hpp +18 -0
  323. data/ext/boost/unordered_set.hpp +18 -0
  324. data/ext/boost/utility/addressof.hpp +2 -2
  325. data/ext/boost/utility/result_of.hpp +8 -1
  326. data/ext/boost/version.hpp +2 -2
  327. data/ext/common/Account.h +1 -1
  328. data/ext/common/AccountsDatabase.h +1 -1
  329. data/ext/common/AgentsStarter.cpp +3 -1
  330. data/ext/common/AgentsStarter.h +2 -2
  331. data/ext/common/ApplicationPool2/AppTypes.cpp +24 -6
  332. data/ext/common/ApplicationPool2/AppTypes.h +17 -8
  333. data/ext/common/ApplicationPool2/Common.h +12 -12
  334. data/ext/common/ApplicationPool2/DirectSpawner.h +2 -2
  335. data/ext/common/ApplicationPool2/DummySpawner.h +3 -3
  336. data/ext/common/ApplicationPool2/Group.h +6 -6
  337. data/ext/common/ApplicationPool2/Implementation.cpp +19 -19
  338. data/ext/common/ApplicationPool2/PipeWatcher.h +5 -5
  339. data/ext/common/ApplicationPool2/Pool.h +21 -21
  340. data/ext/common/ApplicationPool2/Process.h +6 -6
  341. data/ext/common/ApplicationPool2/Session.h +1 -1
  342. data/ext/common/ApplicationPool2/SmartSpawner.h +24 -12
  343. data/ext/common/ApplicationPool2/Socket.h +2 -2
  344. data/ext/common/ApplicationPool2/Spawner.h +64 -14
  345. data/ext/common/ApplicationPool2/SpawnerFactory.h +7 -7
  346. data/ext/common/ApplicationPool2/SuperGroup.h +5 -5
  347. data/ext/common/BackgroundEventLoop.cpp +4 -4
  348. data/ext/common/BackgroundEventLoop.h +1 -1
  349. data/ext/common/Constants.h +13 -1
  350. data/ext/common/EventedBufferedInput.h +8 -8
  351. data/ext/common/Exceptions.cpp +71 -0
  352. data/ext/common/Exceptions.h +60 -7
  353. data/ext/common/FileDescriptor.h +4 -4
  354. data/ext/common/MessageClient.h +1 -1
  355. data/ext/common/MessageServer.h +5 -5
  356. data/ext/common/MultiLibeio.cpp +3 -3
  357. data/ext/common/MultiLibeio.h +2 -2
  358. data/ext/common/RandomGenerator.h +11 -11
  359. data/ext/common/ResourceLocator.h +8 -1
  360. data/ext/common/SafeLibev.h +12 -12
  361. data/ext/common/ServerInstanceDir.h +11 -3
  362. data/ext/common/UnionStation.h +10 -10
  363. data/ext/common/Utils.cpp +11 -13
  364. data/ext/common/Utils.h +9 -9
  365. data/ext/common/Utils/BlockingQueue.h +10 -10
  366. data/ext/common/Utils/BufferedIO.h +1 -1
  367. data/ext/common/Utils/CachedFileStat.hpp +2 -2
  368. data/ext/common/Utils/FileChangeChecker.h +1 -1
  369. data/ext/common/Utils/HashMap.h +13 -4
  370. data/ext/common/Utils/IOUtils.cpp +33 -10
  371. data/ext/common/Utils/IniFile.h +3 -3
  372. data/ext/common/Utils/Lock.h +2 -2
  373. data/ext/common/Utils/MessagePassing.h +10 -10
  374. data/ext/common/Utils/ProcessMetricsCollector.h +24 -6
  375. data/ext/common/Utils/ScopeGuard.h +5 -5
  376. data/ext/common/Utils/jsoncpp.cpp +2 -0
  377. data/ext/common/agents/HelperAgent/FileBackedPipe.h +26 -26
  378. data/ext/common/agents/HelperAgent/Main.cpp +18 -18
  379. data/ext/common/agents/HelperAgent/RequestHandler.cpp +4 -4
  380. data/ext/common/agents/HelperAgent/RequestHandler.h +30 -21
  381. data/ext/common/agents/LoggingAgent/AdminController.h +1 -1
  382. data/ext/common/agents/LoggingAgent/FilterSupport.h +13 -11
  383. data/ext/common/agents/LoggingAgent/LoggingServer.h +11 -11
  384. data/ext/common/agents/LoggingAgent/Main.cpp +9 -9
  385. data/ext/common/agents/LoggingAgent/RemoteSender.h +3 -3
  386. data/ext/common/agents/SpawnPreparer.cpp +1 -0
  387. data/ext/common/agents/Watchdog/AgentWatcher.cpp +8 -7
  388. data/ext/common/agents/Watchdog/Main.cpp +81 -73
  389. data/ext/common/agents/Watchdog/ServerInstanceDirToucher.cpp +1 -1
  390. data/ext/libev/Changes +57 -0
  391. data/ext/libev/LICENSE +2 -1
  392. data/ext/libev/Makefile.in +110 -50
  393. data/ext/libev/README +8 -8
  394. data/ext/libev/aclocal.m4 +1503 -861
  395. data/ext/libev/config.guess +290 -304
  396. data/ext/libev/config.sub +77 -198
  397. data/ext/libev/configure +1735 -890
  398. data/ext/libev/configure.ac +3 -2
  399. data/ext/libev/ev++.h +6 -6
  400. data/ext/libev/ev.c +541 -214
  401. data/ext/libev/ev.h +106 -100
  402. data/ext/libev/ev_epoll.c +1 -1
  403. data/ext/libev/ev_kqueue.c +20 -4
  404. data/ext/libev/ev_vars.h +15 -16
  405. data/ext/libev/ev_win32.c +12 -2
  406. data/ext/libev/ev_wrap.h +162 -160
  407. data/ext/libev/event.c +29 -6
  408. data/ext/libev/event.h +9 -2
  409. data/ext/libev/ltmain.sh +2632 -1384
  410. data/ext/nginx/ConfigurationCommands.c +1 -1
  411. data/ext/nginx/ConfigurationCommands.c.erb +3 -1
  412. data/ext/nginx/ContentHandler.c +25 -2
  413. data/ext/nginx/CreateLocationConfig.c +1 -0
  414. data/ext/nginx/CreateLocationConfig.c.erb +1 -1
  415. data/ext/nginx/MergeLocationConfig.c +1 -0
  416. data/ext/nginx/MergeLocationConfig.c.erb +1 -1
  417. data/ext/nginx/config +12 -0
  418. data/ext/oxt/dynamic_thread_group.hpp +7 -4
  419. data/ext/oxt/system_calls.cpp +5 -1
  420. data/ext/oxt/system_calls.hpp +3 -0
  421. data/helper-scripts/node-loader.js +117 -249
  422. data/lib/phusion_passenger.rb +27 -5
  423. data/lib/phusion_passenger/abstract_installer.rb +104 -9
  424. data/lib/phusion_passenger/admin_tools/memory_stats.rb +10 -9
  425. data/lib/phusion_passenger/apache2/config_options.rb +6 -3
  426. data/lib/phusion_passenger/common_library.rb +7 -1
  427. data/lib/phusion_passenger/constants.rb +6 -0
  428. data/lib/phusion_passenger/loader_shared_helpers.rb +7 -4
  429. data/lib/phusion_passenger/nginx/config_options.rb +2 -1
  430. data/lib/phusion_passenger/packaging.rb +3 -0
  431. data/lib/phusion_passenger/platform_info/apache.rb +43 -6
  432. data/lib/phusion_passenger/platform_info/apache_detector.rb +15 -5
  433. data/lib/phusion_passenger/platform_info/compiler.rb +167 -32
  434. data/lib/phusion_passenger/platform_info/cxx_portability.rb +133 -77
  435. data/lib/phusion_passenger/platform_info/depcheck.rb +17 -7
  436. data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +3 -3
  437. data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
  438. data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +5 -6
  439. data/lib/phusion_passenger/platform_info/linux.rb +2 -1
  440. data/lib/phusion_passenger/platform_info/operating_system.rb +1 -1
  441. data/lib/phusion_passenger/platform_info/ruby.rb +18 -3
  442. data/lib/phusion_passenger/standalone/runtime_installer.rb +6 -2
  443. data/lib/phusion_passenger/standalone/start_command.rb +8 -2
  444. data/lib/phusion_passenger/utils/ansi_colors.rb +9 -0
  445. data/lib/phusion_passenger/utils/hosts_file_parser.rb +4 -2
  446. data/node_lib/phusion_passenger/httplib_emulation.js +141 -0
  447. data/node_lib/phusion_passenger/line_reader.js +154 -0
  448. data/node_lib/phusion_passenger/request_handler.js +65 -0
  449. data/node_lib/phusion_passenger/session_protocol_parser.js +113 -0
  450. data/resources/templates/apache2/deployment_example.txt.erb +2 -1
  451. data/resources/templates/apache2/installing_against_a_different_apache.txt.erb +14 -0
  452. data/resources/templates/apache2/multiple_apache_installations_detected.txt.erb +15 -0
  453. data/resources/templates/apache2/possible_solutions_for_compilation_and_installation_problems.txt.erb +4 -5
  454. data/resources/templates/general_error_with_html.html.template +1 -1
  455. data/resources/templates/installer_common/gem_install_permission_problems.txt.erb +17 -0
  456. data/resources/templates/installer_common/low_amount_of_memory_warning.txt.erb +6 -4
  457. data/resources/templates/installer_common/world_inaccessible_directories.txt.erb +16 -0
  458. data/resources/templates/nginx/deployment_example.txt.erb +2 -1
  459. data/resources/templates/nginx/possible_solutions_for_compilation_and_installation_problems.txt.erb +4 -5
  460. data/resources/templates/standalone/config.erb +1 -0
  461. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +3 -3
  462. data/test/cxx/ApplicationPool2/PoolTest.cpp +4 -4
  463. data/test/cxx/ApplicationPool2/ProcessTest.cpp +5 -5
  464. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +5 -5
  465. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +1 -1
  466. data/test/cxx/EventedBufferedInputTest.cpp +6 -6
  467. data/test/cxx/FileBackedPipeTest.cpp +1 -1
  468. data/test/cxx/MessagePassingTest.cpp +1 -1
  469. data/test/cxx/MessageServerTest.cpp +4 -4
  470. data/test/cxx/RequestHandlerTest.cpp +7 -7
  471. data/test/cxx/UnionStationTest.cpp +2 -2
  472. data/test/node/line_reader_spec.js +338 -0
  473. data/test/node/spec_helper.js +27 -0
  474. data/test/ruby/standalone/runtime_installer_spec.rb +2 -1
  475. metadata +131 -22
  476. metadata.gz.asc +7 -7
  477. data/ext/boost/functional/hash/detail/container_fwd_0x.hpp +0 -29
  478. data/ext/boost/lambda/core.hpp +0 -79
  479. data/ext/boost/lambda/detail/actions.hpp +0 -174
  480. data/ext/boost/lambda/detail/arity_code.hpp +0 -110
  481. data/ext/boost/lambda/detail/function_adaptors.hpp +0 -789
  482. data/ext/boost/lambda/detail/is_instance_of.hpp +0 -104
  483. data/ext/boost/lambda/detail/lambda_config.hpp +0 -48
  484. data/ext/boost/lambda/detail/lambda_functor_base.hpp +0 -615
  485. data/ext/boost/lambda/detail/lambda_functors.hpp +0 -324
  486. data/ext/boost/lambda/detail/lambda_fwd.hpp +0 -74
  487. data/ext/boost/lambda/detail/lambda_traits.hpp +0 -578
  488. data/ext/boost/lambda/detail/member_ptr.hpp +0 -737
  489. data/ext/boost/lambda/detail/operator_actions.hpp +0 -139
  490. data/ext/boost/lambda/detail/operator_lambda_func_base.hpp +0 -271
  491. data/ext/boost/lambda/detail/operator_return_type_traits.hpp +0 -917
  492. data/ext/boost/lambda/detail/operators.hpp +0 -370
  493. data/ext/boost/lambda/detail/ret.hpp +0 -325
  494. data/ext/boost/lambda/detail/return_type_traits.hpp +0 -282
  495. data/ext/boost/lambda/detail/select_functions.hpp +0 -74
  496. data/ext/boost/lambda/lambda.hpp +0 -34
@@ -1,9 +1,10 @@
1
+ AC_INIT
2
+
1
3
  orig_CFLAGS="$CFLAGS"
2
4
 
3
- AC_INIT
4
5
  AC_CONFIG_SRCDIR([ev_epoll.c])
5
6
 
6
- AM_INIT_AUTOMAKE(libev,4.11) dnl also update ev.h!
7
+ AM_INIT_AUTOMAKE(libev,4.15) dnl also update ev.h!
7
8
  AC_CONFIG_HEADERS([config.h])
8
9
  AM_MAINTAINER_MODE
9
10
 
@@ -286,7 +286,7 @@ namespace ev {
286
286
  template<class K, void (K::*method)(int)>
287
287
  static void method_thunk (int revents, void *arg)
288
288
  {
289
- static_cast<K *>(arg)->*method
289
+ (static_cast<K *>(arg)->*method)
290
290
  (revents);
291
291
  }
292
292
 
@@ -300,7 +300,7 @@ namespace ev {
300
300
  template<class K, void (K::*method)()>
301
301
  static void method_noargs_thunk (int revents, void *arg)
302
302
  {
303
- static_cast<K *>(arg)->*method
303
+ (static_cast<K *>(arg)->*method)
304
304
  ();
305
305
  }
306
306
 
@@ -513,7 +513,7 @@ namespace ev {
513
513
 
514
514
  void feed_event (int revents) throw ()
515
515
  {
516
- ev_feed_event (EV_A_ static_cast<const ev_watcher *>(this), revents);
516
+ ev_feed_event (EV_A_ static_cast<ev_watcher *>(this), revents);
517
517
  }
518
518
  };
519
519
 
@@ -552,12 +552,12 @@ namespace ev {
552
552
  return ev_embeddable_backends ();
553
553
  }
554
554
 
555
- inline void set_allocator (void *(*cb)(void *ptr, long size)) throw ()
555
+ inline void set_allocator (void *(*cb)(void *ptr, long size) throw ()) throw ()
556
556
  {
557
557
  ev_set_allocator (cb);
558
558
  }
559
559
 
560
- inline void set_syserr_cb (void (*cb)(const char *msg)) throw ()
560
+ inline void set_syserr_cb (void (*cb)(const char *msg) throw ()) throw ()
561
561
  {
562
562
  ev_set_syserr_cb (cb);
563
563
  }
@@ -764,7 +764,7 @@ namespace ev {
764
764
 
765
765
  #if EV_EMBED_ENABLE
766
766
  EV_BEGIN_WATCHER (embed, embed)
767
- void set (struct ev_loop *embedded_loop) throw ()
767
+ void set_embed (struct ev_loop *embedded_loop) throw ()
768
768
  {
769
769
  int active = is_active ();
770
770
  if (active) stop ();
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * libev event processing core, watcher management
3
3
  *
4
- * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
4
+ * Copyright (c) 2007,2008,2009,2010,2011,2012 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-
@@ -61,7 +61,7 @@
61
61
  # define EV_USE_MONOTONIC 1
62
62
  # endif
63
63
  # endif
64
- # elif !defined(EV_USE_CLOCK_SYSCALL)
64
+ # elif !defined EV_USE_CLOCK_SYSCALL
65
65
  # define EV_USE_CLOCK_SYSCALL 0
66
66
  # endif
67
67
 
@@ -203,6 +203,7 @@
203
203
  #else
204
204
  # include <io.h>
205
205
  # define WIN32_LEAN_AND_MEAN
206
+ # include <winsock2.h>
206
207
  # include <windows.h>
207
208
  # ifndef EV_SELECT_IS_WINSOCKET
208
209
  # define EV_SELECT_IS_WINSOCKET 1
@@ -221,25 +222,25 @@
221
222
  /* this block tries to deduce configuration from header-defined symbols and defaults */
222
223
 
223
224
  /* try to deduce the maximum number of signals on this platform */
224
- #if defined (EV_NSIG)
225
+ #if defined EV_NSIG
225
226
  /* use what's provided */
226
- #elif defined (NSIG)
227
+ #elif defined NSIG
227
228
  # define EV_NSIG (NSIG)
228
- #elif defined(_NSIG)
229
+ #elif defined _NSIG
229
230
  # define EV_NSIG (_NSIG)
230
- #elif defined (SIGMAX)
231
+ #elif defined SIGMAX
231
232
  # define EV_NSIG (SIGMAX+1)
232
- #elif defined (SIG_MAX)
233
+ #elif defined SIG_MAX
233
234
  # define EV_NSIG (SIG_MAX+1)
234
- #elif defined (_SIG_MAX)
235
+ #elif defined _SIG_MAX
235
236
  # define EV_NSIG (_SIG_MAX+1)
236
- #elif defined (MAXSIG)
237
+ #elif defined MAXSIG
237
238
  # define EV_NSIG (MAXSIG+1)
238
- #elif defined (MAX_SIG)
239
+ #elif defined MAX_SIG
239
240
  # define EV_NSIG (MAX_SIG+1)
240
- #elif defined (SIGARRAYSIZE)
241
+ #elif defined SIGARRAYSIZE
241
242
  # define EV_NSIG (SIGARRAYSIZE) /* Assume ary[SIGARRAYSIZE] */
242
- #elif defined (_sys_nsig)
243
+ #elif defined _sys_nsig
243
244
  # define EV_NSIG (_sys_nsig) /* Solaris 2.5 */
244
245
  #else
245
246
  # error "unable to find value for NSIG, please report"
@@ -261,7 +262,7 @@
261
262
  #endif
262
263
 
263
264
  #ifndef EV_USE_MONOTONIC
264
- # if defined (_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
265
+ # if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
265
266
  # define EV_USE_MONOTONIC EV_FEATURE_OS
266
267
  # else
267
268
  # define EV_USE_MONOTONIC 0
@@ -358,10 +359,26 @@
358
359
  # define EV_HEAP_CACHE_AT EV_FEATURE_DATA
359
360
  #endif
360
361
 
362
+ #ifdef ANDROID
363
+ /* supposedly, android doesn't typedef fd_mask */
364
+ # undef EV_USE_SELECT
365
+ # define EV_USE_SELECT 0
366
+ /* supposedly, we need to include syscall.h, not sys/syscall.h, so just disable */
367
+ # undef EV_USE_CLOCK_SYSCALL
368
+ # define EV_USE_CLOCK_SYSCALL 0
369
+ #endif
370
+
371
+ /* aix's poll.h seems to cause lots of trouble */
372
+ #ifdef _AIX
373
+ /* AIX has a completely broken poll.h header */
374
+ # undef EV_USE_POLL
375
+ # define EV_USE_POLL 0
376
+ #endif
377
+
361
378
  /* on linux, we can use a (slow) syscall to avoid a dependency on pthread, */
362
379
  /* which makes programs even slower. might work on other unices, too. */
363
380
  #if EV_USE_CLOCK_SYSCALL
364
- # include <syscall.h>
381
+ # include <sys/syscall.h>
365
382
  # ifdef SYS_clock_gettime
366
383
  # define clock_gettime(id, ts) syscall (SYS_clock_gettime, (id), (ts))
367
384
  # undef EV_USE_MONOTONIC
@@ -374,12 +391,6 @@
374
391
 
375
392
  /* this block fixes any misconfiguration where we know we run into trouble otherwise */
376
393
 
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
-
383
394
  #ifndef CLOCK_MONOTONIC
384
395
  # undef EV_USE_MONOTONIC
385
396
  # define EV_USE_MONOTONIC 0
@@ -397,7 +408,7 @@
397
408
 
398
409
  #if !EV_USE_NANOSLEEP
399
410
  /* hp-ux has it in sys/time.h, which we unconditionally include above */
400
- # if !defined(_WIN32) && !defined(__hpux)
411
+ # if !defined _WIN32 && !defined __hpux
401
412
  # include <sys/select.h>
402
413
  # endif
403
414
  #endif
@@ -412,10 +423,6 @@
412
423
  # endif
413
424
  #endif
414
425
 
415
- #if EV_SELECT_IS_WINSOCKET
416
- # include <winsock.h>
417
- #endif
418
-
419
426
  #if EV_USE_EVENTFD
420
427
  /* our minimum requirement is glibc 2.7 which has the stub, but not the header */
421
428
  # include <stdint.h>
@@ -509,6 +516,9 @@ struct signalfd_siginfo
509
516
  #ifndef ECB_H
510
517
  #define ECB_H
511
518
 
519
+ /* 16 bits major, 16 bits minor */
520
+ #define ECB_VERSION 0x00010003
521
+
512
522
  #ifdef _WIN32
513
523
  typedef signed char int8_t;
514
524
  typedef unsigned char uint8_t;
@@ -523,8 +533,31 @@ struct signalfd_siginfo
523
533
  typedef signed __int64 int64_t;
524
534
  typedef unsigned __int64 uint64_t;
525
535
  #endif
536
+ #ifdef _WIN64
537
+ #define ECB_PTRSIZE 8
538
+ typedef uint64_t uintptr_t;
539
+ typedef int64_t intptr_t;
540
+ #else
541
+ #define ECB_PTRSIZE 4
542
+ typedef uint32_t uintptr_t;
543
+ typedef int32_t intptr_t;
544
+ #endif
526
545
  #else
527
546
  #include <inttypes.h>
547
+ #if UINTMAX_MAX > 0xffffffffU
548
+ #define ECB_PTRSIZE 8
549
+ #else
550
+ #define ECB_PTRSIZE 4
551
+ #endif
552
+ #endif
553
+
554
+ /* work around x32 idiocy by defining proper macros */
555
+ #if __x86_64 || _M_AMD64
556
+ #if __ILP32
557
+ #define ECB_AMD64_X32 1
558
+ #else
559
+ #define ECB_AMD64 1
560
+ #endif
528
561
  #endif
529
562
 
530
563
  /* many compilers define _GNUC_ to some versions but then only implement
@@ -535,65 +568,101 @@ struct signalfd_siginfo
535
568
  * an issue with that they should have done it right in the first place.
536
569
  */
537
570
  #ifndef ECB_GCC_VERSION
538
- #if !defined(__GNUC_MINOR__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__llvm__) || defined(__clang__)
571
+ #if !defined __GNUC_MINOR__ || defined __INTEL_COMPILER || defined __SUNPRO_C || defined __SUNPRO_CC || defined __llvm__ || defined __clang__
539
572
  #define ECB_GCC_VERSION(major,minor) 0
540
573
  #else
541
574
  #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
542
575
  #endif
543
576
  #endif
544
577
 
578
+ #define ECB_C (__STDC__+0) /* this assumes that __STDC__ is either empty or a number */
579
+ #define ECB_C99 (__STDC_VERSION__ >= 199901L)
580
+ #define ECB_C11 (__STDC_VERSION__ >= 201112L)
581
+ #define ECB_CPP (__cplusplus+0)
582
+ #define ECB_CPP11 (__cplusplus >= 201103L)
583
+
584
+ #if ECB_CPP
585
+ #define ECB_EXTERN_C extern "C"
586
+ #define ECB_EXTERN_C_BEG ECB_EXTERN_C {
587
+ #define ECB_EXTERN_C_END }
588
+ #else
589
+ #define ECB_EXTERN_C extern
590
+ #define ECB_EXTERN_C_BEG
591
+ #define ECB_EXTERN_C_END
592
+ #endif
593
+
545
594
  /*****************************************************************************/
546
595
 
547
596
  /* ECB_NO_THREADS - ecb is not used by multiple threads, ever */
548
597
  /* ECB_NO_SMP - ecb might be used in multiple threads, but only on a single cpu */
549
598
 
550
599
  #if ECB_NO_THREADS
551
- # define ECB_NO_SMP 1
600
+ #define ECB_NO_SMP 1
552
601
  #endif
553
602
 
554
- #if ECB_NO_THREADS || ECB_NO_SMP
603
+ #if ECB_NO_SMP
555
604
  #define ECB_MEMORY_FENCE do { } while (0)
556
605
  #endif
557
606
 
558
607
  #ifndef ECB_MEMORY_FENCE
559
- #if ECB_GCC_VERSION(2,5) || defined(__INTEL_COMPILER) || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
608
+ #if ECB_GCC_VERSION(2,5) || defined __INTEL_COMPILER || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
560
609
  #if __i386 || __i386__
561
610
  #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 */
611
+ #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory")
612
+ #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
564
613
  #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 */
614
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mfence" : : : "memory")
615
+ #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory")
616
+ #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
568
617
  #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")
618
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory")
619
+ #elif defined __ARM_ARCH_6__ || defined __ARM_ARCH_6J__ \
620
+ || defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6ZK__
621
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mcr p15,0,%0,c7,c10,5" : : "r" (0) : "memory")
622
+ #elif defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ \
623
+ || defined __ARM_ARCH_7M__ || defined __ARM_ARCH_7R__
624
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb" : : : "memory")
576
625
  #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__)
626
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad | #StoreStore | #StoreLoad" : : : "memory")
627
+ #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad" : : : "memory")
628
+ #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("membar #LoadStore | #StoreStore")
629
+ #elif defined __s390__ || defined __s390x__
581
630
  #define ECB_MEMORY_FENCE __asm__ __volatile__ ("bcr 15,0" : : : "memory")
631
+ #elif defined __mips__
632
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory")
633
+ #elif defined __alpha__
634
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mb" : : : "memory")
635
+ #elif defined __hppa__
636
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory")
637
+ #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
638
+ #elif defined __ia64__
639
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mf" : : : "memory")
582
640
  #endif
583
641
  #endif
584
642
  #endif
585
643
 
586
644
  #ifndef ECB_MEMORY_FENCE
587
- #if ECB_GCC_VERSION(4,4) || defined(__INTEL_COMPILER) || defined(__clang__)
645
+ #if ECB_GCC_VERSION(4,7)
646
+ /* see comment below (stdatomic.h) about the C11 memory model. */
647
+ #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST)
648
+
649
+ /* The __has_feature syntax from clang is so misdesigned that we cannot use it
650
+ * without risking compile time errors with other compilers. We *could*
651
+ * define our own ecb_clang_has_feature, but I just can't be bothered to work
652
+ * around this shit time and again.
653
+ * #elif defined __clang && __has_feature (cxx_atomic)
654
+ * // see comment below (stdatomic.h) about the C11 memory model.
655
+ * #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST)
656
+ */
657
+
658
+ #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__
588
659
  #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
660
  #elif _MSC_VER >= 1400 /* VC++ 2005 */
592
661
  #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
593
662
  #define ECB_MEMORY_FENCE _ReadWriteBarrier ()
594
663
  #define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier () /* according to msdn, _ReadBarrier is not a load fence */
595
664
  #define ECB_MEMORY_FENCE_RELEASE _WriteBarrier ()
596
- #elif defined(_WIN32)
665
+ #elif defined _WIN32
597
666
  #include <WinNT.h>
598
667
  #define ECB_MEMORY_FENCE MemoryBarrier () /* actually just xchg on x86... scary */
599
668
  #elif __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
@@ -601,6 +670,23 @@ struct signalfd_siginfo
601
670
  #define ECB_MEMORY_FENCE __machine_rw_barrier ()
602
671
  #define ECB_MEMORY_FENCE_ACQUIRE __machine_r_barrier ()
603
672
  #define ECB_MEMORY_FENCE_RELEASE __machine_w_barrier ()
673
+ #elif __xlC__
674
+ #define ECB_MEMORY_FENCE __sync ()
675
+ #endif
676
+ #endif
677
+
678
+ #ifndef ECB_MEMORY_FENCE
679
+ #if ECB_C11 && !defined __STDC_NO_ATOMICS__
680
+ /* we assume that these memory fences work on all variables/all memory accesses, */
681
+ /* not just C11 atomics and atomic accesses */
682
+ #include <stdatomic.h>
683
+ /* Unfortunately, neither gcc 4.7 nor clang 3.1 generate any instructions for */
684
+ /* any fence other than seq_cst, which isn't very efficient for us. */
685
+ /* Why that is, we don't know - either the C11 memory model is quite useless */
686
+ /* for most usages, or gcc and clang have a bug */
687
+ /* I *currently* lean towards the latter, and inefficiently implement */
688
+ /* all three of ecb's fences as a seq_cst fence */
689
+ #define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst)
604
690
  #endif
605
691
  #endif
606
692
 
@@ -622,18 +708,16 @@ struct signalfd_siginfo
622
708
  #endif
623
709
  #endif
624
710
 
625
- #if !defined(ECB_MEMORY_FENCE_ACQUIRE) && defined(ECB_MEMORY_FENCE)
711
+ #if !defined ECB_MEMORY_FENCE_ACQUIRE && defined ECB_MEMORY_FENCE
626
712
  #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
627
713
  #endif
628
714
 
629
- #if !defined(ECB_MEMORY_FENCE_RELEASE) && defined(ECB_MEMORY_FENCE)
715
+ #if !defined ECB_MEMORY_FENCE_RELEASE && defined ECB_MEMORY_FENCE
630
716
  #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
631
717
  #endif
632
718
 
633
719
  /*****************************************************************************/
634
720
 
635
- #define ECB_C99 (__STDC_VERSION__ >= 199901L)
636
-
637
721
  #if __cplusplus
638
722
  #define ecb_inline static inline
639
723
  #elif ECB_GCC_VERSION(2,5)
@@ -681,11 +765,16 @@ typedef int ecb_bool;
681
765
  #endif
682
766
 
683
767
  #define ecb_noinline ecb_attribute ((__noinline__))
684
- #define ecb_noreturn ecb_attribute ((__noreturn__))
685
768
  #define ecb_unused ecb_attribute ((__unused__))
686
769
  #define ecb_const ecb_attribute ((__const__))
687
770
  #define ecb_pure ecb_attribute ((__pure__))
688
771
 
772
+ #if ECB_C11
773
+ #define ecb_noreturn _Noreturn
774
+ #else
775
+ #define ecb_noreturn ecb_attribute ((__noreturn__))
776
+ #endif
777
+
689
778
  #if ECB_GCC_VERSION(4,3)
690
779
  #define ecb_artificial ecb_attribute ((__artificial__))
691
780
  #define ecb_hot ecb_attribute ((__hot__))
@@ -785,6 +874,11 @@ typedef int ecb_bool;
785
874
  }
786
875
  #endif
787
876
 
877
+ ecb_function_ ecb_bool ecb_is_pot32 (uint32_t x) ecb_const;
878
+ ecb_function_ ecb_bool ecb_is_pot32 (uint32_t x) { return !(x & (x - 1)); }
879
+ ecb_function_ ecb_bool ecb_is_pot64 (uint64_t x) ecb_const;
880
+ ecb_function_ ecb_bool ecb_is_pot64 (uint64_t x) { return !(x & (x - 1)); }
881
+
788
882
  ecb_function_ uint8_t ecb_bitrev8 (uint8_t x) ecb_const;
789
883
  ecb_function_ uint8_t ecb_bitrev8 (uint8_t x)
790
884
  {
@@ -878,14 +972,32 @@ ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (
878
972
  #endif
879
973
 
880
974
  /* try to tell the compiler that some condition is definitely true */
881
- #define ecb_assume(cond) do { if (!(cond)) ecb_unreachable (); } while (0)
975
+ #define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0
882
976
 
883
977
  ecb_inline unsigned char ecb_byteorder_helper (void) ecb_const;
884
978
  ecb_inline unsigned char
885
979
  ecb_byteorder_helper (void)
886
980
  {
887
- const uint32_t u = 0x11223344;
888
- return *(unsigned char *)&u;
981
+ /* the union code still generates code under pressure in gcc, */
982
+ /* but less than using pointers, and always seems to */
983
+ /* successfully return a constant. */
984
+ /* the reason why we have this horrible preprocessor mess */
985
+ /* is to avoid it in all cases, at least on common architectures */
986
+ /* or when using a recent enough gcc version (>= 4.6) */
987
+ #if __i386 || __i386__ || _M_X86 || __amd64 || __amd64__ || _M_X64
988
+ return 0x44;
989
+ #elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
990
+ return 0x44;
991
+ #elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
992
+ return 0x11;
993
+ #else
994
+ union
995
+ {
996
+ uint32_t i;
997
+ uint8_t c;
998
+ } u = { 0x11223344 };
999
+ return u.c;
1000
+ #endif
889
1001
  }
890
1002
 
891
1003
  ecb_inline ecb_bool ecb_big_endian (void) ecb_const;
@@ -926,6 +1038,173 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
926
1038
  #define ecb_array_length(name) (sizeof (name) / sizeof (name [0]))
927
1039
  #endif
928
1040
 
1041
+ /*******************************************************************************/
1042
+ /* floating point stuff, can be disabled by defining ECB_NO_LIBM */
1043
+
1044
+ /* basically, everything uses "ieee pure-endian" floating point numbers */
1045
+ /* the only noteworthy exception is ancient armle, which uses order 43218765 */
1046
+ #if 0 \
1047
+ || __i386 || __i386__ \
1048
+ || __amd64 || __amd64__ || __x86_64 || __x86_64__ \
1049
+ || __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__ \
1050
+ || defined __arm__ && defined __ARM_EABI__ \
1051
+ || defined __s390__ || defined __s390x__ \
1052
+ || defined __mips__ \
1053
+ || defined __alpha__ \
1054
+ || defined __hppa__ \
1055
+ || defined __ia64__ \
1056
+ || defined _M_IX86 || defined _M_AMD64 || defined _M_IA64
1057
+ #define ECB_STDFP 1
1058
+ #include <string.h> /* for memcpy */
1059
+ #else
1060
+ #define ECB_STDFP 0
1061
+ #include <math.h> /* for frexp*, ldexp* */
1062
+ #endif
1063
+
1064
+ #ifndef ECB_NO_LIBM
1065
+
1066
+ /* convert a float to ieee single/binary32 */
1067
+ ecb_function_ uint32_t ecb_float_to_binary32 (float x) ecb_const;
1068
+ ecb_function_ uint32_t
1069
+ ecb_float_to_binary32 (float x)
1070
+ {
1071
+ uint32_t r;
1072
+
1073
+ #if ECB_STDFP
1074
+ memcpy (&r, &x, 4);
1075
+ #else
1076
+ /* slow emulation, works for anything but -0 */
1077
+ uint32_t m;
1078
+ int e;
1079
+
1080
+ if (x == 0e0f ) return 0x00000000U;
1081
+ if (x > +3.40282346638528860e+38f) return 0x7f800000U;
1082
+ if (x < -3.40282346638528860e+38f) return 0xff800000U;
1083
+ if (x != x ) return 0x7fbfffffU;
1084
+
1085
+ m = frexpf (x, &e) * 0x1000000U;
1086
+
1087
+ r = m & 0x80000000U;
1088
+
1089
+ if (r)
1090
+ m = -m;
1091
+
1092
+ if (e <= -126)
1093
+ {
1094
+ m &= 0xffffffU;
1095
+ m >>= (-125 - e);
1096
+ e = -126;
1097
+ }
1098
+
1099
+ r |= (e + 126) << 23;
1100
+ r |= m & 0x7fffffU;
1101
+ #endif
1102
+
1103
+ return r;
1104
+ }
1105
+
1106
+ /* converts an ieee single/binary32 to a float */
1107
+ ecb_function_ float ecb_binary32_to_float (uint32_t x) ecb_const;
1108
+ ecb_function_ float
1109
+ ecb_binary32_to_float (uint32_t x)
1110
+ {
1111
+ float r;
1112
+
1113
+ #if ECB_STDFP
1114
+ memcpy (&r, &x, 4);
1115
+ #else
1116
+ /* emulation, only works for normals and subnormals and +0 */
1117
+ int neg = x >> 31;
1118
+ int e = (x >> 23) & 0xffU;
1119
+
1120
+ x &= 0x7fffffU;
1121
+
1122
+ if (e)
1123
+ x |= 0x800000U;
1124
+ else
1125
+ e = 1;
1126
+
1127
+ /* we distrust ldexpf a bit and do the 2**-24 scaling by an extra multiply */
1128
+ r = ldexpf (x * (0.5f / 0x800000U), e - 126);
1129
+
1130
+ r = neg ? -r : r;
1131
+ #endif
1132
+
1133
+ return r;
1134
+ }
1135
+
1136
+ /* convert a double to ieee double/binary64 */
1137
+ ecb_function_ uint64_t ecb_double_to_binary64 (double x) ecb_const;
1138
+ ecb_function_ uint64_t
1139
+ ecb_double_to_binary64 (double x)
1140
+ {
1141
+ uint64_t r;
1142
+
1143
+ #if ECB_STDFP
1144
+ memcpy (&r, &x, 8);
1145
+ #else
1146
+ /* slow emulation, works for anything but -0 */
1147
+ uint64_t m;
1148
+ int e;
1149
+
1150
+ if (x == 0e0 ) return 0x0000000000000000U;
1151
+ if (x > +1.79769313486231470e+308) return 0x7ff0000000000000U;
1152
+ if (x < -1.79769313486231470e+308) return 0xfff0000000000000U;
1153
+ if (x != x ) return 0X7ff7ffffffffffffU;
1154
+
1155
+ m = frexp (x, &e) * 0x20000000000000U;
1156
+
1157
+ r = m & 0x8000000000000000;;
1158
+
1159
+ if (r)
1160
+ m = -m;
1161
+
1162
+ if (e <= -1022)
1163
+ {
1164
+ m &= 0x1fffffffffffffU;
1165
+ m >>= (-1021 - e);
1166
+ e = -1022;
1167
+ }
1168
+
1169
+ r |= ((uint64_t)(e + 1022)) << 52;
1170
+ r |= m & 0xfffffffffffffU;
1171
+ #endif
1172
+
1173
+ return r;
1174
+ }
1175
+
1176
+ /* converts an ieee double/binary64 to a double */
1177
+ ecb_function_ double ecb_binary64_to_double (uint64_t x) ecb_const;
1178
+ ecb_function_ double
1179
+ ecb_binary64_to_double (uint64_t x)
1180
+ {
1181
+ double r;
1182
+
1183
+ #if ECB_STDFP
1184
+ memcpy (&r, &x, 8);
1185
+ #else
1186
+ /* emulation, only works for normals and subnormals and +0 */
1187
+ int neg = x >> 63;
1188
+ int e = (x >> 52) & 0x7ffU;
1189
+
1190
+ x &= 0xfffffffffffffU;
1191
+
1192
+ if (e)
1193
+ x |= 0x10000000000000U;
1194
+ else
1195
+ e = 1;
1196
+
1197
+ /* we distrust ldexp a bit and do the 2**-53 scaling by an extra multiply */
1198
+ r = ldexp (x * (0.5 / 0x10000000000000U), e - 1022);
1199
+
1200
+ r = neg ? -r : r;
1201
+ #endif
1202
+
1203
+ return r;
1204
+ }
1205
+
1206
+ #endif
1207
+
929
1208
  #endif
930
1209
 
931
1210
  /* ECB.H END */
@@ -1101,10 +1380,10 @@ ev_printerr (const char *msg)
1101
1380
  }
1102
1381
  #endif
1103
1382
 
1104
- static void (*syserr_cb)(const char *msg);
1383
+ static void (*syserr_cb)(const char *msg) EV_THROW;
1105
1384
 
1106
1385
  void ecb_cold
1107
- ev_set_syserr_cb (void (*cb)(const char *msg))
1386
+ ev_set_syserr_cb (void (*cb)(const char *msg) EV_THROW) EV_THROW
1108
1387
  {
1109
1388
  syserr_cb = cb;
1110
1389
  }
@@ -1132,14 +1411,13 @@ ev_syserr (const char *msg)
1132
1411
  }
1133
1412
 
1134
1413
  static void *
1135
- ev_realloc_emul (void *ptr, long size)
1414
+ ev_realloc_emul (void *ptr, long size) EV_THROW
1136
1415
  {
1137
- #if __GLIBC__
1138
- return realloc (ptr, size);
1139
- #else
1140
1416
  /* some systems, notably openbsd and darwin, fail to properly
1141
1417
  * implement realloc (x, 0) (as required by both ansi c-89 and
1142
1418
  * the single unix specification, so work around them here.
1419
+ * recently, also (at least) fedora and debian started breaking it,
1420
+ * despite documenting it otherwise.
1143
1421
  */
1144
1422
 
1145
1423
  if (size)
@@ -1147,13 +1425,12 @@ ev_realloc_emul (void *ptr, long size)
1147
1425
 
1148
1426
  free (ptr);
1149
1427
  return 0;
1150
- #endif
1151
1428
  }
1152
1429
 
1153
- static void *(*alloc)(void *ptr, long size) = ev_realloc_emul;
1430
+ static void *(*alloc)(void *ptr, long size) EV_THROW = ev_realloc_emul;
1154
1431
 
1155
1432
  void ecb_cold
1156
- ev_set_allocator (void *(*cb)(void *ptr, long size))
1433
+ ev_set_allocator (void *(*cb)(void *ptr, long size) EV_THROW) EV_THROW
1157
1434
  {
1158
1435
  alloc = cb;
1159
1436
  }
@@ -1280,7 +1557,7 @@ typedef struct
1280
1557
 
1281
1558
  #ifndef EV_HAVE_EV_TIME
1282
1559
  ev_tstamp
1283
- ev_time (void)
1560
+ ev_time (void) EV_THROW
1284
1561
  {
1285
1562
  #if EV_USE_REALTIME
1286
1563
  if (expect_true (have_realtime))
@@ -1314,14 +1591,14 @@ get_clock (void)
1314
1591
 
1315
1592
  #if EV_MULTIPLICITY
1316
1593
  ev_tstamp
1317
- ev_now (EV_P)
1594
+ ev_now (EV_P) EV_THROW
1318
1595
  {
1319
1596
  return ev_rt_now;
1320
1597
  }
1321
1598
  #endif
1322
1599
 
1323
1600
  void
1324
- ev_sleep (ev_tstamp delay)
1601
+ ev_sleep (ev_tstamp delay) EV_THROW
1325
1602
  {
1326
1603
  if (delay > 0.)
1327
1604
  {
@@ -1330,7 +1607,7 @@ ev_sleep (ev_tstamp delay)
1330
1607
 
1331
1608
  EV_TS_SET (ts, delay);
1332
1609
  nanosleep (&ts, 0);
1333
- #elif defined(_WIN32)
1610
+ #elif defined _WIN32
1334
1611
  Sleep ((unsigned long)(delay * 1e3));
1335
1612
  #else
1336
1613
  struct timeval tv;
@@ -1412,7 +1689,7 @@ pendingcb (EV_P_ ev_prepare *w, int revents)
1412
1689
  }
1413
1690
 
1414
1691
  void noinline
1415
- ev_feed_event (EV_P_ void *w, int revents)
1692
+ ev_feed_event (EV_P_ void *w, int revents) EV_THROW
1416
1693
  {
1417
1694
  W w_ = (W)w;
1418
1695
  int pri = ABSPRI (w_);
@@ -1426,6 +1703,8 @@ ev_feed_event (EV_P_ void *w, int revents)
1426
1703
  pendings [pri][w_->pending - 1].w = w_;
1427
1704
  pendings [pri][w_->pending - 1].events = revents;
1428
1705
  }
1706
+
1707
+ pendingpri = NUMPRI - 1;
1429
1708
  }
1430
1709
 
1431
1710
  inline_speed void
@@ -1481,7 +1760,7 @@ fd_event (EV_P_ int fd, int revents)
1481
1760
  }
1482
1761
 
1483
1762
  void
1484
- ev_feed_fd_event (EV_P_ int fd, int revents)
1763
+ ev_feed_fd_event (EV_P_ int fd, int revents) EV_THROW
1485
1764
  {
1486
1765
  if (fd >= 0 && fd < anfdmax)
1487
1766
  fd_event_nocheck (EV_A_ fd, revents);
@@ -1810,28 +2089,41 @@ evpipe_init (EV_P)
1810
2089
  {
1811
2090
  if (!ev_is_active (&pipe_w))
1812
2091
  {
2092
+ int fds [2];
2093
+
1813
2094
  # if EV_USE_EVENTFD
1814
- evfd = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC);
1815
- if (evfd < 0 && errno == EINVAL)
1816
- evfd = eventfd (0, 0);
2095
+ fds [0] = -1;
2096
+ fds [1] = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC);
2097
+ if (fds [1] < 0 && errno == EINVAL)
2098
+ fds [1] = eventfd (0, 0);
1817
2099
 
1818
- if (evfd >= 0)
2100
+ if (fds [1] < 0)
2101
+ # endif
1819
2102
  {
1820
- evpipe [0] = -1;
1821
- fd_intern (evfd); /* doing it twice doesn't hurt */
1822
- ev_io_set (&pipe_w, evfd, EV_READ);
2103
+ while (pipe (fds))
2104
+ ev_syserr ("(libev) error creating signal/async pipe");
2105
+
2106
+ fd_intern (fds [0]);
1823
2107
  }
2108
+
2109
+ fd_intern (fds [1]);
2110
+
2111
+ evpipe [0] = fds [0];
2112
+
2113
+ if (evpipe [1] < 0)
2114
+ evpipe [1] = fds [1]; /* first call, set write fd */
1824
2115
  else
1825
- # endif
1826
2116
  {
1827
- while (pipe (evpipe))
1828
- ev_syserr ("(libev) error creating signal/async pipe");
2117
+ /* on subsequent calls, do not change evpipe [1] */
2118
+ /* so that evpipe_write can always rely on its value. */
2119
+ /* this branch does not do anything sensible on windows, */
2120
+ /* so must not be executed on windows */
1829
2121
 
1830
- fd_intern (evpipe [0]);
1831
- fd_intern (evpipe [1]);
1832
- ev_io_set (&pipe_w, evpipe [0], EV_READ);
2122
+ dup2 (fds [1], evpipe [1]);
2123
+ close (fds [1]);
1833
2124
  }
1834
2125
 
2126
+ ev_io_set (&pipe_w, evpipe [0] < 0 ? evpipe [1] : evpipe [0], EV_READ);
1835
2127
  ev_io_start (EV_A_ &pipe_w);
1836
2128
  ev_unref (EV_A); /* watcher should not keep loop alive */
1837
2129
  }
@@ -1840,11 +2132,12 @@ evpipe_init (EV_P)
1840
2132
  inline_speed void
1841
2133
  evpipe_write (EV_P_ EV_ATOMIC_T *flag)
1842
2134
  {
2135
+ ECB_MEMORY_FENCE; /* push out the write before this function was called, acquire flag */
2136
+
1843
2137
  if (expect_true (*flag))
1844
2138
  return;
1845
2139
 
1846
2140
  *flag = 1;
1847
-
1848
2141
  ECB_MEMORY_FENCE_RELEASE; /* make sure flag is visible before the wakeup */
1849
2142
 
1850
2143
  pipe_write_skipped = 1;
@@ -1855,25 +2148,29 @@ evpipe_write (EV_P_ EV_ATOMIC_T *flag)
1855
2148
  {
1856
2149
  int old_errno;
1857
2150
 
1858
- pipe_write_skipped = 0; /* just an optimisation, no fence needed */
2151
+ pipe_write_skipped = 0;
2152
+ ECB_MEMORY_FENCE_RELEASE;
1859
2153
 
1860
2154
  old_errno = errno; /* save errno because write will clobber it */
1861
2155
 
1862
2156
  #if EV_USE_EVENTFD
1863
- if (evfd >= 0)
2157
+ if (evpipe [0] < 0)
1864
2158
  {
1865
2159
  uint64_t counter = 1;
1866
- write (evfd, &counter, sizeof (uint64_t));
2160
+ write (evpipe [1], &counter, sizeof (uint64_t));
1867
2161
  }
1868
2162
  else
1869
2163
  #endif
1870
2164
  {
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. */
2165
+ #ifdef _WIN32
2166
+ WSABUF buf;
2167
+ DWORD sent;
2168
+ buf.buf = &buf;
2169
+ buf.len = 1;
2170
+ WSASend (EV_FD_TO_WIN32_HANDLE (evpipe [1]), &buf, 1, &sent, 0, 0, 0);
2171
+ #else
1876
2172
  write (evpipe [1], &(evpipe [1]), 1);
2173
+ #endif
1877
2174
  }
1878
2175
 
1879
2176
  errno = old_errno;
@@ -1890,27 +2187,39 @@ pipecb (EV_P_ ev_io *iow, int revents)
1890
2187
  if (revents & EV_READ)
1891
2188
  {
1892
2189
  #if EV_USE_EVENTFD
1893
- if (evfd >= 0)
2190
+ if (evpipe [0] < 0)
1894
2191
  {
1895
2192
  uint64_t counter;
1896
- read (evfd, &counter, sizeof (uint64_t));
2193
+ read (evpipe [1], &counter, sizeof (uint64_t));
1897
2194
  }
1898
2195
  else
1899
2196
  #endif
1900
2197
  {
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);
2198
+ char dummy[4];
2199
+ #ifdef _WIN32
2200
+ WSABUF buf;
2201
+ DWORD recvd;
2202
+ DWORD flags = 0;
2203
+ buf.buf = dummy;
2204
+ buf.len = sizeof (dummy);
2205
+ WSARecv (EV_FD_TO_WIN32_HANDLE (evpipe [0]), &buf, 1, &recvd, &flags, 0, 0);
2206
+ #else
2207
+ read (evpipe [0], &dummy, sizeof (dummy));
2208
+ #endif
1904
2209
  }
1905
2210
  }
1906
2211
 
1907
2212
  pipe_write_skipped = 0;
1908
2213
 
2214
+ ECB_MEMORY_FENCE; /* push out skipped, acquire flags */
2215
+
1909
2216
  #if EV_SIGNAL_ENABLE
1910
2217
  if (sig_pending)
1911
2218
  {
1912
2219
  sig_pending = 0;
1913
2220
 
2221
+ ECB_MEMORY_FENCE;
2222
+
1914
2223
  for (i = EV_NSIG - 1; i--; )
1915
2224
  if (expect_false (signals [i].pending))
1916
2225
  ev_feed_signal_event (EV_A_ i + 1);
@@ -1922,10 +2231,13 @@ pipecb (EV_P_ ev_io *iow, int revents)
1922
2231
  {
1923
2232
  async_pending = 0;
1924
2233
 
2234
+ ECB_MEMORY_FENCE;
2235
+
1925
2236
  for (i = asynccnt; i--; )
1926
2237
  if (asyncs [i]->sent)
1927
2238
  {
1928
2239
  asyncs [i]->sent = 0;
2240
+ ECB_MEMORY_FENCE_RELEASE;
1929
2241
  ev_feed_event (EV_A_ asyncs [i], EV_ASYNC);
1930
2242
  }
1931
2243
  }
@@ -1935,18 +2247,17 @@ pipecb (EV_P_ ev_io *iow, int revents)
1935
2247
  /*****************************************************************************/
1936
2248
 
1937
2249
  void
1938
- ev_feed_signal (int signum)
2250
+ ev_feed_signal (int signum) EV_THROW
1939
2251
  {
1940
2252
  #if EV_MULTIPLICITY
1941
- EV_P = signals [signum - 1].loop;
2253
+ EV_P;
2254
+ ECB_MEMORY_FENCE_ACQUIRE;
2255
+ EV_A = signals [signum - 1].loop;
1942
2256
 
1943
2257
  if (!EV_A)
1944
2258
  return;
1945
2259
  #endif
1946
2260
 
1947
- if (!ev_active (&pipe_w))
1948
- return;
1949
-
1950
2261
  signals [signum - 1].pending = 1;
1951
2262
  evpipe_write (EV_A_ &sig_pending);
1952
2263
  }
@@ -1962,11 +2273,11 @@ ev_sighandler (int signum)
1962
2273
  }
1963
2274
 
1964
2275
  void noinline
1965
- ev_feed_signal_event (EV_P_ int signum)
2276
+ ev_feed_signal_event (EV_P_ int signum) EV_THROW
1966
2277
  {
1967
2278
  WL w;
1968
2279
 
1969
- if (expect_false (signum <= 0 || signum > EV_NSIG))
2280
+ if (expect_false (signum <= 0 || signum >= EV_NSIG))
1970
2281
  return;
1971
2282
 
1972
2283
  --signum;
@@ -1980,6 +2291,7 @@ ev_feed_signal_event (EV_P_ int signum)
1980
2291
  #endif
1981
2292
 
1982
2293
  signals [signum].pending = 0;
2294
+ ECB_MEMORY_FENCE_RELEASE;
1983
2295
 
1984
2296
  for (w = signals [signum].head; w; w = w->next)
1985
2297
  ev_feed_event (EV_A_ (W)w, EV_SIGNAL);
@@ -2088,13 +2400,13 @@ childcb (EV_P_ ev_signal *sw, int revents)
2088
2400
  #endif
2089
2401
 
2090
2402
  int ecb_cold
2091
- ev_version_major (void)
2403
+ ev_version_major (void) EV_THROW
2092
2404
  {
2093
2405
  return EV_VERSION_MAJOR;
2094
2406
  }
2095
2407
 
2096
2408
  int ecb_cold
2097
- ev_version_minor (void)
2409
+ ev_version_minor (void) EV_THROW
2098
2410
  {
2099
2411
  return EV_VERSION_MINOR;
2100
2412
  }
@@ -2112,7 +2424,7 @@ enable_secure (void)
2112
2424
  }
2113
2425
 
2114
2426
  unsigned int ecb_cold
2115
- ev_supported_backends (void)
2427
+ ev_supported_backends (void) EV_THROW
2116
2428
  {
2117
2429
  unsigned int flags = 0;
2118
2430
 
@@ -2126,7 +2438,7 @@ ev_supported_backends (void)
2126
2438
  }
2127
2439
 
2128
2440
  unsigned int ecb_cold
2129
- ev_recommended_backends (void)
2441
+ ev_recommended_backends (void) EV_THROW
2130
2442
  {
2131
2443
  unsigned int flags = ev_supported_backends ();
2132
2444
 
@@ -2148,7 +2460,7 @@ ev_recommended_backends (void)
2148
2460
  }
2149
2461
 
2150
2462
  unsigned int ecb_cold
2151
- ev_embeddable_backends (void)
2463
+ ev_embeddable_backends (void) EV_THROW
2152
2464
  {
2153
2465
  int flags = EVBACKEND_EPOLL | EVBACKEND_KQUEUE | EVBACKEND_PORT;
2154
2466
 
@@ -2160,56 +2472,56 @@ ev_embeddable_backends (void)
2160
2472
  }
2161
2473
 
2162
2474
  unsigned int
2163
- ev_backend (EV_P)
2475
+ ev_backend (EV_P) EV_THROW
2164
2476
  {
2165
2477
  return backend;
2166
2478
  }
2167
2479
 
2168
2480
  #if EV_FEATURE_API
2169
2481
  unsigned int
2170
- ev_iteration (EV_P)
2482
+ ev_iteration (EV_P) EV_THROW
2171
2483
  {
2172
2484
  return loop_count;
2173
2485
  }
2174
2486
 
2175
2487
  unsigned int
2176
- ev_depth (EV_P)
2488
+ ev_depth (EV_P) EV_THROW
2177
2489
  {
2178
2490
  return loop_depth;
2179
2491
  }
2180
2492
 
2181
2493
  void
2182
- ev_set_io_collect_interval (EV_P_ ev_tstamp interval)
2494
+ ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_THROW
2183
2495
  {
2184
2496
  io_blocktime = interval;
2185
2497
  }
2186
2498
 
2187
2499
  void
2188
- ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval)
2500
+ ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_THROW
2189
2501
  {
2190
2502
  timeout_blocktime = interval;
2191
2503
  }
2192
2504
 
2193
2505
  void
2194
- ev_set_userdata (EV_P_ void *data)
2506
+ ev_set_userdata (EV_P_ void *data) EV_THROW
2195
2507
  {
2196
2508
  userdata = data;
2197
2509
  }
2198
2510
 
2199
2511
  void *
2200
- ev_userdata (EV_P)
2512
+ ev_userdata (EV_P) EV_THROW
2201
2513
  {
2202
2514
  return userdata;
2203
2515
  }
2204
2516
 
2205
2517
  void
2206
- ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P))
2518
+ ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P)) EV_THROW
2207
2519
  {
2208
2520
  invoke_cb = invoke_pending_cb;
2209
2521
  }
2210
2522
 
2211
2523
  void
2212
- ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P))
2524
+ ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV_P) EV_THROW) EV_THROW
2213
2525
  {
2214
2526
  release_cb = release;
2215
2527
  acquire_cb = acquire;
@@ -2218,7 +2530,7 @@ ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P))
2218
2530
 
2219
2531
  /* initialise a loop structure, must be zero-initialised */
2220
2532
  static void noinline ecb_cold
2221
- loop_init (EV_P_ unsigned int flags)
2533
+ loop_init (EV_P_ unsigned int flags) EV_THROW
2222
2534
  {
2223
2535
  if (!backend)
2224
2536
  {
@@ -2273,6 +2585,8 @@ loop_init (EV_P_ unsigned int flags)
2273
2585
  #endif
2274
2586
  pipe_write_skipped = 0;
2275
2587
  pipe_write_wanted = 0;
2588
+ evpipe [0] = -1;
2589
+ evpipe [1] = -1;
2276
2590
  #if EV_USE_INOTIFY
2277
2591
  fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2;
2278
2592
  #endif
@@ -2333,7 +2647,7 @@ ev_loop_destroy (EV_P)
2333
2647
  #endif
2334
2648
 
2335
2649
  #if EV_CHILD_ENABLE
2336
- if (ev_is_active (&childev))
2650
+ if (ev_is_default_loop (EV_A) && ev_is_active (&childev))
2337
2651
  {
2338
2652
  ev_ref (EV_A); /* child watcher */
2339
2653
  ev_signal_stop (EV_A_ &childev);
@@ -2345,16 +2659,8 @@ ev_loop_destroy (EV_P)
2345
2659
  /*ev_ref (EV_A);*/
2346
2660
  /*ev_io_stop (EV_A_ &pipe_w);*/
2347
2661
 
2348
- #if EV_USE_EVENTFD
2349
- if (evfd >= 0)
2350
- close (evfd);
2351
- #endif
2352
-
2353
- if (evpipe [0] >= 0)
2354
- {
2355
- EV_WIN32_CLOSE_FD (evpipe [0]);
2356
- EV_WIN32_CLOSE_FD (evpipe [1]);
2357
- }
2662
+ if (evpipe [0] >= 0) EV_WIN32_CLOSE_FD (evpipe [0]);
2663
+ if (evpipe [1] >= 0) EV_WIN32_CLOSE_FD (evpipe [1]);
2358
2664
  }
2359
2665
 
2360
2666
  #if EV_USE_SIGNALFD
@@ -2450,6 +2756,7 @@ loop_fork (EV_P)
2450
2756
  infy_fork (EV_A);
2451
2757
  #endif
2452
2758
 
2759
+ #if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
2453
2760
  if (ev_is_active (&pipe_w))
2454
2761
  {
2455
2762
  /* pipe_write_wanted must be false now, so modifying fd vars should be safe */
@@ -2457,23 +2764,14 @@ loop_fork (EV_P)
2457
2764
  ev_ref (EV_A);
2458
2765
  ev_io_stop (EV_A_ &pipe_w);
2459
2766
 
2460
- #if EV_USE_EVENTFD
2461
- if (evfd >= 0)
2462
- close (evfd);
2463
- #endif
2464
-
2465
2767
  if (evpipe [0] >= 0)
2466
- {
2467
- EV_WIN32_CLOSE_FD (evpipe [0]);
2468
- EV_WIN32_CLOSE_FD (evpipe [1]);
2469
- }
2768
+ EV_WIN32_CLOSE_FD (evpipe [0]);
2470
2769
 
2471
- #if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
2472
2770
  evpipe_init (EV_A);
2473
- /* now iterate over everything, in case we missed something */
2474
- pipecb (EV_A_ &pipe_w, EV_READ);
2475
- #endif
2771
+ /* iterate over everything, in case we missed something before */
2772
+ ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM);
2476
2773
  }
2774
+ #endif
2477
2775
 
2478
2776
  postfork = 0;
2479
2777
  }
@@ -2481,7 +2779,7 @@ loop_fork (EV_P)
2481
2779
  #if EV_MULTIPLICITY
2482
2780
 
2483
2781
  struct ev_loop * ecb_cold
2484
- ev_loop_new (unsigned int flags)
2782
+ ev_loop_new (unsigned int flags) EV_THROW
2485
2783
  {
2486
2784
  EV_P = (struct ev_loop *)ev_malloc (sizeof (struct ev_loop));
2487
2785
 
@@ -2535,11 +2833,11 @@ array_verify (EV_P_ W *ws, int cnt)
2535
2833
 
2536
2834
  #if EV_FEATURE_API
2537
2835
  void ecb_cold
2538
- ev_verify (EV_P)
2836
+ ev_verify (EV_P) EV_THROW
2539
2837
  {
2540
2838
  #if EV_VERIFY
2541
2839
  int i;
2542
- WL w;
2840
+ WL w, w2;
2543
2841
 
2544
2842
  assert (activecnt >= -1);
2545
2843
 
@@ -2549,12 +2847,23 @@ ev_verify (EV_P)
2549
2847
 
2550
2848
  assert (anfdmax >= 0);
2551
2849
  for (i = 0; i < anfdmax; ++i)
2552
- for (w = anfds [i].head; w; w = w->next)
2553
- {
2554
- verify_watcher (EV_A_ (W)w);
2555
- assert (("libev: inactive fd watcher on anfd list", ev_active (w) == 1));
2556
- assert (("libev: fd mismatch between watcher and anfd", ((ev_io *)w)->fd == i));
2557
- }
2850
+ {
2851
+ int j = 0;
2852
+
2853
+ for (w = w2 = anfds [i].head; w; w = w->next)
2854
+ {
2855
+ verify_watcher (EV_A_ (W)w);
2856
+
2857
+ if (j++ & 1)
2858
+ {
2859
+ assert (("libev: io watcher list contains a loop", w != w2));
2860
+ w2 = w2->next;
2861
+ }
2862
+
2863
+ assert (("libev: inactive fd watcher on anfd list", ev_active (w) == 1));
2864
+ assert (("libev: fd mismatch between watcher and anfd", ((ev_io *)w)->fd == i));
2865
+ }
2866
+ }
2558
2867
 
2559
2868
  assert (timermax >= timercnt);
2560
2869
  verify_heap (EV_A_ timers, timercnt);
@@ -2614,7 +2923,7 @@ struct ev_loop * ecb_cold
2614
2923
  #else
2615
2924
  int
2616
2925
  #endif
2617
- ev_default_loop (unsigned int flags)
2926
+ ev_default_loop (unsigned int flags) EV_THROW
2618
2927
  {
2619
2928
  if (!ev_default_loop_ptr)
2620
2929
  {
@@ -2643,9 +2952,9 @@ ev_default_loop (unsigned int flags)
2643
2952
  }
2644
2953
 
2645
2954
  void
2646
- ev_loop_fork (EV_P)
2955
+ ev_loop_fork (EV_P) EV_THROW
2647
2956
  {
2648
- postfork = 1; /* must be in line with ev_default_fork */
2957
+ postfork = 1;
2649
2958
  }
2650
2959
 
2651
2960
  /*****************************************************************************/
@@ -2657,7 +2966,7 @@ ev_invoke (EV_P_ void *w, int revents)
2657
2966
  }
2658
2967
 
2659
2968
  unsigned int
2660
- ev_pending_count (EV_P)
2969
+ ev_pending_count (EV_P) EV_THROW
2661
2970
  {
2662
2971
  int pri;
2663
2972
  unsigned int count = 0;
@@ -2671,17 +2980,21 @@ ev_pending_count (EV_P)
2671
2980
  void noinline
2672
2981
  ev_invoke_pending (EV_P)
2673
2982
  {
2674
- int pri;
2983
+ pendingpri = NUMPRI;
2675
2984
 
2676
- for (pri = NUMPRI; pri--; )
2677
- while (pendingcnt [pri])
2678
- {
2679
- ANPENDING *p = pendings [pri] + --pendingcnt [pri];
2985
+ while (pendingpri) /* pendingpri possibly gets modified in the inner loop */
2986
+ {
2987
+ --pendingpri;
2680
2988
 
2681
- p->w->pending = 0;
2682
- EV_CB_INVOKE (p->w, p->events);
2683
- EV_FREQUENT_CHECK;
2684
- }
2989
+ while (pendingcnt [pendingpri])
2990
+ {
2991
+ ANPENDING *p = pendings [pendingpri] + --pendingcnt [pendingpri];
2992
+
2993
+ p->w->pending = 0;
2994
+ EV_CB_INVOKE (p->w, p->events);
2995
+ EV_FREQUENT_CHECK;
2996
+ }
2997
+ }
2685
2998
  }
2686
2999
 
2687
3000
  #if EV_IDLE_ENABLE
@@ -2781,8 +3094,6 @@ periodics_reify (EV_P)
2781
3094
 
2782
3095
  while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now)
2783
3096
  {
2784
- int feed_count = 0;
2785
-
2786
3097
  do
2787
3098
  {
2788
3099
  ev_periodic *w = (ev_periodic *)ANHE_w (periodics [HEAP0]);
@@ -2926,7 +3237,7 @@ time_update (EV_P_ ev_tstamp max_block)
2926
3237
  }
2927
3238
  }
2928
3239
 
2929
- void
3240
+ int
2930
3241
  ev_run (EV_P_ int flags)
2931
3242
  {
2932
3243
  #if EV_FEATURE_API
@@ -3051,6 +3362,7 @@ ev_run (EV_P_ int flags)
3051
3362
 
3052
3363
  pipe_write_wanted = 0; /* just an optimisation, no fence needed */
3053
3364
 
3365
+ ECB_MEMORY_FENCE_ACQUIRE;
3054
3366
  if (pipe_write_skipped)
3055
3367
  {
3056
3368
  assert (("libev: pipe_w not active, but pipe not written", ev_is_active (&pipe_w)));
@@ -3093,40 +3405,42 @@ ev_run (EV_P_ int flags)
3093
3405
  #if EV_FEATURE_API
3094
3406
  --loop_depth;
3095
3407
  #endif
3408
+
3409
+ return activecnt;
3096
3410
  }
3097
3411
 
3098
3412
  void
3099
- ev_break (EV_P_ int how)
3413
+ ev_break (EV_P_ int how) EV_THROW
3100
3414
  {
3101
3415
  loop_done = how;
3102
3416
  }
3103
3417
 
3104
3418
  void
3105
- ev_ref (EV_P)
3419
+ ev_ref (EV_P) EV_THROW
3106
3420
  {
3107
3421
  ++activecnt;
3108
3422
  }
3109
3423
 
3110
3424
  void
3111
- ev_unref (EV_P)
3425
+ ev_unref (EV_P) EV_THROW
3112
3426
  {
3113
3427
  --activecnt;
3114
3428
  }
3115
3429
 
3116
3430
  void
3117
- ev_now_update (EV_P)
3431
+ ev_now_update (EV_P) EV_THROW
3118
3432
  {
3119
3433
  time_update (EV_A_ 1e100);
3120
3434
  }
3121
3435
 
3122
3436
  void
3123
- ev_suspend (EV_P)
3437
+ ev_suspend (EV_P) EV_THROW
3124
3438
  {
3125
3439
  ev_now_update (EV_A);
3126
3440
  }
3127
3441
 
3128
3442
  void
3129
- ev_resume (EV_P)
3443
+ ev_resume (EV_P) EV_THROW
3130
3444
  {
3131
3445
  ev_tstamp mn_prev = mn_now;
3132
3446
 
@@ -3175,7 +3489,7 @@ clear_pending (EV_P_ W w)
3175
3489
  }
3176
3490
 
3177
3491
  int
3178
- ev_clear_pending (EV_P_ void *w)
3492
+ ev_clear_pending (EV_P_ void *w) EV_THROW
3179
3493
  {
3180
3494
  W w_ = (W)w;
3181
3495
  int pending = w_->pending;
@@ -3218,7 +3532,7 @@ ev_stop (EV_P_ W w)
3218
3532
  /*****************************************************************************/
3219
3533
 
3220
3534
  void noinline
3221
- ev_io_start (EV_P_ ev_io *w)
3535
+ ev_io_start (EV_P_ ev_io *w) EV_THROW
3222
3536
  {
3223
3537
  int fd = w->fd;
3224
3538
 
@@ -3234,6 +3548,9 @@ ev_io_start (EV_P_ ev_io *w)
3234
3548
  array_needsize (ANFD, anfds, anfdmax, fd + 1, array_init_zero);
3235
3549
  wlist_add (&anfds[fd].head, (WL)w);
3236
3550
 
3551
+ /* common bug, apparently */
3552
+ assert (("libev: ev_io_start called with corrupted watcher", ((WL)w)->next != (WL)w));
3553
+
3237
3554
  fd_change (EV_A_ fd, w->events & EV__IOFDSET | EV_ANFD_REIFY);
3238
3555
  w->events &= ~EV__IOFDSET;
3239
3556
 
@@ -3241,7 +3558,7 @@ ev_io_start (EV_P_ ev_io *w)
3241
3558
  }
3242
3559
 
3243
3560
  void noinline
3244
- ev_io_stop (EV_P_ ev_io *w)
3561
+ ev_io_stop (EV_P_ ev_io *w) EV_THROW
3245
3562
  {
3246
3563
  clear_pending (EV_A_ (W)w);
3247
3564
  if (expect_false (!ev_is_active (w)))
@@ -3260,7 +3577,7 @@ ev_io_stop (EV_P_ ev_io *w)
3260
3577
  }
3261
3578
 
3262
3579
  void noinline
3263
- ev_timer_start (EV_P_ ev_timer *w)
3580
+ ev_timer_start (EV_P_ ev_timer *w) EV_THROW
3264
3581
  {
3265
3582
  if (expect_false (ev_is_active (w)))
3266
3583
  return;
@@ -3284,7 +3601,7 @@ ev_timer_start (EV_P_ ev_timer *w)
3284
3601
  }
3285
3602
 
3286
3603
  void noinline
3287
- ev_timer_stop (EV_P_ ev_timer *w)
3604
+ ev_timer_stop (EV_P_ ev_timer *w) EV_THROW
3288
3605
  {
3289
3606
  clear_pending (EV_A_ (W)w);
3290
3607
  if (expect_false (!ev_is_active (w)))
@@ -3314,7 +3631,7 @@ ev_timer_stop (EV_P_ ev_timer *w)
3314
3631
  }
3315
3632
 
3316
3633
  void noinline
3317
- ev_timer_again (EV_P_ ev_timer *w)
3634
+ ev_timer_again (EV_P_ ev_timer *w) EV_THROW
3318
3635
  {
3319
3636
  EV_FREQUENT_CHECK;
3320
3637
 
@@ -3341,14 +3658,14 @@ ev_timer_again (EV_P_ ev_timer *w)
3341
3658
  }
3342
3659
 
3343
3660
  ev_tstamp
3344
- ev_timer_remaining (EV_P_ ev_timer *w)
3661
+ ev_timer_remaining (EV_P_ ev_timer *w) EV_THROW
3345
3662
  {
3346
3663
  return ev_at (w) - (ev_is_active (w) ? mn_now : 0.);
3347
3664
  }
3348
3665
 
3349
3666
  #if EV_PERIODIC_ENABLE
3350
3667
  void noinline
3351
- ev_periodic_start (EV_P_ ev_periodic *w)
3668
+ ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW
3352
3669
  {
3353
3670
  if (expect_false (ev_is_active (w)))
3354
3671
  return;
@@ -3378,7 +3695,7 @@ ev_periodic_start (EV_P_ ev_periodic *w)
3378
3695
  }
3379
3696
 
3380
3697
  void noinline
3381
- ev_periodic_stop (EV_P_ ev_periodic *w)
3698
+ ev_periodic_stop (EV_P_ ev_periodic *w) EV_THROW
3382
3699
  {
3383
3700
  clear_pending (EV_A_ (W)w);
3384
3701
  if (expect_false (!ev_is_active (w)))
@@ -3406,7 +3723,7 @@ ev_periodic_stop (EV_P_ ev_periodic *w)
3406
3723
  }
3407
3724
 
3408
3725
  void noinline
3409
- ev_periodic_again (EV_P_ ev_periodic *w)
3726
+ ev_periodic_again (EV_P_ ev_periodic *w) EV_THROW
3410
3727
  {
3411
3728
  /* TODO: use adjustheap and recalculation */
3412
3729
  ev_periodic_stop (EV_A_ w);
@@ -3421,7 +3738,7 @@ ev_periodic_again (EV_P_ ev_periodic *w)
3421
3738
  #if EV_SIGNAL_ENABLE
3422
3739
 
3423
3740
  void noinline
3424
- ev_signal_start (EV_P_ ev_signal *w)
3741
+ ev_signal_start (EV_P_ ev_signal *w) EV_THROW
3425
3742
  {
3426
3743
  if (expect_false (ev_is_active (w)))
3427
3744
  return;
@@ -3433,6 +3750,7 @@ ev_signal_start (EV_P_ ev_signal *w)
3433
3750
  !signals [w->signum - 1].loop || signals [w->signum - 1].loop == loop));
3434
3751
 
3435
3752
  signals [w->signum - 1].loop = EV_A;
3753
+ ECB_MEMORY_FENCE_RELEASE;
3436
3754
  #endif
3437
3755
 
3438
3756
  EV_FREQUENT_CHECK;
@@ -3502,7 +3820,7 @@ ev_signal_start (EV_P_ ev_signal *w)
3502
3820
  }
3503
3821
 
3504
3822
  void noinline
3505
- ev_signal_stop (EV_P_ ev_signal *w)
3823
+ ev_signal_stop (EV_P_ ev_signal *w) EV_THROW
3506
3824
  {
3507
3825
  clear_pending (EV_A_ (W)w);
3508
3826
  if (expect_false (!ev_is_active (w)))
@@ -3543,7 +3861,7 @@ ev_signal_stop (EV_P_ ev_signal *w)
3543
3861
  #if EV_CHILD_ENABLE
3544
3862
 
3545
3863
  void
3546
- ev_child_start (EV_P_ ev_child *w)
3864
+ ev_child_start (EV_P_ ev_child *w) EV_THROW
3547
3865
  {
3548
3866
  #if EV_MULTIPLICITY
3549
3867
  assert (("libev: child watchers are only supported in the default loop", loop == ev_default_loop_ptr));
@@ -3560,7 +3878,7 @@ ev_child_start (EV_P_ ev_child *w)
3560
3878
  }
3561
3879
 
3562
3880
  void
3563
- ev_child_stop (EV_P_ ev_child *w)
3881
+ ev_child_stop (EV_P_ ev_child *w) EV_THROW
3564
3882
  {
3565
3883
  clear_pending (EV_A_ (W)w);
3566
3884
  if (expect_false (!ev_is_active (w)))
@@ -3597,7 +3915,10 @@ static void noinline stat_timer_cb (EV_P_ ev_timer *w_, int revents);
3597
3915
  static void noinline
3598
3916
  infy_add (EV_P_ ev_stat *w)
3599
3917
  {
3600
- w->wd = inotify_add_watch (fs_fd, w->path, IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_MODIFY | IN_DONT_FOLLOW | IN_MASK_ADD);
3918
+ w->wd = inotify_add_watch (fs_fd, w->path,
3919
+ IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_MODIFY
3920
+ | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO
3921
+ | IN_DONT_FOLLOW | IN_MASK_ADD);
3601
3922
 
3602
3923
  if (w->wd >= 0)
3603
3924
  {
@@ -3611,10 +3932,16 @@ infy_add (EV_P_ ev_stat *w)
3611
3932
  w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL;
3612
3933
  else if (!statfs (w->path, &sfs)
3613
3934
  && (sfs.f_type == 0x1373 /* devfs */
3935
+ || sfs.f_type == 0x4006 /* fat */
3936
+ || sfs.f_type == 0x4d44 /* msdos */
3614
3937
  || sfs.f_type == 0xEF53 /* ext2/3 */
3938
+ || sfs.f_type == 0x72b6 /* jffs2 */
3939
+ || sfs.f_type == 0x858458f6 /* ramfs */
3940
+ || sfs.f_type == 0x5346544e /* ntfs */
3615
3941
  || sfs.f_type == 0x3153464a /* jfs */
3942
+ || sfs.f_type == 0x9123683e /* btrfs */
3616
3943
  || sfs.f_type == 0x52654973 /* reiser3 */
3617
- || sfs.f_type == 0x01021994 /* tempfs */
3944
+ || sfs.f_type == 0x01021994 /* tmpfs */
3618
3945
  || sfs.f_type == 0x58465342 /* xfs */))
3619
3946
  w->timer.repeat = 0.; /* filesystem is local, kernel new enough */
3620
3947
  else
@@ -3737,7 +4064,7 @@ ev_check_2625 (EV_P)
3737
4064
  inline_size int
3738
4065
  infy_newfd (void)
3739
4066
  {
3740
- #if defined (IN_CLOEXEC) && defined (IN_NONBLOCK)
4067
+ #if defined IN_CLOEXEC && defined IN_NONBLOCK
3741
4068
  int fd = inotify_init1 (IN_CLOEXEC | IN_NONBLOCK);
3742
4069
  if (fd >= 0)
3743
4070
  return fd;
@@ -3822,7 +4149,7 @@ infy_fork (EV_P)
3822
4149
  #endif
3823
4150
 
3824
4151
  void
3825
- ev_stat_stat (EV_P_ ev_stat *w)
4152
+ ev_stat_stat (EV_P_ ev_stat *w) EV_THROW
3826
4153
  {
3827
4154
  if (lstat (w->path, &w->attr) < 0)
3828
4155
  w->attr.st_nlink = 0;
@@ -3871,7 +4198,7 @@ stat_timer_cb (EV_P_ ev_timer *w_, int revents)
3871
4198
  }
3872
4199
 
3873
4200
  void
3874
- ev_stat_start (EV_P_ ev_stat *w)
4201
+ ev_stat_start (EV_P_ ev_stat *w) EV_THROW
3875
4202
  {
3876
4203
  if (expect_false (ev_is_active (w)))
3877
4204
  return;
@@ -3902,7 +4229,7 @@ ev_stat_start (EV_P_ ev_stat *w)
3902
4229
  }
3903
4230
 
3904
4231
  void
3905
- ev_stat_stop (EV_P_ ev_stat *w)
4232
+ ev_stat_stop (EV_P_ ev_stat *w) EV_THROW
3906
4233
  {
3907
4234
  clear_pending (EV_A_ (W)w);
3908
4235
  if (expect_false (!ev_is_active (w)))
@@ -3928,7 +4255,7 @@ ev_stat_stop (EV_P_ ev_stat *w)
3928
4255
 
3929
4256
  #if EV_IDLE_ENABLE
3930
4257
  void
3931
- ev_idle_start (EV_P_ ev_idle *w)
4258
+ ev_idle_start (EV_P_ ev_idle *w) EV_THROW
3932
4259
  {
3933
4260
  if (expect_false (ev_is_active (w)))
3934
4261
  return;
@@ -3951,7 +4278,7 @@ ev_idle_start (EV_P_ ev_idle *w)
3951
4278
  }
3952
4279
 
3953
4280
  void
3954
- ev_idle_stop (EV_P_ ev_idle *w)
4281
+ ev_idle_stop (EV_P_ ev_idle *w) EV_THROW
3955
4282
  {
3956
4283
  clear_pending (EV_A_ (W)w);
3957
4284
  if (expect_false (!ev_is_active (w)))
@@ -3975,7 +4302,7 @@ ev_idle_stop (EV_P_ ev_idle *w)
3975
4302
 
3976
4303
  #if EV_PREPARE_ENABLE
3977
4304
  void
3978
- ev_prepare_start (EV_P_ ev_prepare *w)
4305
+ ev_prepare_start (EV_P_ ev_prepare *w) EV_THROW
3979
4306
  {
3980
4307
  if (expect_false (ev_is_active (w)))
3981
4308
  return;
@@ -3990,7 +4317,7 @@ ev_prepare_start (EV_P_ ev_prepare *w)
3990
4317
  }
3991
4318
 
3992
4319
  void
3993
- ev_prepare_stop (EV_P_ ev_prepare *w)
4320
+ ev_prepare_stop (EV_P_ ev_prepare *w) EV_THROW
3994
4321
  {
3995
4322
  clear_pending (EV_A_ (W)w);
3996
4323
  if (expect_false (!ev_is_active (w)))
@@ -4013,7 +4340,7 @@ ev_prepare_stop (EV_P_ ev_prepare *w)
4013
4340
 
4014
4341
  #if EV_CHECK_ENABLE
4015
4342
  void
4016
- ev_check_start (EV_P_ ev_check *w)
4343
+ ev_check_start (EV_P_ ev_check *w) EV_THROW
4017
4344
  {
4018
4345
  if (expect_false (ev_is_active (w)))
4019
4346
  return;
@@ -4028,7 +4355,7 @@ ev_check_start (EV_P_ ev_check *w)
4028
4355
  }
4029
4356
 
4030
4357
  void
4031
- ev_check_stop (EV_P_ ev_check *w)
4358
+ ev_check_stop (EV_P_ ev_check *w) EV_THROW
4032
4359
  {
4033
4360
  clear_pending (EV_A_ (W)w);
4034
4361
  if (expect_false (!ev_is_active (w)))
@@ -4051,7 +4378,7 @@ ev_check_stop (EV_P_ ev_check *w)
4051
4378
 
4052
4379
  #if EV_EMBED_ENABLE
4053
4380
  void noinline
4054
- ev_embed_sweep (EV_P_ ev_embed *w)
4381
+ ev_embed_sweep (EV_P_ ev_embed *w) EV_THROW
4055
4382
  {
4056
4383
  ev_run (w->other, EVRUN_NOWAIT);
4057
4384
  }
@@ -4109,7 +4436,7 @@ embed_idle_cb (EV_P_ ev_idle *idle, int revents)
4109
4436
  #endif
4110
4437
 
4111
4438
  void
4112
- ev_embed_start (EV_P_ ev_embed *w)
4439
+ ev_embed_start (EV_P_ ev_embed *w) EV_THROW
4113
4440
  {
4114
4441
  if (expect_false (ev_is_active (w)))
4115
4442
  return;
@@ -4140,7 +4467,7 @@ ev_embed_start (EV_P_ ev_embed *w)
4140
4467
  }
4141
4468
 
4142
4469
  void
4143
- ev_embed_stop (EV_P_ ev_embed *w)
4470
+ ev_embed_stop (EV_P_ ev_embed *w) EV_THROW
4144
4471
  {
4145
4472
  clear_pending (EV_A_ (W)w);
4146
4473
  if (expect_false (!ev_is_active (w)))
@@ -4160,7 +4487,7 @@ ev_embed_stop (EV_P_ ev_embed *w)
4160
4487
 
4161
4488
  #if EV_FORK_ENABLE
4162
4489
  void
4163
- ev_fork_start (EV_P_ ev_fork *w)
4490
+ ev_fork_start (EV_P_ ev_fork *w) EV_THROW
4164
4491
  {
4165
4492
  if (expect_false (ev_is_active (w)))
4166
4493
  return;
@@ -4175,7 +4502,7 @@ ev_fork_start (EV_P_ ev_fork *w)
4175
4502
  }
4176
4503
 
4177
4504
  void
4178
- ev_fork_stop (EV_P_ ev_fork *w)
4505
+ ev_fork_stop (EV_P_ ev_fork *w) EV_THROW
4179
4506
  {
4180
4507
  clear_pending (EV_A_ (W)w);
4181
4508
  if (expect_false (!ev_is_active (w)))
@@ -4198,7 +4525,7 @@ ev_fork_stop (EV_P_ ev_fork *w)
4198
4525
 
4199
4526
  #if EV_CLEANUP_ENABLE
4200
4527
  void
4201
- ev_cleanup_start (EV_P_ ev_cleanup *w)
4528
+ ev_cleanup_start (EV_P_ ev_cleanup *w) EV_THROW
4202
4529
  {
4203
4530
  if (expect_false (ev_is_active (w)))
4204
4531
  return;
@@ -4215,7 +4542,7 @@ ev_cleanup_start (EV_P_ ev_cleanup *w)
4215
4542
  }
4216
4543
 
4217
4544
  void
4218
- ev_cleanup_stop (EV_P_ ev_cleanup *w)
4545
+ ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_THROW
4219
4546
  {
4220
4547
  clear_pending (EV_A_ (W)w);
4221
4548
  if (expect_false (!ev_is_active (w)))
@@ -4239,7 +4566,7 @@ ev_cleanup_stop (EV_P_ ev_cleanup *w)
4239
4566
 
4240
4567
  #if EV_ASYNC_ENABLE
4241
4568
  void
4242
- ev_async_start (EV_P_ ev_async *w)
4569
+ ev_async_start (EV_P_ ev_async *w) EV_THROW
4243
4570
  {
4244
4571
  if (expect_false (ev_is_active (w)))
4245
4572
  return;
@@ -4258,7 +4585,7 @@ ev_async_start (EV_P_ ev_async *w)
4258
4585
  }
4259
4586
 
4260
4587
  void
4261
- ev_async_stop (EV_P_ ev_async *w)
4588
+ ev_async_stop (EV_P_ ev_async *w) EV_THROW
4262
4589
  {
4263
4590
  clear_pending (EV_A_ (W)w);
4264
4591
  if (expect_false (!ev_is_active (w)))
@@ -4279,7 +4606,7 @@ ev_async_stop (EV_P_ ev_async *w)
4279
4606
  }
4280
4607
 
4281
4608
  void
4282
- ev_async_send (EV_P_ ev_async *w)
4609
+ ev_async_send (EV_P_ ev_async *w) EV_THROW
4283
4610
  {
4284
4611
  w->sent = 1;
4285
4612
  evpipe_write (EV_A_ &async_pending);
@@ -4326,7 +4653,7 @@ once_cb_to (EV_P_ ev_timer *w, int revents)
4326
4653
  }
4327
4654
 
4328
4655
  void
4329
- ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg)
4656
+ ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_THROW
4330
4657
  {
4331
4658
  struct ev_once *once = (struct ev_once *)ev_malloc (sizeof (struct ev_once));
4332
4659
 
@@ -4358,7 +4685,7 @@ ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, vo
4358
4685
 
4359
4686
  #if EV_WALK_ENABLE
4360
4687
  void ecb_cold
4361
- ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w))
4688
+ ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_THROW
4362
4689
  {
4363
4690
  int i, j;
4364
4691
  ev_watcher_list *wl, *wn;