grpc 1.2.5 → 1.3.4

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

Potentially problematic release.


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

Files changed (327) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +1434 -399
  3. data/etc/roots.pem +34 -150
  4. data/include/grpc/grpc.h +71 -0
  5. data/include/grpc/impl/codegen/atm.h +5 -0
  6. data/include/grpc/impl/codegen/atm_gcc_atomic.h +6 -0
  7. data/include/grpc/impl/codegen/atm_gcc_sync.h +2 -0
  8. data/include/grpc/impl/codegen/atm_windows.h +11 -0
  9. data/include/grpc/impl/codegen/grpc_types.h +54 -13
  10. data/include/grpc/impl/codegen/port_platform.h +15 -1
  11. data/include/grpc/support/alloc.h +2 -1
  12. data/include/grpc/support/sync.h +4 -0
  13. data/include/grpc/support/tls.h +1 -1
  14. data/src/core/ext/census/gen/trace_context.pb.h +1 -1
  15. data/src/core/ext/census/grpc_filter.c +14 -10
  16. data/src/core/ext/census/grpc_plugin.c +3 -1
  17. data/src/core/ext/census/trace_label.h +1 -1
  18. data/src/core/ext/census/trace_propagation.h +1 -1
  19. data/src/core/ext/census/trace_status.h +1 -1
  20. data/src/core/ext/census/trace_string.h +1 -1
  21. data/src/core/ext/census/tracing.h +1 -1
  22. data/src/core/ext/{client_channel → filters/client_channel}/channel_connectivity.c +56 -27
  23. data/src/core/ext/{client_channel → filters/client_channel}/client_channel.c +407 -202
  24. data/src/core/ext/{client_channel → filters/client_channel}/client_channel.h +10 -6
  25. data/src/core/ext/{client_channel → filters/client_channel}/client_channel_factory.c +1 -1
  26. data/src/core/ext/{client_channel → filters/client_channel}/client_channel_factory.h +4 -4
  27. data/src/core/ext/{client_channel → filters/client_channel}/client_channel_plugin.c +12 -7
  28. data/src/core/ext/{client_channel → filters/client_channel}/connector.c +1 -1
  29. data/src/core/ext/{client_channel → filters/client_channel}/connector.h +3 -5
  30. data/src/core/ext/{client_channel → filters/client_channel}/http_connect_handshaker.c +6 -6
  31. data/src/core/ext/{client_channel → filters/client_channel}/http_connect_handshaker.h +3 -3
  32. data/src/core/ext/{client_channel → filters/client_channel}/http_proxy.c +4 -4
  33. data/src/core/ext/{client_channel → filters/client_channel}/http_proxy.h +3 -3
  34. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy.c +1 -1
  35. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy.h +4 -4
  36. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb.c +22 -20
  37. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb.h +4 -4
  38. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb_channel.h +5 -4
  39. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb_channel_secure.c +2 -2
  40. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/load_balancer_api.c +1 -1
  41. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/load_balancer_api.h +6 -5
  42. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +1 -1
  43. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +0 -0
  44. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/pick_first/pick_first.c +20 -15
  45. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/round_robin/round_robin.c +21 -16
  46. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_factory.c +1 -1
  47. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_factory.h +5 -5
  48. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_registry.c +1 -1
  49. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_registry.h +4 -4
  50. data/src/core/ext/{client_channel → filters/client_channel}/parse_address.c +1 -1
  51. data/src/core/ext/{client_channel → filters/client_channel}/parse_address.h +4 -4
  52. data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper.c +1 -1
  53. data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper.h +3 -3
  54. data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper_registry.c +10 -4
  55. data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper_registry.h +4 -4
  56. data/src/core/ext/{client_channel → filters/client_channel}/resolver.c +1 -1
  57. data/src/core/ext/{client_channel → filters/client_channel}/resolver.h +4 -4
  58. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c +350 -0
  59. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +66 -0
  60. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c +319 -0
  61. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c +289 -0
  62. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +64 -0
  63. data/src/core/ext/{resolver → filters/client_channel/resolver}/dns/native/dns_resolver.c +21 -5
  64. data/src/core/ext/{resolver → filters/client_channel/resolver}/sockaddr/sockaddr_resolver.c +3 -3
  65. data/src/core/ext/{client_channel → filters/client_channel}/resolver_factory.c +1 -1
  66. data/src/core/ext/{client_channel → filters/client_channel}/resolver_factory.h +6 -6
  67. data/src/core/ext/{client_channel → filters/client_channel}/resolver_registry.c +1 -2
  68. data/src/core/ext/{client_channel → filters/client_channel}/resolver_registry.h +4 -4
  69. data/src/core/ext/filters/client_channel/retry_throttle.c +210 -0
  70. data/src/core/ext/filters/client_channel/retry_throttle.h +65 -0
  71. data/src/core/ext/{client_channel → filters/client_channel}/subchannel.c +49 -43
  72. data/src/core/ext/{client_channel → filters/client_channel}/subchannel.h +21 -7
  73. data/src/core/ext/{client_channel → filters/client_channel}/subchannel_index.c +1 -1
  74. data/src/core/ext/{client_channel → filters/client_channel}/subchannel_index.h +5 -5
  75. data/src/core/ext/{client_channel → filters/client_channel}/uri_parser.c +1 -1
  76. data/src/core/ext/{client_channel → filters/client_channel}/uri_parser.h +3 -3
  77. data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting.c +4 -2
  78. data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting.h +3 -3
  79. data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting_filter.c +17 -14
  80. data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting_filter.h +4 -4
  81. data/src/core/ext/filters/max_age/max_age_filter.c +439 -0
  82. data/src/core/ext/filters/max_age/max_age_filter.h +39 -0
  83. data/src/core/ext/transport/chttp2/client/chttp2_connector.c +6 -41
  84. data/src/core/ext/transport/chttp2/client/chttp2_connector.h +1 -1
  85. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +2 -2
  86. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +3 -3
  87. data/src/core/ext/transport/chttp2/server/chttp2_server.c +2 -2
  88. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c +2 -5
  89. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +2 -2
  90. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +449 -204
  91. data/src/core/ext/transport/chttp2/transport/frame_data.c +10 -7
  92. data/src/core/ext/transport/chttp2/transport/frame_goaway.c +3 -2
  93. data/src/core/ext/transport/chttp2/transport/frame_ping.c +37 -7
  94. data/src/core/ext/transport/chttp2/transport/frame_ping.h +3 -0
  95. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +4 -3
  96. data/src/core/ext/transport/chttp2/transport/frame_settings.c +18 -38
  97. data/src/core/ext/transport/chttp2/transport/frame_settings.h +1 -29
  98. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +2 -2
  99. data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +64 -37
  100. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +11 -4
  101. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +60 -39
  102. data/src/core/ext/transport/chttp2/transport/hpack_table.c +2 -2
  103. data/src/core/ext/transport/chttp2/transport/http2_settings.c +75 -0
  104. data/src/core/ext/transport/chttp2/transport/http2_settings.h +74 -0
  105. data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +22 -43
  106. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +8 -10
  107. data/src/core/ext/transport/chttp2/transport/internal.h +24 -2
  108. data/src/core/ext/transport/chttp2/transport/parsing.c +33 -15
  109. data/src/core/ext/transport/chttp2/transport/writing.c +56 -10
  110. data/src/core/lib/channel/channel_args.c +7 -0
  111. data/src/core/lib/channel/channel_args.h +2 -0
  112. data/src/core/lib/channel/channel_stack.c +20 -27
  113. data/src/core/lib/channel/channel_stack.h +18 -16
  114. data/src/core/lib/channel/compress_filter.c +20 -18
  115. data/src/core/lib/channel/connected_channel.c +9 -8
  116. data/src/core/lib/channel/deadline_filter.c +28 -24
  117. data/src/core/lib/channel/deadline_filter.h +3 -3
  118. data/src/core/lib/channel/handshaker.c +3 -2
  119. data/src/core/lib/channel/http_client_filter.c +119 -61
  120. data/src/core/lib/channel/http_server_filter.c +124 -69
  121. data/src/core/lib/channel/message_size_filter.c +23 -19
  122. data/src/core/lib/http/httpcli.c +8 -6
  123. data/src/core/lib/http/httpcli_security_connector.c +5 -5
  124. data/src/core/lib/http/parser.c +57 -31
  125. data/src/core/lib/iomgr/closure.c +15 -0
  126. data/src/core/lib/iomgr/closure.h +4 -0
  127. data/src/core/lib/iomgr/combiner.c +8 -0
  128. data/src/core/lib/iomgr/endpoint_pair.h +2 -3
  129. data/src/core/lib/iomgr/endpoint_pair_posix.c +10 -7
  130. data/src/core/lib/iomgr/endpoint_pair_uv.c +2 -3
  131. data/src/core/lib/iomgr/endpoint_pair_windows.c +9 -6
  132. data/src/core/lib/iomgr/error.c +360 -177
  133. data/src/core/lib/iomgr/error.h +31 -33
  134. data/src/core/lib/iomgr/error_internal.h +30 -9
  135. data/src/core/lib/iomgr/ev_epoll_linux.c +25 -239
  136. data/src/core/lib/iomgr/ev_poll_posix.c +11 -7
  137. data/src/core/lib/iomgr/ev_posix.c +6 -0
  138. data/src/core/lib/iomgr/ev_posix.h +3 -0
  139. data/src/core/lib/iomgr/exec_ctx.c +6 -0
  140. data/src/core/lib/iomgr/executor.c +8 -2
  141. data/src/core/lib/iomgr/load_file.c +6 -3
  142. data/src/core/lib/iomgr/lockfree_event.c +238 -0
  143. data/src/core/{ext/client_channel/initial_connect_string.h → lib/iomgr/lockfree_event.h} +17 -13
  144. data/src/core/lib/iomgr/pollset.h +4 -0
  145. data/src/core/lib/iomgr/pollset_windows.c +2 -2
  146. data/src/core/lib/iomgr/port.h +9 -0
  147. data/src/core/lib/iomgr/resolve_address_posix.c +15 -9
  148. data/src/core/lib/iomgr/resolve_address_uv.c +8 -6
  149. data/src/core/lib/iomgr/resolve_address_windows.c +2 -2
  150. data/src/core/lib/iomgr/resource_quota.c +19 -4
  151. data/src/core/lib/iomgr/resource_quota.h +2 -0
  152. data/src/core/lib/iomgr/sockaddr_utils.c +3 -1
  153. data/src/core/lib/iomgr/socket_factory_posix.c +110 -0
  154. data/src/core/lib/iomgr/socket_factory_posix.h +90 -0
  155. data/src/core/lib/iomgr/socket_utils_common_posix.c +25 -9
  156. data/src/core/lib/iomgr/socket_utils_posix.h +7 -0
  157. data/src/core/lib/iomgr/tcp_client.h +0 -4
  158. data/src/core/lib/iomgr/tcp_client_posix.c +15 -31
  159. data/src/core/lib/iomgr/tcp_client_uv.c +10 -6
  160. data/src/core/lib/iomgr/tcp_client_windows.c +9 -19
  161. data/src/core/lib/iomgr/tcp_posix.c +111 -22
  162. data/src/core/lib/iomgr/tcp_posix.h +3 -4
  163. data/src/core/lib/iomgr/tcp_server_posix.c +39 -417
  164. data/src/core/lib/iomgr/tcp_server_utils_posix.h +135 -0
  165. data/src/core/lib/iomgr/tcp_server_utils_posix_common.c +221 -0
  166. data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c +196 -0
  167. data/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c +49 -0
  168. data/src/core/lib/iomgr/tcp_server_uv.c +43 -16
  169. data/src/core/lib/iomgr/tcp_server_windows.c +10 -22
  170. data/src/core/lib/iomgr/tcp_uv.c +16 -13
  171. data/src/core/lib/iomgr/tcp_windows.c +24 -12
  172. data/src/core/lib/iomgr/tcp_windows.h +2 -2
  173. data/src/core/lib/iomgr/timer.h +3 -0
  174. data/src/core/lib/iomgr/timer_generic.c +257 -72
  175. data/src/core/lib/iomgr/timer_generic.h +1 -1
  176. data/src/core/lib/iomgr/timer_heap.c +8 -8
  177. data/src/core/lib/iomgr/udp_server.c +54 -24
  178. data/src/core/lib/iomgr/udp_server.h +7 -7
  179. data/src/core/lib/iomgr/unix_sockets_posix.c +1 -1
  180. data/src/core/lib/iomgr/unix_sockets_posix_noop.c +2 -1
  181. data/src/core/lib/iomgr/wakeup_fd_posix.h +1 -1
  182. data/src/core/lib/profiling/basic_timers.c +1 -1
  183. data/src/core/lib/security/credentials/credentials.h +1 -1
  184. data/src/core/lib/security/credentials/google_default/google_default_credentials.c +10 -9
  185. data/src/core/lib/security/credentials/jwt/json_token.c +1 -1
  186. data/src/core/lib/security/credentials/jwt/jwt_verifier.c +2 -2
  187. data/src/core/lib/security/transport/client_auth_filter.c +33 -26
  188. data/src/core/lib/security/transport/secure_endpoint.c +8 -5
  189. data/src/core/lib/security/transport/security_connector.c +37 -37
  190. data/src/core/lib/security/transport/security_connector.h +1 -1
  191. data/src/core/lib/security/transport/security_handshaker.c +15 -12
  192. data/src/core/lib/security/transport/server_auth_filter.c +20 -18
  193. data/src/core/lib/security/transport/tsi_error.c +5 -3
  194. data/src/core/lib/security/transport/tsi_error.h +1 -1
  195. data/src/core/lib/{security/util → slice}/b64.c +21 -6
  196. data/src/core/lib/{security/util → slice}/b64.h +16 -4
  197. data/src/core/lib/slice/slice.c +4 -2
  198. data/src/core/lib/slice/slice_buffer.c +16 -14
  199. data/src/core/lib/support/arena.c +98 -0
  200. data/src/core/{ext/client_channel/initial_connect_string.c → lib/support/arena.h} +17 -15
  201. data/src/core/{ext/client_channel/default_initial_connect_string.c → lib/support/atm.c} +14 -5
  202. data/src/core/lib/support/cpu_linux.c +5 -0
  203. data/src/core/lib/support/sync.c +4 -0
  204. data/src/core/lib/support/time.c +4 -10
  205. data/src/core/lib/support/wrap_memcpy.c +3 -1
  206. data/src/core/lib/surface/call.c +252 -221
  207. data/src/core/lib/surface/channel.c +72 -21
  208. data/src/core/lib/surface/channel.h +8 -0
  209. data/src/core/lib/surface/completion_queue.c +2 -3
  210. data/src/core/lib/surface/completion_queue_factory.c +77 -0
  211. data/src/core/lib/surface/completion_queue_factory.h +51 -0
  212. data/src/core/lib/surface/init_secure.c +3 -1
  213. data/src/core/lib/surface/lame_client.c +18 -14
  214. data/src/core/lib/surface/server.c +43 -41
  215. data/src/core/lib/surface/validate_metadata.c +8 -4
  216. data/src/core/lib/surface/version.c +2 -2
  217. data/src/core/lib/transport/bdp_estimator.h +1 -1
  218. data/src/core/lib/transport/connectivity_state.c +2 -1
  219. data/src/core/lib/transport/error_utils.c +17 -17
  220. data/src/core/lib/transport/error_utils.h +1 -1
  221. data/src/core/lib/transport/metadata_batch.c +6 -7
  222. data/src/core/lib/transport/pid_controller.c +1 -0
  223. data/src/core/lib/transport/service_config.c +12 -0
  224. data/src/core/lib/transport/service_config.h +6 -0
  225. data/src/core/lib/transport/transport.c +29 -17
  226. data/src/core/lib/transport/transport.h +85 -42
  227. data/src/core/lib/transport/transport_impl.h +5 -3
  228. data/src/core/lib/transport/transport_op_string.c +20 -14
  229. data/src/core/plugin_registry/grpc_plugin_registry.c +8 -0
  230. data/src/core/{lib/tsi → tsi}/fake_transport_security.c +2 -2
  231. data/src/core/{lib/tsi → tsi}/fake_transport_security.h +4 -4
  232. data/src/core/{lib/tsi → tsi}/ssl_transport_security.c +40 -79
  233. data/src/core/{lib/tsi → tsi}/ssl_transport_security.h +44 -21
  234. data/src/core/{lib/tsi → tsi}/ssl_types.h +3 -3
  235. data/src/core/{lib/tsi → tsi}/transport_security.c +2 -2
  236. data/src/core/{lib/tsi → tsi}/transport_security.h +4 -4
  237. data/src/core/{lib/tsi → tsi}/transport_security_interface.h +3 -3
  238. data/src/ruby/ext/grpc/extconf.rb +1 -0
  239. data/src/ruby/ext/grpc/rb_call_credentials.c +2 -2
  240. data/src/ruby/ext/grpc/rb_channel.c +520 -93
  241. data/src/ruby/ext/grpc/rb_channel.h +2 -0
  242. data/src/ruby/ext/grpc/rb_channel_credentials.c +3 -0
  243. data/src/ruby/ext/grpc/rb_compression_options.c +5 -2
  244. data/src/ruby/ext/grpc/rb_event_thread.c +6 -6
  245. data/src/ruby/ext/grpc/rb_grpc.c +29 -7
  246. data/src/ruby/ext/grpc/rb_grpc.h +2 -0
  247. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +10 -0
  248. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +15 -0
  249. data/src/ruby/ext/grpc/rb_server.c +5 -3
  250. data/src/ruby/lib/grpc/version.rb +1 -1
  251. data/src/ruby/spec/channel_connection_spec.rb +173 -0
  252. data/src/ruby/spec/channel_spec.rb +29 -0
  253. data/src/ruby/spec/generic/rpc_server_pool_spec.rb +27 -17
  254. data/third_party/cares/ares_build.h +264 -0
  255. data/third_party/cares/cares/ares.h +636 -0
  256. data/third_party/cares/cares/ares__close_sockets.c +61 -0
  257. data/third_party/cares/cares/ares__get_hostent.c +261 -0
  258. data/third_party/cares/cares/ares__read_line.c +73 -0
  259. data/third_party/cares/cares/ares__timeval.c +111 -0
  260. data/third_party/cares/cares/ares_cancel.c +63 -0
  261. data/third_party/cares/cares/ares_create_query.c +202 -0
  262. data/third_party/cares/cares/ares_data.c +221 -0
  263. data/third_party/cares/cares/ares_data.h +72 -0
  264. data/third_party/cares/cares/ares_destroy.c +108 -0
  265. data/third_party/cares/cares/ares_dns.h +103 -0
  266. data/third_party/cares/cares/ares_expand_name.c +205 -0
  267. data/third_party/cares/cares/ares_expand_string.c +70 -0
  268. data/third_party/cares/cares/ares_fds.c +59 -0
  269. data/third_party/cares/cares/ares_free_hostent.c +41 -0
  270. data/third_party/cares/cares/ares_free_string.c +25 -0
  271. data/third_party/cares/cares/ares_getenv.c +30 -0
  272. data/third_party/cares/cares/ares_getenv.h +26 -0
  273. data/third_party/cares/cares/ares_gethostbyaddr.c +294 -0
  274. data/third_party/cares/cares/ares_gethostbyname.c +518 -0
  275. data/third_party/cares/cares/ares_getnameinfo.c +422 -0
  276. data/third_party/cares/cares/ares_getopt.c +122 -0
  277. data/third_party/cares/cares/ares_getopt.h +53 -0
  278. data/third_party/cares/cares/ares_getsock.c +66 -0
  279. data/third_party/cares/cares/ares_inet_net_pton.h +25 -0
  280. data/third_party/cares/cares/ares_init.c +2146 -0
  281. data/third_party/cares/cares/ares_iphlpapi.h +221 -0
  282. data/third_party/cares/cares/ares_ipv6.h +78 -0
  283. data/third_party/cares/cares/ares_library_init.c +167 -0
  284. data/third_party/cares/cares/ares_library_init.h +42 -0
  285. data/third_party/cares/cares/ares_llist.c +63 -0
  286. data/third_party/cares/cares/ares_llist.h +39 -0
  287. data/third_party/cares/cares/ares_mkquery.c +24 -0
  288. data/third_party/cares/cares/ares_nowarn.c +260 -0
  289. data/third_party/cares/cares/ares_nowarn.h +61 -0
  290. data/third_party/cares/cares/ares_options.c +402 -0
  291. data/third_party/cares/cares/ares_parse_a_reply.c +264 -0
  292. data/third_party/cares/cares/ares_parse_aaaa_reply.c +264 -0
  293. data/third_party/cares/cares/ares_parse_mx_reply.c +170 -0
  294. data/third_party/cares/cares/ares_parse_naptr_reply.c +188 -0
  295. data/third_party/cares/cares/ares_parse_ns_reply.c +183 -0
  296. data/third_party/cares/cares/ares_parse_ptr_reply.c +219 -0
  297. data/third_party/cares/cares/ares_parse_soa_reply.c +133 -0
  298. data/third_party/cares/cares/ares_parse_srv_reply.c +179 -0
  299. data/third_party/cares/cares/ares_parse_txt_reply.c +220 -0
  300. data/third_party/cares/cares/ares_platform.c +11035 -0
  301. data/third_party/cares/cares/ares_platform.h +43 -0
  302. data/third_party/cares/cares/ares_private.h +363 -0
  303. data/third_party/cares/cares/ares_process.c +1359 -0
  304. data/third_party/cares/cares/ares_query.c +186 -0
  305. data/third_party/cares/cares/ares_rules.h +125 -0
  306. data/third_party/cares/cares/ares_search.c +316 -0
  307. data/third_party/cares/cares/ares_send.c +131 -0
  308. data/third_party/cares/cares/ares_setup.h +217 -0
  309. data/third_party/cares/cares/ares_strcasecmp.c +66 -0
  310. data/third_party/cares/cares/ares_strcasecmp.h +30 -0
  311. data/third_party/cares/cares/ares_strdup.c +49 -0
  312. data/third_party/cares/cares/ares_strdup.h +24 -0
  313. data/third_party/cares/cares/ares_strerror.c +56 -0
  314. data/third_party/cares/cares/ares_timeout.c +88 -0
  315. data/third_party/cares/cares/ares_version.c +11 -0
  316. data/third_party/cares/cares/ares_version.h +24 -0
  317. data/third_party/cares/cares/ares_writev.c +79 -0
  318. data/third_party/cares/cares/bitncmp.c +59 -0
  319. data/third_party/cares/cares/bitncmp.h +26 -0
  320. data/third_party/cares/cares/config-win32.h +377 -0
  321. data/third_party/cares/cares/inet_net_pton.c +450 -0
  322. data/third_party/cares/cares/inet_ntop.c +208 -0
  323. data/third_party/cares/cares/setup_once.h +554 -0
  324. data/third_party/cares/cares/windows_port.c +22 -0
  325. data/third_party/cares/config_darwin/ares_config.h +523 -0
  326. data/third_party/cares/config_linux/ares_config.h +524 -0
  327. metadata +164 -68
@@ -101,6 +101,9 @@ bool grpc_timer_check(grpc_exec_ctx *exec_ctx, gpr_timespec now,
101
101
  void grpc_timer_list_init(gpr_timespec now);
102
102
  void grpc_timer_list_shutdown(grpc_exec_ctx *exec_ctx);
103
103
 
104
+ /* Consume a kick issued by grpc_kick_poller */
105
+ void grpc_timer_consume_kick(void);
106
+
104
107
  /* the following must be implemented by each iomgr implementation */
105
108
 
106
109
  void grpc_kick_poller(void);
@@ -37,9 +37,13 @@
37
37
 
38
38
  #include "src/core/lib/iomgr/timer.h"
39
39
 
40
+ #include <grpc/support/alloc.h>
40
41
  #include <grpc/support/log.h>
42
+ #include <grpc/support/string_util.h>
41
43
  #include <grpc/support/sync.h>
44
+ #include <grpc/support/tls.h>
42
45
  #include <grpc/support/useful.h>
46
+ #include "src/core/lib/debug/trace.h"
43
47
  #include "src/core/lib/iomgr/time_averaged_stats.h"
44
48
  #include "src/core/lib/iomgr/timer_heap.h"
45
49
  #include "src/core/lib/support/spinlock.h"
@@ -52,12 +56,15 @@
52
56
  #define MIN_QUEUE_WINDOW_DURATION 0.01
53
57
  #define MAX_QUEUE_WINDOW_DURATION 1
54
58
 
59
+ int grpc_timer_trace = 0;
60
+ int grpc_timer_check_trace = 0;
61
+
55
62
  typedef struct {
56
63
  gpr_mu mu;
57
64
  grpc_time_averaged_stats stats;
58
65
  /* All and only timers with deadlines <= this will be in the heap. */
59
- gpr_timespec queue_deadline_cap;
60
- gpr_timespec min_deadline;
66
+ gpr_atm queue_deadline_cap;
67
+ gpr_atm min_deadline;
61
68
  /* Index in the g_shard_queue */
62
69
  uint32_t shard_queue_index;
63
70
  /* This holds all timers with deadlines < queue_deadline_cap. Timers in this
@@ -67,38 +74,92 @@ typedef struct {
67
74
  grpc_timer list;
68
75
  } shard_type;
69
76
 
70
- /* Protects g_shard_queue */
71
- static gpr_mu g_mu;
72
- /* Allow only one run_some_expired_timers at once */
73
- static gpr_spinlock g_checker_mu = GPR_SPINLOCK_STATIC_INITIALIZER;
77
+ struct shared_mutables {
78
+ gpr_atm min_timer;
79
+ /* Allow only one run_some_expired_timers at once */
80
+ gpr_spinlock checker_mu;
81
+ bool initialized;
82
+ /* Protects g_shard_queue */
83
+ gpr_mu mu;
84
+ } GPR_ALIGN_STRUCT(GPR_CACHELINE_SIZE);
85
+
86
+ static struct shared_mutables g_shared_mutables = {
87
+ .checker_mu = GPR_SPINLOCK_STATIC_INITIALIZER, .initialized = false,
88
+ };
74
89
  static gpr_clock_type g_clock_type;
75
90
  static shard_type g_shards[NUM_SHARDS];
76
- /* Protected by g_mu */
91
+ /* Protected by g_shared_mutables.mu */
77
92
  static shard_type *g_shard_queue[NUM_SHARDS];
78
- static bool g_initialized = false;
93
+ static gpr_timespec g_start_time;
94
+
95
+ GPR_TLS_DECL(g_last_seen_min_timer);
96
+
97
+ static gpr_atm saturating_add(gpr_atm a, gpr_atm b) {
98
+ if (a > GPR_ATM_MAX - b) {
99
+ return GPR_ATM_MAX;
100
+ }
101
+ return a + b;
102
+ }
103
+
104
+ static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_atm now,
105
+ gpr_atm *next, grpc_error *error);
106
+
107
+ static gpr_timespec dbl_to_ts(double d) {
108
+ gpr_timespec ts;
109
+ ts.tv_sec = (int64_t)d;
110
+ ts.tv_nsec = (int32_t)(1e9 * (d - (double)ts.tv_sec));
111
+ ts.clock_type = GPR_TIMESPAN;
112
+ return ts;
113
+ }
114
+
115
+ static gpr_atm timespec_to_atm_round_up(gpr_timespec ts) {
116
+ ts = gpr_time_sub(ts, g_start_time);
117
+ double x = GPR_MS_PER_SEC * (double)ts.tv_sec +
118
+ (double)ts.tv_nsec / GPR_NS_PER_MS +
119
+ (double)(GPR_NS_PER_SEC - 1) / (double)GPR_NS_PER_SEC;
120
+ if (x < 0) return 0;
121
+ if (x > GPR_ATM_MAX) return GPR_ATM_MAX;
122
+ return (gpr_atm)x;
123
+ }
124
+
125
+ static gpr_atm timespec_to_atm_round_down(gpr_timespec ts) {
126
+ ts = gpr_time_sub(ts, g_start_time);
127
+ double x =
128
+ GPR_MS_PER_SEC * (double)ts.tv_sec + (double)ts.tv_nsec / GPR_NS_PER_MS;
129
+ if (x < 0) return 0;
130
+ if (x > GPR_ATM_MAX) return GPR_ATM_MAX;
131
+ return (gpr_atm)x;
132
+ }
79
133
 
80
- static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now,
81
- gpr_timespec *next, grpc_error *error);
134
+ static gpr_timespec atm_to_timespec(gpr_atm x) {
135
+ return gpr_time_add(g_start_time, dbl_to_ts((double)x / 1000.0));
136
+ }
82
137
 
83
- static gpr_timespec compute_min_deadline(shard_type *shard) {
138
+ static gpr_atm compute_min_deadline(shard_type *shard) {
84
139
  return grpc_timer_heap_is_empty(&shard->heap)
85
- ? shard->queue_deadline_cap
140
+ ? saturating_add(shard->queue_deadline_cap, 1)
86
141
  : grpc_timer_heap_top(&shard->heap)->deadline;
87
142
  }
88
143
 
89
144
  void grpc_timer_list_init(gpr_timespec now) {
90
145
  uint32_t i;
91
146
 
92
- g_initialized = true;
93
- gpr_mu_init(&g_mu);
147
+ g_shared_mutables.initialized = true;
148
+ gpr_mu_init(&g_shared_mutables.mu);
94
149
  g_clock_type = now.clock_type;
150
+ g_start_time = now;
151
+ g_shared_mutables.min_timer = timespec_to_atm_round_down(now);
152
+ gpr_tls_init(&g_last_seen_min_timer);
153
+ gpr_tls_set(&g_last_seen_min_timer, 0);
154
+ grpc_register_tracer("timer", &grpc_timer_trace);
155
+ grpc_register_tracer("timer_check", &grpc_timer_check_trace);
95
156
 
96
157
  for (i = 0; i < NUM_SHARDS; i++) {
97
158
  shard_type *shard = &g_shards[i];
98
159
  gpr_mu_init(&shard->mu);
99
160
  grpc_time_averaged_stats_init(&shard->stats, 1.0 / ADD_DEADLINE_SCALE, 0.1,
100
161
  0.5);
101
- shard->queue_deadline_cap = now;
162
+ shard->queue_deadline_cap = g_shared_mutables.min_timer;
102
163
  shard->shard_queue_index = i;
103
164
  grpc_timer_heap_init(&shard->heap);
104
165
  shard->list.next = shard->list.prev = &shard->list;
@@ -109,29 +170,24 @@ void grpc_timer_list_init(gpr_timespec now) {
109
170
 
110
171
  void grpc_timer_list_shutdown(grpc_exec_ctx *exec_ctx) {
111
172
  int i;
112
- run_some_expired_timers(exec_ctx, gpr_inf_future(g_clock_type), NULL,
113
- GRPC_ERROR_CREATE("Timer list shutdown"));
173
+ run_some_expired_timers(
174
+ exec_ctx, GPR_ATM_MAX, NULL,
175
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Timer list shutdown"));
114
176
  for (i = 0; i < NUM_SHARDS; i++) {
115
177
  shard_type *shard = &g_shards[i];
116
178
  gpr_mu_destroy(&shard->mu);
117
179
  grpc_timer_heap_destroy(&shard->heap);
118
180
  }
119
- gpr_mu_destroy(&g_mu);
120
- g_initialized = false;
181
+ gpr_mu_destroy(&g_shared_mutables.mu);
182
+ gpr_tls_destroy(&g_last_seen_min_timer);
183
+ g_shared_mutables.initialized = false;
121
184
  }
122
185
 
123
186
  static double ts_to_dbl(gpr_timespec ts) {
124
187
  return (double)ts.tv_sec + 1e-9 * ts.tv_nsec;
125
188
  }
126
189
 
127
- static gpr_timespec dbl_to_ts(double d) {
128
- gpr_timespec ts;
129
- ts.tv_sec = (int64_t)d;
130
- ts.tv_nsec = (int32_t)(1e9 * (d - (double)ts.tv_sec));
131
- ts.clock_type = GPR_TIMESPAN;
132
- return ts;
133
- }
134
-
190
+ /* returns true if the first element in the list */
135
191
  static void list_join(grpc_timer *head, grpc_timer *timer) {
136
192
  timer->next = head;
137
193
  timer->prev = head->prev;
@@ -157,15 +213,13 @@ static void swap_adjacent_shards_in_queue(uint32_t first_shard_queue_index) {
157
213
 
158
214
  static void note_deadline_change(shard_type *shard) {
159
215
  while (shard->shard_queue_index > 0 &&
160
- gpr_time_cmp(
161
- shard->min_deadline,
162
- g_shard_queue[shard->shard_queue_index - 1]->min_deadline) < 0) {
216
+ shard->min_deadline <
217
+ g_shard_queue[shard->shard_queue_index - 1]->min_deadline) {
163
218
  swap_adjacent_shards_in_queue(shard->shard_queue_index - 1);
164
219
  }
165
220
  while (shard->shard_queue_index < NUM_SHARDS - 1 &&
166
- gpr_time_cmp(
167
- shard->min_deadline,
168
- g_shard_queue[shard->shard_queue_index + 1]->min_deadline) > 0) {
221
+ shard->min_deadline >
222
+ g_shard_queue[shard->shard_queue_index + 1]->min_deadline) {
169
223
  swap_adjacent_shards_in_queue(shard->shard_queue_index);
170
224
  }
171
225
  }
@@ -178,13 +232,21 @@ void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
178
232
  GPR_ASSERT(deadline.clock_type == g_clock_type);
179
233
  GPR_ASSERT(now.clock_type == g_clock_type);
180
234
  timer->closure = closure;
181
- timer->deadline = deadline;
235
+ timer->deadline = timespec_to_atm_round_up(deadline);
236
+
237
+ if (grpc_timer_trace) {
238
+ gpr_log(GPR_DEBUG, "TIMER %p: SET %" PRId64 ".%09d [%" PRIdPTR
239
+ "] now %" PRId64 ".%09d [%" PRIdPTR "] call %p[%p]",
240
+ timer, deadline.tv_sec, deadline.tv_nsec, timer->deadline,
241
+ now.tv_sec, now.tv_nsec, timespec_to_atm_round_down(now), closure,
242
+ closure->cb);
243
+ }
182
244
 
183
- if (!g_initialized) {
245
+ if (!g_shared_mutables.initialized) {
184
246
  timer->pending = false;
185
- grpc_closure_sched(
186
- exec_ctx, timer->closure,
187
- GRPC_ERROR_CREATE("Attempt to create timer before initialization"));
247
+ grpc_closure_sched(exec_ctx, timer->closure,
248
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING(
249
+ "Attempt to create timer before initialization"));
188
250
  return;
189
251
  }
190
252
 
@@ -200,12 +262,18 @@ void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
200
262
 
201
263
  grpc_time_averaged_stats_add_sample(&shard->stats,
202
264
  ts_to_dbl(gpr_time_sub(deadline, now)));
203
- if (gpr_time_cmp(deadline, shard->queue_deadline_cap) < 0) {
265
+ if (timer->deadline < shard->queue_deadline_cap) {
204
266
  is_first_timer = grpc_timer_heap_add(&shard->heap, timer);
205
267
  } else {
206
268
  timer->heap_index = INVALID_HEAP_INDEX;
207
269
  list_join(&shard->list, timer);
208
270
  }
271
+ if (grpc_timer_trace) {
272
+ gpr_log(GPR_DEBUG, " .. add to shard %d with queue_deadline_cap=%" PRIdPTR
273
+ " => is_first_timer=%s",
274
+ (int)(shard - g_shards), shard->queue_deadline_cap,
275
+ is_first_timer ? "true" : "false");
276
+ }
209
277
  gpr_mu_unlock(&shard->mu);
210
278
 
211
279
  /* Deadline may have decreased, we need to adjust the master queue. Note
@@ -220,28 +288,41 @@ void grpc_timer_init(grpc_exec_ctx *exec_ctx, grpc_timer *timer,
220
288
  In that case, the timer will simply have to wait for the next
221
289
  grpc_timer_check. */
222
290
  if (is_first_timer) {
223
- gpr_mu_lock(&g_mu);
224
- if (gpr_time_cmp(deadline, shard->min_deadline) < 0) {
225
- gpr_timespec old_min_deadline = g_shard_queue[0]->min_deadline;
226
- shard->min_deadline = deadline;
291
+ gpr_mu_lock(&g_shared_mutables.mu);
292
+ if (grpc_timer_trace) {
293
+ gpr_log(GPR_DEBUG, " .. old shard min_deadline=%" PRIdPTR,
294
+ shard->min_deadline);
295
+ }
296
+ if (timer->deadline < shard->min_deadline) {
297
+ gpr_atm old_min_deadline = g_shard_queue[0]->min_deadline;
298
+ shard->min_deadline = timer->deadline;
227
299
  note_deadline_change(shard);
228
- if (shard->shard_queue_index == 0 &&
229
- gpr_time_cmp(deadline, old_min_deadline) < 0) {
300
+ if (shard->shard_queue_index == 0 && timer->deadline < old_min_deadline) {
301
+ gpr_atm_no_barrier_store(&g_shared_mutables.min_timer, timer->deadline);
230
302
  grpc_kick_poller();
231
303
  }
232
304
  }
233
- gpr_mu_unlock(&g_mu);
305
+ gpr_mu_unlock(&g_shared_mutables.mu);
234
306
  }
235
307
  }
236
308
 
309
+ void grpc_timer_consume_kick(void) {
310
+ /* force re-evaluation of last seeen min */
311
+ gpr_tls_set(&g_last_seen_min_timer, 0);
312
+ }
313
+
237
314
  void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer) {
238
- if (!g_initialized) {
315
+ if (!g_shared_mutables.initialized) {
239
316
  /* must have already been cancelled, also the shard mutex is invalid */
240
317
  return;
241
318
  }
242
319
 
243
320
  shard_type *shard = &g_shards[GPR_HASH_POINTER(timer, NUM_SHARDS)];
244
321
  gpr_mu_lock(&shard->mu);
322
+ if (grpc_timer_trace) {
323
+ gpr_log(GPR_DEBUG, "TIMER %p: CANCEL pending=%s", timer,
324
+ timer->pending ? "true" : "false");
325
+ }
245
326
  if (timer->pending) {
246
327
  grpc_closure_sched(exec_ctx, timer->closure, GRPC_ERROR_CANCELLED);
247
328
  timer->pending = false;
@@ -259,7 +340,7 @@ void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer) {
259
340
  for timers that fall at or under it. Returns true if the queue is no
260
341
  longer empty.
261
342
  REQUIRES: shard->mu locked */
262
- static int refill_queue(shard_type *shard, gpr_timespec now) {
343
+ static int refill_queue(shard_type *shard, gpr_atm now) {
263
344
  /* Compute the new queue window width and bound by the limits: */
264
345
  double computed_deadline_delta =
265
346
  grpc_time_averaged_stats_update_average(&shard->stats) *
@@ -270,12 +351,22 @@ static int refill_queue(shard_type *shard, gpr_timespec now) {
270
351
  grpc_timer *timer, *next;
271
352
 
272
353
  /* Compute the new cap and put all timers under it into the queue: */
273
- shard->queue_deadline_cap = gpr_time_add(
274
- gpr_time_max(now, shard->queue_deadline_cap), dbl_to_ts(deadline_delta));
354
+ shard->queue_deadline_cap =
355
+ saturating_add(GPR_MAX(now, shard->queue_deadline_cap),
356
+ (gpr_atm)(deadline_delta * 1000.0));
357
+
358
+ if (grpc_timer_check_trace) {
359
+ gpr_log(GPR_DEBUG, " .. shard[%d]->queue_deadline_cap --> %" PRIdPTR,
360
+ (int)(shard - g_shards), shard->queue_deadline_cap);
361
+ }
275
362
  for (timer = shard->list.next; timer != &shard->list; timer = next) {
276
363
  next = timer->next;
277
364
 
278
- if (gpr_time_cmp(timer->deadline, shard->queue_deadline_cap) < 0) {
365
+ if (timer->deadline < shard->queue_deadline_cap) {
366
+ if (grpc_timer_check_trace) {
367
+ gpr_log(GPR_DEBUG, " .. add timer with deadline %" PRIdPTR " to heap",
368
+ timer->deadline);
369
+ }
279
370
  list_remove(timer);
280
371
  grpc_timer_heap_add(&shard->heap, timer);
281
372
  }
@@ -286,15 +377,29 @@ static int refill_queue(shard_type *shard, gpr_timespec now) {
286
377
  /* This pops the next non-cancelled timer with deadline <= now from the
287
378
  queue, or returns NULL if there isn't one.
288
379
  REQUIRES: shard->mu locked */
289
- static grpc_timer *pop_one(shard_type *shard, gpr_timespec now) {
380
+ static grpc_timer *pop_one(shard_type *shard, gpr_atm now) {
290
381
  grpc_timer *timer;
291
382
  for (;;) {
383
+ if (grpc_timer_check_trace) {
384
+ gpr_log(GPR_DEBUG, " .. shard[%d]: heap_empty=%s",
385
+ (int)(shard - g_shards),
386
+ grpc_timer_heap_is_empty(&shard->heap) ? "true" : "false");
387
+ }
292
388
  if (grpc_timer_heap_is_empty(&shard->heap)) {
293
- if (gpr_time_cmp(now, shard->queue_deadline_cap) < 0) return NULL;
389
+ if (now < shard->queue_deadline_cap) return NULL;
294
390
  if (!refill_queue(shard, now)) return NULL;
295
391
  }
296
392
  timer = grpc_timer_heap_top(&shard->heap);
297
- if (gpr_time_cmp(timer->deadline, now) > 0) return NULL;
393
+ if (grpc_timer_check_trace) {
394
+ gpr_log(GPR_DEBUG,
395
+ " .. check top timer deadline=%" PRIdPTR " now=%" PRIdPTR,
396
+ timer->deadline, now);
397
+ }
398
+ if (timer->deadline > now) return NULL;
399
+ if (grpc_timer_trace) {
400
+ gpr_log(GPR_DEBUG, "TIMER %p: FIRE %" PRIdPTR "ms late", timer,
401
+ now - timer->deadline);
402
+ }
298
403
  timer->pending = false;
299
404
  grpc_timer_heap_pop(&shard->heap);
300
405
  return timer;
@@ -303,7 +408,7 @@ static grpc_timer *pop_one(shard_type *shard, gpr_timespec now) {
303
408
 
304
409
  /* REQUIRES: shard->mu unlocked */
305
410
  static size_t pop_timers(grpc_exec_ctx *exec_ctx, shard_type *shard,
306
- gpr_timespec now, gpr_timespec *new_min_deadline,
411
+ gpr_atm now, gpr_atm *new_min_deadline,
307
412
  grpc_error *error) {
308
413
  size_t n = 0;
309
414
  grpc_timer *timer;
@@ -317,17 +422,29 @@ static size_t pop_timers(grpc_exec_ctx *exec_ctx, shard_type *shard,
317
422
  return n;
318
423
  }
319
424
 
320
- static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now,
321
- gpr_timespec *next, grpc_error *error) {
425
+ static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_atm now,
426
+ gpr_atm *next, grpc_error *error) {
322
427
  size_t n = 0;
323
428
 
324
- /* TODO(ctiller): verify that there are any timers (atomically) here */
429
+ gpr_atm min_timer = gpr_atm_no_barrier_load(&g_shared_mutables.min_timer);
430
+ gpr_tls_set(&g_last_seen_min_timer, min_timer);
431
+ if (now < min_timer) {
432
+ if (next != NULL) *next = GPR_MIN(*next, min_timer);
433
+ return 0;
434
+ }
325
435
 
326
- if (gpr_spinlock_trylock(&g_checker_mu)) {
327
- gpr_mu_lock(&g_mu);
436
+ if (gpr_spinlock_trylock(&g_shared_mutables.checker_mu)) {
437
+ gpr_mu_lock(&g_shared_mutables.mu);
328
438
 
329
- while (gpr_time_cmp(g_shard_queue[0]->min_deadline, now) < 0) {
330
- gpr_timespec new_min_deadline;
439
+ if (grpc_timer_check_trace) {
440
+ gpr_log(GPR_DEBUG, " .. shard[%d]->min_deadline = %" PRIdPTR,
441
+ (int)(g_shard_queue[0] - g_shards),
442
+ g_shard_queue[0]->min_deadline);
443
+ }
444
+
445
+ while (g_shard_queue[0]->min_deadline < now ||
446
+ (now != GPR_ATM_MAX && g_shard_queue[0]->min_deadline == now)) {
447
+ gpr_atm new_min_deadline;
331
448
 
332
449
  /* For efficiency, we pop as many available timers as we can from the
333
450
  shard. This may violate perfect timer deadline ordering, but that
@@ -335,6 +452,14 @@ static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now,
335
452
  n +=
336
453
  pop_timers(exec_ctx, g_shard_queue[0], now, &new_min_deadline, error);
337
454
 
455
+ if (grpc_timer_check_trace) {
456
+ gpr_log(GPR_DEBUG, " .. popped --> %" PRIdPTR
457
+ ", shard[%d]->min_deadline %" PRIdPTR
458
+ " --> %" PRIdPTR ", now=%" PRIdPTR,
459
+ n, (int)(g_shard_queue[0] - g_shards),
460
+ g_shard_queue[0]->min_deadline, new_min_deadline, now);
461
+ }
462
+
338
463
  /* An grpc_timer_init() on the shard could intervene here, adding a new
339
464
  timer that is earlier than new_min_deadline. However,
340
465
  grpc_timer_init() will block on the master_lock before it can call
@@ -345,23 +470,24 @@ static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now,
345
470
  }
346
471
 
347
472
  if (next) {
348
- *next = gpr_time_min(*next, g_shard_queue[0]->min_deadline);
473
+ *next = GPR_MIN(*next, g_shard_queue[0]->min_deadline);
349
474
  }
350
475
 
351
- gpr_mu_unlock(&g_mu);
352
- gpr_spinlock_unlock(&g_checker_mu);
476
+ gpr_atm_no_barrier_store(&g_shared_mutables.min_timer,
477
+ g_shard_queue[0]->min_deadline);
478
+ gpr_mu_unlock(&g_shared_mutables.mu);
479
+ gpr_spinlock_unlock(&g_shared_mutables.checker_mu);
353
480
  } else if (next != NULL) {
354
481
  /* TODO(ctiller): this forces calling code to do an short poll, and
355
482
  then retry the timer check (because this time through the timer list was
356
483
  contended).
357
484
 
358
- We could reduce the cost here dramatically by keeping a count of how many
359
- currently active pollers got through the uncontended case above
485
+ We could reduce the cost here dramatically by keeping a count of how
486
+ many currently active pollers got through the uncontended case above
360
487
  successfully, and waking up other pollers IFF that count drops to zero.
361
488
 
362
489
  Once that count is in place, this entire else branch could disappear. */
363
- *next = gpr_time_min(
364
- *next, gpr_time_add(now, gpr_time_from_millis(1, GPR_TIMESPAN)));
490
+ *next = GPR_MIN(*next, now + 1);
365
491
  }
366
492
 
367
493
  GRPC_ERROR_UNREF(error);
@@ -371,12 +497,71 @@ static int run_some_expired_timers(grpc_exec_ctx *exec_ctx, gpr_timespec now,
371
497
 
372
498
  bool grpc_timer_check(grpc_exec_ctx *exec_ctx, gpr_timespec now,
373
499
  gpr_timespec *next) {
500
+ // prelude
374
501
  GPR_ASSERT(now.clock_type == g_clock_type);
375
- return run_some_expired_timers(
376
- exec_ctx, now, next,
502
+ gpr_atm now_atm = timespec_to_atm_round_down(now);
503
+
504
+ /* fetch from a thread-local first: this avoids contention on a globally
505
+ mutable cacheline in the common case */
506
+ gpr_atm min_timer = gpr_tls_get(&g_last_seen_min_timer);
507
+ if (now_atm < min_timer) {
508
+ if (next != NULL) {
509
+ *next =
510
+ atm_to_timespec(GPR_MIN(timespec_to_atm_round_up(*next), min_timer));
511
+ }
512
+ if (grpc_timer_check_trace) {
513
+ gpr_log(GPR_DEBUG,
514
+ "TIMER CHECK SKIP: now_atm=%" PRIdPTR " min_timer=%" PRIdPTR,
515
+ now_atm, min_timer);
516
+ }
517
+ return 0;
518
+ }
519
+
520
+ grpc_error *shutdown_error =
377
521
  gpr_time_cmp(now, gpr_inf_future(now.clock_type)) != 0
378
522
  ? GRPC_ERROR_NONE
379
- : GRPC_ERROR_CREATE("Shutting down timer system"));
523
+ : GRPC_ERROR_CREATE_FROM_STATIC_STRING("Shutting down timer system");
524
+
525
+ // tracing
526
+ if (grpc_timer_check_trace) {
527
+ char *next_str;
528
+ if (next == NULL) {
529
+ next_str = gpr_strdup("NULL");
530
+ } else {
531
+ gpr_asprintf(&next_str, "%" PRId64 ".%09d [%" PRIdPTR "]", next->tv_sec,
532
+ next->tv_nsec, timespec_to_atm_round_down(*next));
533
+ }
534
+ gpr_log(GPR_DEBUG, "TIMER CHECK BEGIN: now=%" PRId64 ".%09d [%" PRIdPTR
535
+ "] next=%s tls_min=%" PRIdPTR " glob_min=%" PRIdPTR,
536
+ now.tv_sec, now.tv_nsec, now_atm, next_str,
537
+ gpr_tls_get(&g_last_seen_min_timer),
538
+ gpr_atm_no_barrier_load(&g_shared_mutables.min_timer));
539
+ gpr_free(next_str);
540
+ }
541
+ // actual code
542
+ bool r;
543
+ gpr_atm next_atm;
544
+ if (next == NULL) {
545
+ r = run_some_expired_timers(exec_ctx, now_atm, NULL, shutdown_error);
546
+ } else {
547
+ next_atm = timespec_to_atm_round_down(*next);
548
+ r = run_some_expired_timers(exec_ctx, now_atm, &next_atm, shutdown_error);
549
+ *next = atm_to_timespec(next_atm);
550
+ }
551
+ // tracing
552
+ if (grpc_timer_check_trace) {
553
+ char *next_str;
554
+ if (next == NULL) {
555
+ next_str = gpr_strdup("NULL");
556
+ } else {
557
+ gpr_asprintf(&next_str, "%" PRId64 ".%09d [%" PRIdPTR "]", next->tv_sec,
558
+ next->tv_nsec, next_atm);
559
+ }
560
+ gpr_log(GPR_DEBUG, "TIMER CHECK END: %d timers triggered; next=%s", r,
561
+ next_str);
562
+ gpr_free(next_str);
563
+ }
564
+ return r > 0;
380
565
  }
381
566
 
382
567
  #endif /* GRPC_TIMER_USE_GENERIC */