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
@@ -31,8 +31,8 @@
31
31
  *
32
32
  */
33
33
 
34
- #ifndef GRPC_CORE_LIB_TSI_SSL_TYPES_H
35
- #define GRPC_CORE_LIB_TSI_SSL_TYPES_H
34
+ #ifndef GRPC_CORE_TSI_SSL_TYPES_H
35
+ #define GRPC_CORE_TSI_SSL_TYPES_H
36
36
 
37
37
  /* A collection of macros to cast between various integer types that are
38
38
  * used differently between BoringSSL and OpenSSL:
@@ -52,4 +52,4 @@
52
52
  #define TSI_SIZE_AS_SIZE(x) ((int)(x))
53
53
  #endif
54
54
 
55
- #endif /* GRPC_CORE_LIB_TSI_SSL_TYPES_H */
55
+ #endif /* GRPC_CORE_TSI_SSL_TYPES_H */
@@ -31,7 +31,7 @@
31
31
  *
32
32
  */
33
33
 
34
- #include "src/core/lib/tsi/transport_security.h"
34
+ #include "src/core/tsi/transport_security.h"
35
35
 
36
36
  #include <grpc/support/alloc.h>
37
37
  #include <grpc/support/string_util.h>
@@ -101,7 +101,7 @@ tsi_result tsi_frame_protector_protect_flush(
101
101
  tsi_frame_protector *self, unsigned char *protected_output_frames,
102
102
  size_t *protected_output_frames_size, size_t *still_pending_size) {
103
103
  if (self == NULL || protected_output_frames == NULL ||
104
- protected_output_frames == NULL || still_pending_size == NULL) {
104
+ protected_output_frames_size == NULL || still_pending_size == NULL) {
105
105
  return TSI_INVALID_ARGUMENT;
106
106
  }
107
107
  return self->vtable->protect_flush(self, protected_output_frames,
@@ -31,10 +31,10 @@
31
31
  *
32
32
  */
33
33
 
34
- #ifndef GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_H
35
- #define GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_H
34
+ #ifndef GRPC_CORE_TSI_TRANSPORT_SECURITY_H
35
+ #define GRPC_CORE_TSI_TRANSPORT_SECURITY_H
36
36
 
37
- #include "src/core/lib/tsi/transport_security_interface.h"
37
+ #include "src/core/tsi/transport_security_interface.h"
38
38
 
39
39
  #ifdef __cplusplus
40
40
  extern "C" {
@@ -108,4 +108,4 @@ char *tsi_strdup(const char *src); /* Sadly, no strdup in C89. */
108
108
  }
109
109
  #endif
110
110
 
111
- #endif /* GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_H */
111
+ #endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_H */
@@ -31,8 +31,8 @@
31
31
  *
32
32
  */
33
33
 
34
- #ifndef GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_INTERFACE_H
35
- #define GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_INTERFACE_H
34
+ #ifndef GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H
35
+ #define GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H
36
36
 
37
37
  #include <stdint.h>
38
38
  #include <stdlib.h>
@@ -350,4 +350,4 @@ void tsi_handshaker_destroy(tsi_handshaker *self);
350
350
  }
351
351
  #endif
352
352
 
353
- #endif /* GRPC_CORE_LIB_TSI_TRANSPORT_SECURITY_INTERFACE_H */
353
+ #endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H */
@@ -71,6 +71,7 @@ ENV['AR'] = 'libtool -o' if RUBY_PLATFORM =~ /darwin/
71
71
 
72
72
  ENV['EMBED_OPENSSL'] = 'true'
73
73
  ENV['EMBED_ZLIB'] = 'true'
74
+ ENV['EMBED_CARES'] = 'true'
74
75
  ENV['ARCH_FLAGS'] = RbConfig::CONFIG['ARCH_FLAG']
75
76
  ENV['ARCH_FLAGS'] = '-arch i386 -arch x86_64' if RUBY_PLATFORM =~ /darwin/
76
77
  ENV['CFLAGS'] = '-DGPR_BACKWARDS_COMPATIBILITY_MODE'
@@ -221,6 +221,8 @@ static VALUE grpc_rb_call_credentials_init(VALUE self, VALUE proc) {
221
221
  grpc_call_credentials *creds = NULL;
222
222
  grpc_metadata_credentials_plugin plugin;
223
223
 
224
+ grpc_ruby_once_init();
225
+
224
226
  TypedData_Get_Struct(self, grpc_rb_call_credentials,
225
227
  &grpc_rb_call_credentials_data_type, wrapper);
226
228
 
@@ -281,8 +283,6 @@ void Init_grpc_call_credentials() {
281
283
  grpc_rb_call_credentials_compose, -1);
282
284
 
283
285
  id_callback = rb_intern("__callback");
284
-
285
- grpc_rb_event_queue_thread_start();
286
286
  }
287
287
 
288
288
  /* Gets the wrapped grpc_call_credentials from the ruby wrapper */
@@ -32,26 +32,24 @@
32
32
  */
33
33
 
34
34
  #include <ruby/ruby.h>
35
+ #include <ruby/thread.h>
35
36
 
36
- #include "rb_grpc_imports.generated.h"
37
- #include "rb_channel.h"
38
37
  #include "rb_byte_buffer.h"
38
+ #include "rb_channel.h"
39
+ #include "rb_grpc_imports.generated.h"
39
40
 
40
41
  #include <grpc/grpc.h>
41
42
  #include <grpc/grpc_security.h>
42
43
  #include <grpc/support/alloc.h>
43
44
  #include <grpc/support/log.h>
44
45
  #include <grpc/support/time.h>
45
- #include "rb_grpc.h"
46
46
  #include "rb_call.h"
47
47
  #include "rb_channel_args.h"
48
48
  #include "rb_channel_credentials.h"
49
49
  #include "rb_completion_queue.h"
50
+ #include "rb_grpc.h"
50
51
  #include "rb_server.h"
51
52
 
52
- // TODO: During v1.2.x upmerge to master, no changes from this file should go
53
- // in to master. This is reverted for 1.2.x only.
54
-
55
53
  /* id_channel is the name of the hidden ivar that preserves a reference to the
56
54
  * channel on a call, so that calls are not GCed before their channel. */
57
55
  static ID id_channel;
@@ -70,15 +68,96 @@ static VALUE grpc_rb_cChannel = Qnil;
70
68
  /* Used during the conversion of a hash to channel args during channel setup */
71
69
  static VALUE grpc_rb_cChannelArgs;
72
70
 
71
+ typedef struct bg_watched_channel {
72
+ grpc_channel *channel;
73
+ // these fields must only be accessed under global_connection_polling_mu
74
+ struct bg_watched_channel *next;
75
+ int channel_destroyed;
76
+ int refcount;
77
+ } bg_watched_channel;
78
+
73
79
  /* grpc_rb_channel wraps a grpc_channel. */
74
80
  typedef struct grpc_rb_channel {
75
81
  VALUE credentials;
76
82
 
77
- /* The actual channel */
78
- grpc_channel *wrapped;
79
- grpc_completion_queue *queue;
83
+ /* The actual channel (protected in a wrapper to tell when it's safe to
84
+ * destroy) */
85
+ bg_watched_channel *bg_wrapped;
80
86
  } grpc_rb_channel;
81
87
 
88
+ typedef enum { CONTINUOUS_WATCH, WATCH_STATE_API } watch_state_op_type;
89
+
90
+ typedef struct watch_state_op {
91
+ watch_state_op_type op_type;
92
+ // from event.success
93
+ union {
94
+ struct {
95
+ int success;
96
+ // has been called back due to a cq next call
97
+ int called_back;
98
+ } api_callback_args;
99
+ struct {
100
+ bg_watched_channel *bg;
101
+ } continuous_watch_callback_args;
102
+ } op;
103
+ } watch_state_op;
104
+
105
+ static bg_watched_channel *bg_watched_channel_list_head = NULL;
106
+
107
+ static void grpc_rb_channel_try_register_connection_polling(
108
+ bg_watched_channel *bg);
109
+ static void *wait_until_channel_polling_thread_started_no_gil(void *);
110
+ static void wait_until_channel_polling_thread_started_unblocking_func(void *);
111
+ static void *channel_init_try_register_connection_polling_without_gil(
112
+ void *arg);
113
+
114
+ typedef struct channel_init_try_register_stack {
115
+ grpc_channel *channel;
116
+ grpc_rb_channel *wrapper;
117
+ } channel_init_try_register_stack;
118
+
119
+ static grpc_completion_queue *channel_polling_cq;
120
+ static gpr_mu global_connection_polling_mu;
121
+ static gpr_cv global_connection_polling_cv;
122
+ static int abort_channel_polling = 0;
123
+ static int channel_polling_thread_started = 0;
124
+
125
+ static int bg_watched_channel_list_lookup(bg_watched_channel *bg);
126
+ static bg_watched_channel *bg_watched_channel_list_create_and_add(
127
+ grpc_channel *channel);
128
+ static void bg_watched_channel_list_free_and_remove(bg_watched_channel *bg);
129
+ static void run_poll_channels_loop_unblocking_func(void *arg);
130
+
131
+ // Needs to be called under global_connection_polling_mu
132
+ static void grpc_rb_channel_watch_connection_state_op_complete(
133
+ watch_state_op *op, int success) {
134
+ GPR_ASSERT(!op->op.api_callback_args.called_back);
135
+ op->op.api_callback_args.called_back = 1;
136
+ op->op.api_callback_args.success = success;
137
+ // wake up the watch API call thats waiting on this op
138
+ gpr_cv_broadcast(&global_connection_polling_cv);
139
+ }
140
+
141
+ /* Avoids destroying a channel twice. */
142
+ static void grpc_rb_channel_safe_destroy(bg_watched_channel *bg) {
143
+ gpr_mu_lock(&global_connection_polling_mu);
144
+ GPR_ASSERT(bg_watched_channel_list_lookup(bg));
145
+ if (!bg->channel_destroyed) {
146
+ grpc_channel_destroy(bg->channel);
147
+ bg->channel_destroyed = 1;
148
+ }
149
+ bg->refcount--;
150
+ if (bg->refcount == 0) {
151
+ bg_watched_channel_list_free_and_remove(bg);
152
+ }
153
+ gpr_mu_unlock(&global_connection_polling_mu);
154
+ }
155
+
156
+ static void *channel_safe_destroy_without_gil(void *arg) {
157
+ grpc_rb_channel_safe_destroy((bg_watched_channel *)arg);
158
+ return NULL;
159
+ }
160
+
82
161
  /* Destroys Channel instances. */
83
162
  static void grpc_rb_channel_free(void *p) {
84
163
  grpc_rb_channel *ch = NULL;
@@ -87,9 +166,13 @@ static void grpc_rb_channel_free(void *p) {
87
166
  };
88
167
  ch = (grpc_rb_channel *)p;
89
168
 
90
- if (ch->wrapped != NULL) {
91
- grpc_channel_destroy(ch->wrapped);
92
- grpc_rb_completion_queue_destroy(ch->queue);
169
+ if (ch->bg_wrapped != NULL) {
170
+ /* assumption made here: it's ok to directly gpr_mu_lock the global
171
+ * connection polling mutex becuse we're in a finalizer,
172
+ * and we can count on this thread to not be interrupted or
173
+ * yield the gil. */
174
+ grpc_rb_channel_safe_destroy(ch->bg_wrapped);
175
+ ch->bg_wrapped = NULL;
93
176
  }
94
177
 
95
178
  xfree(p);
@@ -107,20 +190,22 @@ static void grpc_rb_channel_mark(void *p) {
107
190
  }
108
191
  }
109
192
 
110
- static rb_data_type_t grpc_channel_data_type = {
111
- "grpc_channel",
112
- {grpc_rb_channel_mark, grpc_rb_channel_free, GRPC_RB_MEMSIZE_UNAVAILABLE,
113
- {NULL, NULL}},
114
- NULL, NULL,
193
+ static rb_data_type_t grpc_channel_data_type = {"grpc_channel",
194
+ {grpc_rb_channel_mark,
195
+ grpc_rb_channel_free,
196
+ GRPC_RB_MEMSIZE_UNAVAILABLE,
197
+ {NULL, NULL}},
198
+ NULL,
199
+ NULL,
115
200
  #ifdef RUBY_TYPED_FREE_IMMEDIATELY
116
- RUBY_TYPED_FREE_IMMEDIATELY
201
+ RUBY_TYPED_FREE_IMMEDIATELY
117
202
  #endif
118
203
  };
119
204
 
120
205
  /* Allocates grpc_rb_channel instances. */
121
206
  static VALUE grpc_rb_channel_alloc(VALUE cls) {
122
207
  grpc_rb_channel *wrapper = ALLOC(grpc_rb_channel);
123
- wrapper->wrapped = NULL;
208
+ wrapper->bg_wrapped = NULL;
124
209
  wrapper->credentials = Qnil;
125
210
  return TypedData_Wrap_Struct(cls, &grpc_channel_data_type, wrapper);
126
211
  }
@@ -142,8 +227,17 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
142
227
  grpc_channel_credentials *creds = NULL;
143
228
  char *target_chars = NULL;
144
229
  grpc_channel_args args;
230
+ channel_init_try_register_stack stack;
231
+ int stop_waiting_for_thread_start = 0;
145
232
  MEMZERO(&args, grpc_channel_args, 1);
146
233
 
234
+ grpc_ruby_once_init();
235
+ rb_thread_call_without_gvl(
236
+ wait_until_channel_polling_thread_started_no_gil,
237
+ &stop_waiting_for_thread_start,
238
+ wait_until_channel_polling_thread_started_unblocking_func,
239
+ &stop_waiting_for_thread_start);
240
+
147
241
  /* "3" == 3 mandatory args */
148
242
  rb_scan_args(argc, argv, "3", &target, &channel_args, &credentials);
149
243
 
@@ -162,6 +256,14 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
162
256
  creds = grpc_rb_get_wrapped_channel_credentials(credentials);
163
257
  ch = grpc_secure_channel_create(creds, target_chars, &args, NULL);
164
258
  }
259
+
260
+ GPR_ASSERT(ch);
261
+ stack.channel = ch;
262
+ stack.wrapper = wrapper;
263
+ rb_thread_call_without_gvl(
264
+ channel_init_try_register_connection_polling_without_gil, &stack, NULL,
265
+ NULL);
266
+
165
267
  if (args.args != NULL) {
166
268
  xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */
167
269
  }
@@ -171,98 +273,167 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
171
273
  return Qnil;
172
274
  }
173
275
  rb_ivar_set(self, id_target, target);
174
- wrapper->wrapped = ch;
175
- wrapper->queue = grpc_completion_queue_create(NULL);
176
276
  return self;
177
277
  }
178
278
 
279
+ typedef struct get_state_stack {
280
+ bg_watched_channel *bg;
281
+ int try_to_connect;
282
+ int out;
283
+ } get_state_stack;
284
+
285
+ static void *get_state_without_gil(void *arg) {
286
+ get_state_stack *stack = (get_state_stack *)arg;
287
+
288
+ gpr_mu_lock(&global_connection_polling_mu);
289
+ GPR_ASSERT(abort_channel_polling || channel_polling_thread_started);
290
+ if (stack->bg->channel_destroyed) {
291
+ stack->out = GRPC_CHANNEL_SHUTDOWN;
292
+ } else {
293
+ stack->out = grpc_channel_check_connectivity_state(stack->bg->channel,
294
+ stack->try_to_connect);
295
+ }
296
+ gpr_mu_unlock(&global_connection_polling_mu);
297
+
298
+ return NULL;
299
+ }
300
+
179
301
  /*
180
302
  call-seq:
181
- insecure_channel = Channel:new("myhost:8080", {'arg1': 'value1'})
182
- creds = ...
183
- secure_channel = Channel:new("myhost:443", {'arg1': 'value1'}, creds)
303
+ ch.connectivity_state -> state
304
+ ch.connectivity_state(true) -> state
184
305
 
185
- Creates channel instances. */
306
+ Indicates the current state of the channel, whose value is one of the
307
+ constants defined in GRPC::Core::ConnectivityStates.
308
+
309
+ It also tries to connect if the chennel is idle in the second form. */
186
310
  static VALUE grpc_rb_channel_get_connectivity_state(int argc, VALUE *argv,
187
311
  VALUE self) {
188
- VALUE try_to_connect = Qfalse;
312
+ VALUE try_to_connect_param = Qfalse;
189
313
  grpc_rb_channel *wrapper = NULL;
190
- grpc_channel *ch = NULL;
314
+ get_state_stack stack;
191
315
 
192
316
  /* "01" == 0 mandatory args, 1 (try_to_connect) is optional */
193
- rb_scan_args(argc, argv, "01", try_to_connect);
317
+ rb_scan_args(argc, argv, "01", &try_to_connect_param);
194
318
 
195
319
  TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
196
- ch = wrapper->wrapped;
197
- if (ch == NULL) {
320
+ if (wrapper->bg_wrapped == NULL) {
198
321
  rb_raise(rb_eRuntimeError, "closed!");
199
322
  return Qnil;
200
323
  }
201
- return NUM2LONG(
202
- grpc_channel_check_connectivity_state(ch, (int)try_to_connect));
324
+
325
+ stack.bg = wrapper->bg_wrapped;
326
+ stack.try_to_connect = RTEST(try_to_connect_param) ? 1 : 0;
327
+ rb_thread_call_without_gvl(get_state_without_gil, &stack, NULL, NULL);
328
+
329
+ return LONG2NUM(stack.out);
203
330
  }
204
331
 
205
- /* Watch for a change in connectivity state.
332
+ typedef struct watch_state_stack {
333
+ grpc_channel *channel;
334
+ gpr_timespec deadline;
335
+ int last_state;
336
+ } watch_state_stack;
337
+
338
+ static void *wait_for_watch_state_op_complete_without_gvl(void *arg) {
339
+ watch_state_stack *stack = (watch_state_stack *)arg;
340
+ watch_state_op *op = NULL;
341
+ void *success = (void *)0;
342
+
343
+ gpr_mu_lock(&global_connection_polling_mu);
344
+ // its unsafe to do a "watch" after "channel polling abort" because the cq has
345
+ // been shut down.
346
+ if (abort_channel_polling) {
347
+ gpr_mu_unlock(&global_connection_polling_mu);
348
+ return (void *)0;
349
+ }
350
+ op = gpr_zalloc(sizeof(watch_state_op));
351
+ op->op_type = WATCH_STATE_API;
352
+ grpc_channel_watch_connectivity_state(stack->channel, stack->last_state,
353
+ stack->deadline, channel_polling_cq,
354
+ op);
355
+
356
+ while (!op->op.api_callback_args.called_back) {
357
+ gpr_cv_wait(&global_connection_polling_cv, &global_connection_polling_mu,
358
+ gpr_inf_future(GPR_CLOCK_REALTIME));
359
+ }
360
+ if (op->op.api_callback_args.success) {
361
+ success = (void *)1;
362
+ }
363
+ gpr_free(op);
364
+ gpr_mu_unlock(&global_connection_polling_mu);
206
365
 
207
- Once the channel connectivity state is different from the last observed
208
- state, tag will be enqueued on cq with success=1
366
+ return success;
367
+ }
209
368
 
210
- If deadline expires BEFORE the state is changed, tag will be enqueued on
211
- the completion queue with success=0 */
369
+ static void wait_for_watch_state_op_complete_unblocking_func(void *arg) {
370
+ bg_watched_channel *bg = (bg_watched_channel *)arg;
371
+ gpr_mu_lock(&global_connection_polling_mu);
372
+ if (!bg->channel_destroyed) {
373
+ grpc_channel_destroy(bg->channel);
374
+ bg->channel_destroyed = 1;
375
+ }
376
+ gpr_mu_unlock(&global_connection_polling_mu);
377
+ }
378
+
379
+ /* Wait until the channel's connectivity state becomes different from
380
+ * "last_state", or "deadline" expires.
381
+ * Returns true if the the channel's connectivity state becomes
382
+ * different from "last_state" within "deadline".
383
+ * Returns false if "deadline" expires before the channel's connectivity
384
+ * state changes from "last_state".
385
+ * */
212
386
  static VALUE grpc_rb_channel_watch_connectivity_state(VALUE self,
213
387
  VALUE last_state,
214
388
  VALUE deadline) {
215
389
  grpc_rb_channel *wrapper = NULL;
216
- grpc_channel *ch = NULL;
217
- grpc_completion_queue *cq = NULL;
218
-
219
- void *tag = wrapper;
220
-
221
- grpc_event event;
390
+ watch_state_stack stack;
391
+ void *op_success = 0;
222
392
 
223
393
  TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
224
- ch = wrapper->wrapped;
225
- cq = wrapper->queue;
226
- if (ch == NULL) {
394
+
395
+ if (wrapper->bg_wrapped == NULL) {
227
396
  rb_raise(rb_eRuntimeError, "closed!");
228
397
  return Qnil;
229
398
  }
230
- grpc_channel_watch_connectivity_state(
231
- ch,
232
- (grpc_connectivity_state)NUM2LONG(last_state),
233
- grpc_rb_time_timeval(deadline, /* absolute time */ 0),
234
- cq,
235
- tag);
236
399
 
237
- event = rb_completion_queue_pluck(cq, tag,
238
- gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
239
-
240
- if (event.success) {
241
- return Qtrue;
242
- } else {
243
- return Qfalse;
400
+ if (!FIXNUM_P(last_state)) {
401
+ rb_raise(
402
+ rb_eTypeError,
403
+ "bad type for last_state. want a GRPC::Core::ChannelState constant");
404
+ return Qnil;
244
405
  }
406
+
407
+ stack.channel = wrapper->bg_wrapped->channel;
408
+ stack.deadline = grpc_rb_time_timeval(deadline, 0),
409
+ stack.last_state = NUM2LONG(last_state);
410
+
411
+ op_success = rb_thread_call_without_gvl(
412
+ wait_for_watch_state_op_complete_without_gvl, &stack,
413
+ wait_for_watch_state_op_complete_unblocking_func, wrapper->bg_wrapped);
414
+
415
+ return op_success ? Qtrue : Qfalse;
245
416
  }
246
417
 
247
418
  /* Create a call given a grpc_channel, in order to call method. The request
248
419
  is not sent until grpc_call_invoke is called. */
249
- static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent,
250
- VALUE mask, VALUE method,
251
- VALUE host, VALUE deadline) {
420
+ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent, VALUE mask,
421
+ VALUE method, VALUE host,
422
+ VALUE deadline) {
252
423
  VALUE res = Qnil;
253
424
  grpc_rb_channel *wrapper = NULL;
254
425
  grpc_call *call = NULL;
255
426
  grpc_call *parent_call = NULL;
256
- grpc_channel *ch = NULL;
257
427
  grpc_completion_queue *cq = NULL;
258
428
  int flags = GRPC_PROPAGATE_DEFAULTS;
259
429
  grpc_slice method_slice;
260
430
  grpc_slice host_slice;
261
431
  grpc_slice *host_slice_ptr = NULL;
262
- char* tmp_str = NULL;
432
+ char *tmp_str = NULL;
263
433
 
264
434
  if (host != Qnil) {
265
- host_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(host), RSTRING_LEN(host));
435
+ host_slice =
436
+ grpc_slice_from_copied_buffer(RSTRING_PTR(host), RSTRING_LEN(host));
266
437
  host_slice_ptr = &host_slice;
267
438
  }
268
439
  if (mask != Qnil) {
@@ -274,23 +445,23 @@ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent,
274
445
 
275
446
  cq = grpc_completion_queue_create(NULL);
276
447
  TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
277
- ch = wrapper->wrapped;
278
- if (ch == NULL) {
448
+ if (wrapper->bg_wrapped == NULL) {
279
449
  rb_raise(rb_eRuntimeError, "closed!");
280
450
  return Qnil;
281
451
  }
282
452
 
283
- method_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(method), RSTRING_LEN(method));
453
+ method_slice =
454
+ grpc_slice_from_copied_buffer(RSTRING_PTR(method), RSTRING_LEN(method));
284
455
 
285
- call = grpc_channel_create_call(ch, parent_call, flags, cq, method_slice,
286
- host_slice_ptr, grpc_rb_time_timeval(
287
- deadline,
288
- /* absolute time */ 0), NULL);
456
+ call = grpc_channel_create_call(wrapper->bg_wrapped->channel, parent_call,
457
+ flags, cq, method_slice, host_slice_ptr,
458
+ grpc_rb_time_timeval(deadline,
459
+ /* absolute time */ 0),
460
+ NULL);
289
461
 
290
462
  if (call == NULL) {
291
463
  tmp_str = grpc_slice_to_c_string(method_slice);
292
- rb_raise(rb_eRuntimeError, "cannot create call with method %s",
293
- tmp_str);
464
+ rb_raise(rb_eRuntimeError, "cannot create call with method %s", tmp_str);
294
465
  return Qnil;
295
466
  }
296
467
 
@@ -307,41 +478,298 @@ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent,
307
478
  return res;
308
479
  }
309
480
 
310
-
311
481
  /* Closes the channel, calling it's destroy method */
482
+ /* Note this is an API-level call; a wrapped channel's finalizer doesn't call
483
+ * this */
312
484
  static VALUE grpc_rb_channel_destroy(VALUE self) {
313
485
  grpc_rb_channel *wrapper = NULL;
314
- grpc_channel *ch = NULL;
315
486
 
316
487
  TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
317
- ch = wrapper->wrapped;
318
- if (ch != NULL) {
319
- grpc_channel_destroy(ch);
320
- wrapper->wrapped = NULL;
488
+ if (wrapper->bg_wrapped != NULL) {
489
+ rb_thread_call_without_gvl(channel_safe_destroy_without_gil,
490
+ wrapper->bg_wrapped, NULL, NULL);
491
+ wrapper->bg_wrapped = NULL;
321
492
  }
322
493
 
323
494
  return Qnil;
324
495
  }
325
496
 
326
-
327
497
  /* Called to obtain the target that this channel accesses. */
328
498
  static VALUE grpc_rb_channel_get_target(VALUE self) {
329
499
  grpc_rb_channel *wrapper = NULL;
330
500
  VALUE res = Qnil;
331
- char* target = NULL;
501
+ char *target = NULL;
332
502
 
333
503
  TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
334
- target = grpc_channel_get_target(wrapper->wrapped);
504
+ target = grpc_channel_get_target(wrapper->bg_wrapped->channel);
335
505
  res = rb_str_new2(target);
336
506
  gpr_free(target);
337
507
 
338
508
  return res;
339
509
  }
340
510
 
511
+ /* Needs to be called under global_connection_polling_mu */
512
+ static int bg_watched_channel_list_lookup(bg_watched_channel *target) {
513
+ bg_watched_channel *cur = bg_watched_channel_list_head;
514
+
515
+ while (cur != NULL) {
516
+ if (cur == target) {
517
+ return 1;
518
+ }
519
+ cur = cur->next;
520
+ }
521
+
522
+ return 0;
523
+ }
524
+
525
+ /* Needs to be called under global_connection_polling_mu */
526
+ static bg_watched_channel *bg_watched_channel_list_create_and_add(
527
+ grpc_channel *channel) {
528
+ bg_watched_channel *watched = gpr_zalloc(sizeof(bg_watched_channel));
529
+
530
+ watched->channel = channel;
531
+ watched->next = bg_watched_channel_list_head;
532
+ watched->refcount = 1;
533
+ bg_watched_channel_list_head = watched;
534
+ return watched;
535
+ }
536
+
537
+ /* Needs to be called under global_connection_polling_mu */
538
+ static void bg_watched_channel_list_free_and_remove(
539
+ bg_watched_channel *target) {
540
+ bg_watched_channel *bg = NULL;
541
+
542
+ GPR_ASSERT(bg_watched_channel_list_lookup(target));
543
+ GPR_ASSERT(target->channel_destroyed && target->refcount == 0);
544
+ if (bg_watched_channel_list_head == target) {
545
+ bg_watched_channel_list_head = target->next;
546
+ gpr_free(target);
547
+ return;
548
+ }
549
+ bg = bg_watched_channel_list_head;
550
+ while (bg != NULL && bg->next != NULL) {
551
+ if (bg->next == target) {
552
+ bg->next = bg->next->next;
553
+ gpr_free(target);
554
+ return;
555
+ }
556
+ bg = bg->next;
557
+ }
558
+ GPR_ASSERT(0);
559
+ }
560
+
561
+ /* Initialize a grpc_rb_channel's "protected grpc_channel" and try to push
562
+ * it onto the background thread for constant watches. */
563
+ static void *channel_init_try_register_connection_polling_without_gil(
564
+ void *arg) {
565
+ channel_init_try_register_stack *stack =
566
+ (channel_init_try_register_stack *)arg;
567
+
568
+ gpr_mu_lock(&global_connection_polling_mu);
569
+ stack->wrapper->bg_wrapped =
570
+ bg_watched_channel_list_create_and_add(stack->channel);
571
+ grpc_rb_channel_try_register_connection_polling(stack->wrapper->bg_wrapped);
572
+ gpr_mu_unlock(&global_connection_polling_mu);
573
+ return NULL;
574
+ }
575
+
576
+ // Needs to be called under global_connection_poolling_mu
577
+ static void grpc_rb_channel_try_register_connection_polling(
578
+ bg_watched_channel *bg) {
579
+ grpc_connectivity_state conn_state;
580
+ watch_state_op *op = NULL;
581
+
582
+ GPR_ASSERT(channel_polling_thread_started || abort_channel_polling);
583
+
584
+ if (bg->refcount == 0) {
585
+ GPR_ASSERT(bg->channel_destroyed);
586
+ bg_watched_channel_list_free_and_remove(bg);
587
+ return;
588
+ }
589
+ GPR_ASSERT(bg->refcount == 1);
590
+ if (bg->channel_destroyed || abort_channel_polling) {
591
+ return;
592
+ }
593
+
594
+ conn_state = grpc_channel_check_connectivity_state(bg->channel, 0);
595
+ if (conn_state == GRPC_CHANNEL_SHUTDOWN) {
596
+ return;
597
+ }
598
+ GPR_ASSERT(bg_watched_channel_list_lookup(bg));
599
+ // prevent bg from being free'd by GC while background thread is watching it
600
+ bg->refcount++;
601
+
602
+ op = gpr_zalloc(sizeof(watch_state_op));
603
+ op->op_type = CONTINUOUS_WATCH;
604
+ op->op.continuous_watch_callback_args.bg = bg;
605
+ grpc_channel_watch_connectivity_state(bg->channel, conn_state,
606
+ gpr_inf_future(GPR_CLOCK_REALTIME),
607
+ channel_polling_cq, op);
608
+ }
609
+
610
+ // Note this loop breaks out with a single call of
611
+ // "run_poll_channels_loop_no_gil".
612
+ // This assumes that a ruby call the unblocking func
613
+ // indicates process shutdown.
614
+ // In the worst case, this stops polling channel connectivity
615
+ // early and falls back to current behavior.
616
+ static void *run_poll_channels_loop_no_gil(void *arg) {
617
+ grpc_event event;
618
+ watch_state_op *op = NULL;
619
+ bg_watched_channel *bg = NULL;
620
+ (void)arg;
621
+ gpr_log(GPR_DEBUG, "GRPC_RUBY: run_poll_channels_loop_no_gil - begin");
622
+
623
+ gpr_mu_lock(&global_connection_polling_mu);
624
+ GPR_ASSERT(!channel_polling_thread_started);
625
+ channel_polling_thread_started = 1;
626
+ gpr_cv_broadcast(&global_connection_polling_cv);
627
+ gpr_mu_unlock(&global_connection_polling_mu);
628
+
629
+ for (;;) {
630
+ event = grpc_completion_queue_next(
631
+ channel_polling_cq, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
632
+ if (event.type == GRPC_QUEUE_SHUTDOWN) {
633
+ break;
634
+ }
635
+ gpr_mu_lock(&global_connection_polling_mu);
636
+ if (event.type == GRPC_OP_COMPLETE) {
637
+ op = (watch_state_op *)event.tag;
638
+ if (op->op_type == CONTINUOUS_WATCH) {
639
+ bg = (bg_watched_channel *)op->op.continuous_watch_callback_args.bg;
640
+ bg->refcount--;
641
+ grpc_rb_channel_try_register_connection_polling(bg);
642
+ gpr_free(op);
643
+ } else if (op->op_type == WATCH_STATE_API) {
644
+ grpc_rb_channel_watch_connection_state_op_complete(
645
+ (watch_state_op *)event.tag, event.success);
646
+ } else {
647
+ GPR_ASSERT(0);
648
+ }
649
+ }
650
+ gpr_mu_unlock(&global_connection_polling_mu);
651
+ }
652
+ grpc_completion_queue_destroy(channel_polling_cq);
653
+ gpr_log(GPR_DEBUG,
654
+ "GRPC_RUBY: run_poll_channels_loop_no_gil - exit connection polling "
655
+ "loop");
656
+ return NULL;
657
+ }
658
+
659
+ // Notify the channel polling loop to cleanup and shutdown.
660
+ static void run_poll_channels_loop_unblocking_func(void *arg) {
661
+ bg_watched_channel *bg = NULL;
662
+ (void)arg;
663
+
664
+ gpr_mu_lock(&global_connection_polling_mu);
665
+ gpr_log(GPR_DEBUG,
666
+ "GRPC_RUBY: run_poll_channels_loop_unblocking_func - begin aborting "
667
+ "connection polling");
668
+ // early out after first time through
669
+ if (abort_channel_polling) {
670
+ gpr_mu_unlock(&global_connection_polling_mu);
671
+ return;
672
+ }
673
+ abort_channel_polling = 1;
674
+
675
+ // force pending watches to end by switching to shutdown state
676
+ bg = bg_watched_channel_list_head;
677
+ while (bg != NULL) {
678
+ if (!bg->channel_destroyed) {
679
+ grpc_channel_destroy(bg->channel);
680
+ bg->channel_destroyed = 1;
681
+ }
682
+ bg = bg->next;
683
+ }
684
+
685
+ grpc_completion_queue_shutdown(channel_polling_cq);
686
+ gpr_cv_broadcast(&global_connection_polling_cv);
687
+ gpr_mu_unlock(&global_connection_polling_mu);
688
+ gpr_log(GPR_DEBUG,
689
+ "GRPC_RUBY: run_poll_channels_loop_unblocking_func - end aborting "
690
+ "connection polling");
691
+ }
692
+
693
+ // Poll channel connectivity states in background thread without the GIL.
694
+ static VALUE run_poll_channels_loop(VALUE arg) {
695
+ (void)arg;
696
+ gpr_log(
697
+ GPR_DEBUG,
698
+ "GRPC_RUBY: run_poll_channels_loop - create connection polling thread");
699
+ rb_thread_call_without_gvl(run_poll_channels_loop_no_gil, NULL,
700
+ run_poll_channels_loop_unblocking_func, NULL);
701
+
702
+ return Qnil;
703
+ }
704
+
705
+ static void *wait_until_channel_polling_thread_started_no_gil(void *arg) {
706
+ int *stop_waiting = (int *)arg;
707
+ gpr_log(GPR_DEBUG, "GRPC_RUBY: wait for channel polling thread to start");
708
+ gpr_mu_lock(&global_connection_polling_mu);
709
+ while (!channel_polling_thread_started && !abort_channel_polling &&
710
+ !*stop_waiting) {
711
+ gpr_cv_wait(&global_connection_polling_cv, &global_connection_polling_mu,
712
+ gpr_inf_future(GPR_CLOCK_REALTIME));
713
+ }
714
+ gpr_mu_unlock(&global_connection_polling_mu);
715
+
716
+ return NULL;
717
+ }
718
+
719
+ static void wait_until_channel_polling_thread_started_unblocking_func(
720
+ void *arg) {
721
+ int *stop_waiting = (int *)arg;
722
+ gpr_mu_lock(&global_connection_polling_mu);
723
+ gpr_log(GPR_DEBUG,
724
+ "GRPC_RUBY: interrupt wait for channel polling thread to start");
725
+ *stop_waiting = 1;
726
+ gpr_cv_broadcast(&global_connection_polling_cv);
727
+ gpr_mu_unlock(&global_connection_polling_mu);
728
+ }
729
+
730
+ static void *set_abort_channel_polling_without_gil(void *arg) {
731
+ (void)arg;
732
+ gpr_mu_lock(&global_connection_polling_mu);
733
+ abort_channel_polling = 1;
734
+ gpr_cv_broadcast(&global_connection_polling_cv);
735
+ gpr_mu_unlock(&global_connection_polling_mu);
736
+ return NULL;
737
+ }
738
+
739
+ /* Temporary fix for
740
+ * https://github.com/GoogleCloudPlatform/google-cloud-ruby/issues/899.
741
+ * Transports in idle channels can get destroyed. Normally c-core re-connects,
742
+ * but in grpc-ruby core never gets a thread until an RPC is made, because ruby
743
+ * only calls c-core's "completion_queu_pluck" API.
744
+ * This uses a global background thread that calls
745
+ * "completion_queue_next" on registered "watch_channel_connectivity_state"
746
+ * calls - so that c-core can reconnect if needed, when there aren't any RPC's.
747
+ * TODO(apolcyn) remove this when core handles new RPCs on dead connections.
748
+ */
749
+ void grpc_rb_channel_polling_thread_start() {
750
+ VALUE background_thread = Qnil;
751
+
752
+ GPR_ASSERT(!abort_channel_polling);
753
+ GPR_ASSERT(!channel_polling_thread_started);
754
+ GPR_ASSERT(channel_polling_cq == NULL);
755
+
756
+ gpr_mu_init(&global_connection_polling_mu);
757
+ gpr_cv_init(&global_connection_polling_cv);
758
+
759
+ channel_polling_cq = grpc_completion_queue_create(NULL);
760
+ background_thread = rb_thread_create(run_poll_channels_loop, NULL);
761
+
762
+ if (!RTEST(background_thread)) {
763
+ gpr_log(GPR_DEBUG, "GRPC_RUBY: failed to spawn channel polling thread");
764
+ rb_thread_call_without_gvl(set_abort_channel_polling_without_gil, NULL,
765
+ NULL, NULL);
766
+ }
767
+ }
768
+
341
769
  static void Init_grpc_propagate_masks() {
342
770
  /* Constants representing call propagation masks in grpc.h */
343
- VALUE grpc_rb_mPropagateMasks = rb_define_module_under(
344
- grpc_rb_mGrpcCore, "PropagateMasks");
771
+ VALUE grpc_rb_mPropagateMasks =
772
+ rb_define_module_under(grpc_rb_mGrpcCore, "PropagateMasks");
345
773
  rb_define_const(grpc_rb_mPropagateMasks, "DEADLINE",
346
774
  UINT2NUM(GRPC_PROPAGATE_DEADLINE));
347
775
  rb_define_const(grpc_rb_mPropagateMasks, "CENSUS_STATS_CONTEXT",
@@ -356,8 +784,8 @@ static void Init_grpc_propagate_masks() {
356
784
 
357
785
  static void Init_grpc_connectivity_states() {
358
786
  /* Constants representing call propagation masks in grpc.h */
359
- VALUE grpc_rb_mConnectivityStates = rb_define_module_under(
360
- grpc_rb_mGrpcCore, "ConnectivityStates");
787
+ VALUE grpc_rb_mConnectivityStates =
788
+ rb_define_module_under(grpc_rb_mGrpcCore, "ConnectivityStates");
361
789
  rb_define_const(grpc_rb_mConnectivityStates, "IDLE",
362
790
  LONG2NUM(GRPC_CHANNEL_IDLE));
363
791
  rb_define_const(grpc_rb_mConnectivityStates, "CONNECTING",
@@ -385,12 +813,11 @@ void Init_grpc_channel() {
385
813
 
386
814
  /* Add ruby analogues of the Channel methods. */
387
815
  rb_define_method(grpc_rb_cChannel, "connectivity_state",
388
- grpc_rb_channel_get_connectivity_state,
389
- -1);
816
+ grpc_rb_channel_get_connectivity_state, -1);
390
817
  rb_define_method(grpc_rb_cChannel, "watch_connectivity_state",
391
- grpc_rb_channel_watch_connectivity_state, 4);
392
- rb_define_method(grpc_rb_cChannel, "create_call",
393
- grpc_rb_channel_create_call, 5);
818
+ grpc_rb_channel_watch_connectivity_state, 2);
819
+ rb_define_method(grpc_rb_cChannel, "create_call", grpc_rb_channel_create_call,
820
+ 5);
394
821
  rb_define_method(grpc_rb_cChannel, "target", grpc_rb_channel_get_target, 0);
395
822
  rb_define_method(grpc_rb_cChannel, "destroy", grpc_rb_channel_destroy, 0);
396
823
  rb_define_alias(grpc_rb_cChannel, "close", "destroy");
@@ -414,5 +841,5 @@ void Init_grpc_channel() {
414
841
  grpc_channel *grpc_rb_get_wrapped_channel(VALUE v) {
415
842
  grpc_rb_channel *wrapper = NULL;
416
843
  TypedData_Get_Struct(v, grpc_rb_channel, &grpc_channel_data_type, wrapper);
417
- return wrapper->wrapped;
844
+ return wrapper->bg_wrapped->channel;
418
845
  }