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,16 +31,28 @@
31
31
  *
32
32
  */
33
33
 
34
- #ifndef GRPC_CORE_LIB_SECURITY_UTIL_B64_H
35
- #define GRPC_CORE_LIB_SECURITY_UTIL_B64_H
34
+ #ifndef GRPC_CORE_LIB_SLICE_B64_H
35
+ #define GRPC_CORE_LIB_SLICE_B64_H
36
36
 
37
37
  #include <grpc/slice.h>
38
38
 
39
39
  /* Encodes data using base64. It is the caller's responsability to free
40
- the returned char * using gpr_free. Returns NULL on NULL input. */
40
+ the returned char * using gpr_free. Returns NULL on NULL input.
41
+ TODO(makdharma) : change the flags to bool from int */
41
42
  char *grpc_base64_encode(const void *data, size_t data_size, int url_safe,
42
43
  int multiline);
43
44
 
45
+ /* estimate the upper bound on size of base64 encoded data. The actual size
46
+ * is guaranteed to be less than or equal to the size returned here. */
47
+ size_t grpc_base64_estimate_encoded_size(size_t data_size, int url_safe,
48
+ int multiline);
49
+
50
+ /* Encodes data using base64 and write it to memory pointed to by result. It is
51
+ * the caller's responsiblity to allocate enough memory in |result| to fit the
52
+ * encoded data. */
53
+ void grpc_base64_encode_core(char *result, const void *vdata, size_t data_size,
54
+ int url_safe, int multiline);
55
+
44
56
  /* Decodes data according to the base64 specification. Returns an empty
45
57
  slice in case of failure. */
46
58
  grpc_slice grpc_base64_decode(grpc_exec_ctx *exec_ctx, const char *b64,
@@ -50,4 +62,4 @@ grpc_slice grpc_base64_decode(grpc_exec_ctx *exec_ctx, const char *b64,
50
62
  grpc_slice grpc_base64_decode_with_len(grpc_exec_ctx *exec_ctx, const char *b64,
51
63
  size_t b64_len, int url_safe);
52
64
 
53
- #endif /* GRPC_CORE_LIB_SECURITY_UTIL_B64_H */
65
+ #endif /* GRPC_CORE_LIB_SLICE_B64_H */
@@ -197,6 +197,7 @@ grpc_slice grpc_slice_new_with_len(void *p, size_t len,
197
197
  }
198
198
 
199
199
  grpc_slice grpc_slice_from_copied_buffer(const char *source, size_t length) {
200
+ if (length == 0) return grpc_empty_slice();
200
201
  grpc_slice slice = grpc_slice_malloc(length);
201
202
  memcpy(GRPC_SLICE_START_PTR(slice), source, length);
202
203
  return slice;
@@ -382,8 +383,9 @@ grpc_slice grpc_slice_split_head(grpc_slice *source, size_t split) {
382
383
  }
383
384
 
384
385
  int grpc_slice_default_eq_impl(grpc_slice a, grpc_slice b) {
385
- return GRPC_SLICE_LENGTH(a) == GRPC_SLICE_LENGTH(b) &&
386
- 0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b),
386
+ if (GRPC_SLICE_LENGTH(a) != GRPC_SLICE_LENGTH(b)) return false;
387
+ if (GRPC_SLICE_LENGTH(a) == 0) return true;
388
+ return 0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b),
387
389
  GRPC_SLICE_LENGTH(a));
388
390
  }
389
391
 
@@ -46,27 +46,29 @@
46
46
  #define GROW(x) (3 * (x) / 2)
47
47
 
48
48
  static void maybe_embiggen(grpc_slice_buffer *sb) {
49
- if (sb->base_slices != sb->slices) {
50
- memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice));
51
- sb->slices = sb->base_slices;
52
- }
53
-
54
49
  /* How far away from sb->base_slices is sb->slices pointer */
55
50
  size_t slice_offset = (size_t)(sb->slices - sb->base_slices);
56
51
  size_t slice_count = sb->count + slice_offset;
57
52
 
58
53
  if (slice_count == sb->capacity) {
59
- sb->capacity = GROW(sb->capacity);
60
- GPR_ASSERT(sb->capacity > slice_count);
61
- if (sb->base_slices == sb->inlined) {
62
- sb->base_slices = gpr_malloc(sb->capacity * sizeof(grpc_slice));
63
- memcpy(sb->base_slices, sb->inlined, slice_count * sizeof(grpc_slice));
54
+ if (sb->base_slices != sb->slices) {
55
+ /* Make room by moving elements if there's still space unused */
56
+ memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice));
57
+ sb->slices = sb->base_slices;
64
58
  } else {
65
- sb->base_slices =
66
- gpr_realloc(sb->base_slices, sb->capacity * sizeof(grpc_slice));
67
- }
59
+ /* Allocate more memory if no more space is available */
60
+ sb->capacity = GROW(sb->capacity);
61
+ GPR_ASSERT(sb->capacity > slice_count);
62
+ if (sb->base_slices == sb->inlined) {
63
+ sb->base_slices = gpr_malloc(sb->capacity * sizeof(grpc_slice));
64
+ memcpy(sb->base_slices, sb->inlined, slice_count * sizeof(grpc_slice));
65
+ } else {
66
+ sb->base_slices =
67
+ gpr_realloc(sb->base_slices, sb->capacity * sizeof(grpc_slice));
68
+ }
68
69
 
69
- sb->slices = sb->base_slices + slice_offset;
70
+ sb->slices = sb->base_slices + slice_offset;
71
+ }
70
72
  }
71
73
  }
72
74
 
@@ -0,0 +1,98 @@
1
+ /*
2
+ *
3
+ * Copyright 2017, Google Inc.
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are
8
+ * met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright
11
+ * notice, this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above
13
+ * copyright notice, this list of conditions and the following disclaimer
14
+ * in the documentation and/or other materials provided with the
15
+ * distribution.
16
+ * * Neither the name of Google Inc. nor the names of its
17
+ * contributors may be used to endorse or promote products derived from
18
+ * this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ */
33
+
34
+ #include "src/core/lib/support/arena.h"
35
+ #include <grpc/support/alloc.h>
36
+ #include <grpc/support/atm.h>
37
+ #include <grpc/support/log.h>
38
+ #include <grpc/support/useful.h>
39
+
40
+ #define ROUND_UP_TO_ALIGNMENT_SIZE(x) \
41
+ (((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u))
42
+
43
+ typedef struct zone {
44
+ size_t size_begin;
45
+ size_t size_end;
46
+ gpr_atm next_atm;
47
+ } zone;
48
+
49
+ struct gpr_arena {
50
+ gpr_atm size_so_far;
51
+ zone initial_zone;
52
+ };
53
+
54
+ gpr_arena *gpr_arena_create(size_t initial_size) {
55
+ initial_size = ROUND_UP_TO_ALIGNMENT_SIZE(initial_size);
56
+ gpr_arena *a = gpr_zalloc(sizeof(gpr_arena) + initial_size);
57
+ a->initial_zone.size_end = initial_size;
58
+ return a;
59
+ }
60
+
61
+ size_t gpr_arena_destroy(gpr_arena *arena) {
62
+ gpr_atm size = gpr_atm_no_barrier_load(&arena->size_so_far);
63
+ zone *z = (zone *)gpr_atm_no_barrier_load(&arena->initial_zone.next_atm);
64
+ gpr_free(arena);
65
+ while (z) {
66
+ zone *next_z = (zone *)gpr_atm_no_barrier_load(&z->next_atm);
67
+ gpr_free(z);
68
+ z = next_z;
69
+ }
70
+ return (size_t)size;
71
+ }
72
+
73
+ void *gpr_arena_alloc(gpr_arena *arena, size_t size) {
74
+ size = ROUND_UP_TO_ALIGNMENT_SIZE(size);
75
+ size_t start =
76
+ (size_t)gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size);
77
+ zone *z = &arena->initial_zone;
78
+ while (start > z->size_end) {
79
+ zone *next_z = (zone *)gpr_atm_acq_load(&z->next_atm);
80
+ if (next_z == NULL) {
81
+ size_t next_z_size = (size_t)gpr_atm_no_barrier_load(&arena->size_so_far);
82
+ next_z = gpr_zalloc(sizeof(zone) + next_z_size);
83
+ next_z->size_begin = z->size_end;
84
+ next_z->size_end = z->size_end + next_z_size;
85
+ if (!gpr_atm_rel_cas(&z->next_atm, (gpr_atm)NULL, (gpr_atm)next_z)) {
86
+ gpr_free(next_z);
87
+ next_z = (zone *)gpr_atm_acq_load(&z->next_atm);
88
+ }
89
+ }
90
+ z = next_z;
91
+ }
92
+ if (start + size > z->size_end) {
93
+ return gpr_arena_alloc(arena, size);
94
+ }
95
+ GPR_ASSERT(start >= z->size_begin);
96
+ GPR_ASSERT(start + size <= z->size_end);
97
+ return ((char *)(z + 1)) + start - z->size_begin;
98
+ }
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  *
3
- * Copyright 2015, Google Inc.
3
+ * Copyright 2017, Google Inc.
4
4
  * All rights reserved.
5
5
  *
6
6
  * Redistribution and use in source and binary forms, with or without
@@ -31,22 +31,24 @@
31
31
  *
32
32
  */
33
33
 
34
- #include "src/core/ext/client_channel/initial_connect_string.h"
34
+ // \file Arena based allocator
35
+ // Allows very fast allocation of memory, but that memory cannot be freed until
36
+ // the arena as a whole is freed
37
+ // Tracks the total memory allocated against it, so that future arenas can
38
+ // pre-allocate the right amount of memory
35
39
 
36
- #include <stddef.h>
40
+ #ifndef GRPC_CORE_LIB_SUPPORT_ARENA_H
41
+ #define GRPC_CORE_LIB_SUPPORT_ARENA_H
37
42
 
38
- extern void grpc_set_default_initial_connect_string(
39
- grpc_resolved_address **addr, grpc_slice *initial_str);
43
+ #include <stddef.h>
40
44
 
41
- static grpc_set_initial_connect_string_func g_set_initial_connect_string_func =
42
- grpc_set_default_initial_connect_string;
45
+ typedef struct gpr_arena gpr_arena;
43
46
 
44
- void grpc_test_set_initial_connect_string_function(
45
- grpc_set_initial_connect_string_func func) {
46
- g_set_initial_connect_string_func = func;
47
- }
47
+ // Create an arena, with \a initial_size bytes in the first allocated buffer
48
+ gpr_arena *gpr_arena_create(size_t initial_size);
49
+ // Allocate \a size bytes from the arena
50
+ void *gpr_arena_alloc(gpr_arena *arena, size_t size);
51
+ // Destroy an arena, returning the total number of bytes allocated
52
+ size_t gpr_arena_destroy(gpr_arena *arena);
48
53
 
49
- void grpc_set_initial_connect_string(grpc_resolved_address **addr,
50
- grpc_slice *initial_str) {
51
- g_set_initial_connect_string_func(addr, initial_str);
52
- }
54
+ #endif /* GRPC_CORE_LIB_SUPPORT_ARENA_H */
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  *
3
- * Copyright 2015, Google Inc.
3
+ * Copyright 2017, Google Inc.
4
4
  * All rights reserved.
5
5
  *
6
6
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,17 @@
31
31
  *
32
32
  */
33
33
 
34
- #include <grpc/slice.h>
35
- #include "src/core/lib/iomgr/resolve_address.h"
34
+ #include <grpc/support/atm.h>
35
+ #include <grpc/support/useful.h>
36
36
 
37
- void grpc_set_default_initial_connect_string(grpc_resolved_address **addr,
38
- grpc_slice *initial_str) {}
37
+ gpr_atm gpr_atm_no_barrier_clamped_add(gpr_atm *value, gpr_atm delta,
38
+ gpr_atm min, gpr_atm max) {
39
+ gpr_atm current;
40
+ gpr_atm new;
41
+ do {
42
+ current = gpr_atm_no_barrier_load(value);
43
+ new = GPR_CLAMP(current + delta, min, max);
44
+ if (new == current) break;
45
+ } while (!gpr_atm_no_barrier_cas(value, current, new));
46
+ return new;
47
+ }
@@ -67,12 +67,17 @@ unsigned gpr_cpu_num_cores(void) {
67
67
  }
68
68
 
69
69
  unsigned gpr_cpu_current_cpu(void) {
70
+ #ifdef GPR_MUSL_LIBC_COMPAT
71
+ // sched_getcpu() is undefined on musl
72
+ return 0;
73
+ #else
70
74
  int cpu = sched_getcpu();
71
75
  if (cpu < 0) {
72
76
  gpr_log(GPR_ERROR, "Error determining current CPU: %s\n", strerror(errno));
73
77
  return 0;
74
78
  }
75
79
  return (unsigned)cpu;
80
+ #endif
76
81
  }
77
82
 
78
83
  #endif /* GPR_CPU_LINUX */
@@ -119,6 +119,10 @@ int gpr_unref(gpr_refcount *r) {
119
119
  return prior == 1;
120
120
  }
121
121
 
122
+ int gpr_ref_is_unique(gpr_refcount *r) {
123
+ return gpr_atm_acq_load(&r->count) == 1;
124
+ }
125
+
122
126
  void gpr_stats_init(gpr_stats_counter *c, intptr_t n) {
123
127
  gpr_atm_rel_store(&c->value, n);
124
128
  }
@@ -42,7 +42,7 @@
42
42
  int gpr_time_cmp(gpr_timespec a, gpr_timespec b) {
43
43
  int cmp = (a.tv_sec > b.tv_sec) - (a.tv_sec < b.tv_sec);
44
44
  GPR_ASSERT(a.clock_type == b.clock_type);
45
- if (cmp == 0) {
45
+ if (cmp == 0 && a.tv_sec != INT64_MAX && a.tv_sec != INT64_MIN) {
46
46
  cmp = (a.tv_nsec > b.tv_nsec) - (a.tv_nsec < b.tv_nsec);
47
47
  }
48
48
  return cmp;
@@ -244,15 +244,9 @@ gpr_timespec gpr_convert_clock_type(gpr_timespec t, gpr_clock_type clock_type) {
244
244
  return t;
245
245
  }
246
246
 
247
- if (t.tv_nsec == 0) {
248
- if (t.tv_sec == INT64_MAX) {
249
- t.clock_type = clock_type;
250
- return t;
251
- }
252
- if (t.tv_sec == INT64_MIN) {
253
- t.clock_type = clock_type;
254
- return t;
255
- }
247
+ if (t.tv_sec == INT64_MAX || t.tv_sec == INT64_MIN) {
248
+ t.clock_type = clock_type;
249
+ return t;
256
250
  }
257
251
 
258
252
  if (clock_type == GPR_TIMESPAN) {
@@ -31,6 +31,8 @@
31
31
  *
32
32
  */
33
33
 
34
+ #include <grpc/support/port_platform.h>
35
+
34
36
  #include <string.h>
35
37
 
36
38
  /* Provide a wrapped memcpy for targets that need to be backwards
@@ -40,7 +42,7 @@
40
42
  */
41
43
 
42
44
  #ifdef __linux__
43
- #ifdef __x86_64__
45
+ #if defined(__x86_64__) && !defined(GPR_MUSL_LIBC_COMPAT)
44
46
  __asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
45
47
  void *__wrap_memcpy(void *destination, const void *source, size_t num) {
46
48
  return memcpy(destination, source, num);
@@ -51,6 +51,7 @@
51
51
  #include "src/core/lib/profiling/timers.h"
52
52
  #include "src/core/lib/slice/slice_internal.h"
53
53
  #include "src/core/lib/slice/slice_string_helpers.h"
54
+ #include "src/core/lib/support/arena.h"
54
55
  #include "src/core/lib/support/string.h"
55
56
  #include "src/core/lib/surface/api_trace.h"
56
57
  #include "src/core/lib/surface/call.h"
@@ -116,36 +117,56 @@ static received_status unpack_received_status(gpr_atm atm) {
116
117
 
117
118
  typedef struct batch_control {
118
119
  grpc_call *call;
119
- grpc_cq_completion cq_completion;
120
+ /* Share memory for cq_completion and notify_tag as they are never needed
121
+ simultaneously. Each byte used in this data structure count as six bytes
122
+ per call, so any savings we can make are worthwhile,
123
+
124
+ We use notify_tag to determine whether or not to send notification to the
125
+ completion queue. Once we've made that determination, we can reuse the
126
+ memory for cq_completion. */
127
+ union {
128
+ grpc_cq_completion cq_completion;
129
+ struct {
130
+ /* Any given op indicates completion by either (a) calling a closure or
131
+ (b) sending a notification on the call's completion queue. If
132
+ \a is_closure is true, \a tag indicates a closure to be invoked;
133
+ otherwise, \a tag indicates the tag to be used in the notification to
134
+ be sent to the completion queue. */
135
+ void *tag;
136
+ bool is_closure;
137
+ } notify_tag;
138
+ } completion_data;
120
139
  grpc_closure finish_batch;
121
- void *notify_tag;
122
140
  gpr_refcount steps_to_complete;
123
141
 
124
142
  grpc_error *errors[MAX_ERRORS_PER_BATCH];
125
143
  gpr_atm num_errors;
126
144
 
127
- uint8_t send_initial_metadata;
128
- uint8_t send_message;
129
- uint8_t send_final_op;
130
- uint8_t recv_initial_metadata;
131
- uint8_t recv_message;
132
- uint8_t recv_final_op;
133
- uint8_t is_notify_tag_closure;
134
-
135
- /* TODO(ctiller): now that this is inlined, figure out how much of the above
136
- state can be eliminated */
137
- grpc_transport_stream_op op;
145
+ grpc_transport_stream_op_batch op;
138
146
  } batch_control;
139
147
 
148
+ typedef struct {
149
+ gpr_mu child_list_mu;
150
+ grpc_call *first_child;
151
+ } parent_call;
152
+
153
+ typedef struct {
154
+ grpc_call *parent;
155
+ /** siblings: children of the same parent form a list, and this list is
156
+ protected under
157
+ parent->mu */
158
+ grpc_call *sibling_next;
159
+ grpc_call *sibling_prev;
160
+ } child_call;
161
+
140
162
  struct grpc_call {
163
+ gpr_arena *arena;
141
164
  grpc_completion_queue *cq;
142
165
  grpc_polling_entity pollent;
143
166
  grpc_channel *channel;
144
- grpc_call *parent;
145
- grpc_call *first_child;
146
167
  gpr_timespec start_time;
147
- /* TODO(ctiller): share with cq if possible? */
148
- gpr_mu mu;
168
+ /* parent_call* */ gpr_atm parent_call_atm;
169
+ child_call *child_call;
149
170
 
150
171
  /* client or server call */
151
172
  bool is_client;
@@ -160,13 +181,14 @@ struct grpc_call {
160
181
  bool received_initial_metadata;
161
182
  bool receiving_message;
162
183
  bool requested_final_op;
163
- bool received_final_op;
164
- bool sent_any_op;
184
+ gpr_atm any_ops_sent_atm;
185
+ gpr_atm received_final_op_atm;
165
186
 
166
187
  /* have we received initial metadata */
167
188
  bool has_initial_md_been_received;
168
189
 
169
- batch_control active_batches[MAX_CONCURRENT_BATCHES];
190
+ batch_control *active_batches[MAX_CONCURRENT_BATCHES];
191
+ grpc_transport_stream_op_batch_payload stream_op_payload;
170
192
 
171
193
  /* first idx: is_receiving, second idx: is_trailing */
172
194
  grpc_metadata_batch metadata_batch[2][2];
@@ -196,12 +218,6 @@ struct grpc_call {
196
218
  int send_extra_metadata_count;
197
219
  gpr_timespec send_deadline;
198
220
 
199
- /** siblings: children of the same parent form a list, and this list is
200
- protected under
201
- parent->mu */
202
- grpc_call *sibling_next;
203
- grpc_call *sibling_prev;
204
-
205
221
  grpc_slice_buffer_stream sending_stream;
206
222
 
207
223
  grpc_byte_stream *receiving_stream;
@@ -212,6 +228,8 @@ struct grpc_call {
212
228
  grpc_closure receiving_initial_metadata_ready;
213
229
  uint32_t test_only_last_message_flags;
214
230
 
231
+ grpc_closure release_call;
232
+
215
233
  union {
216
234
  struct {
217
235
  grpc_status_code *status;
@@ -235,7 +253,7 @@ int grpc_call_error_trace = 0;
235
253
  CALL_FROM_CALL_STACK(grpc_call_stack_from_top_element(top_elem))
236
254
 
237
255
  static void execute_op(grpc_exec_ctx *exec_ctx, grpc_call *call,
238
- grpc_transport_stream_op *op);
256
+ grpc_transport_stream_op_batch *op);
239
257
  static void cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
240
258
  status_source source, grpc_status_code status,
241
259
  const char *description);
@@ -260,10 +278,27 @@ static void add_batch_error(grpc_exec_ctx *exec_ctx, batch_control *bctl,
260
278
  static void add_init_error(grpc_error **composite, grpc_error *new) {
261
279
  if (new == GRPC_ERROR_NONE) return;
262
280
  if (*composite == GRPC_ERROR_NONE)
263
- *composite = GRPC_ERROR_CREATE("Call creation failed");
281
+ *composite = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Call creation failed");
264
282
  *composite = grpc_error_add_child(*composite, new);
265
283
  }
266
284
 
285
+ static parent_call *get_or_create_parent_call(grpc_call *call) {
286
+ parent_call *p = (parent_call *)gpr_atm_acq_load(&call->parent_call_atm);
287
+ if (p == NULL) {
288
+ p = gpr_arena_alloc(call->arena, sizeof(*p));
289
+ gpr_mu_init(&p->child_list_mu);
290
+ if (!gpr_atm_rel_cas(&call->parent_call_atm, (gpr_atm)NULL, (gpr_atm)p)) {
291
+ gpr_mu_destroy(&p->child_list_mu);
292
+ p = (parent_call *)gpr_atm_acq_load(&call->parent_call_atm);
293
+ }
294
+ }
295
+ return p;
296
+ }
297
+
298
+ static parent_call *get_parent_call(grpc_call *call) {
299
+ return (parent_call *)gpr_atm_acq_load(&call->parent_call_atm);
300
+ }
301
+
267
302
  grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
268
303
  const grpc_call_create_args *args,
269
304
  grpc_call **out_call) {
@@ -273,16 +308,19 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
273
308
  grpc_channel_get_channel_stack(args->channel);
274
309
  grpc_call *call;
275
310
  GPR_TIMER_BEGIN("grpc_call_create", 0);
276
- call = gpr_zalloc(sizeof(grpc_call) + channel_stack->call_stack_size);
311
+ gpr_arena *arena =
312
+ gpr_arena_create(grpc_channel_get_call_size_estimate(args->channel));
313
+ call = gpr_arena_alloc(arena,
314
+ sizeof(grpc_call) + channel_stack->call_stack_size);
315
+ call->arena = arena;
277
316
  *out_call = call;
278
- gpr_mu_init(&call->mu);
279
317
  call->channel = args->channel;
280
318
  call->cq = args->cq;
281
- call->parent = args->parent_call;
282
319
  call->start_time = gpr_now(GPR_CLOCK_MONOTONIC);
283
320
  /* Always support no compression */
284
321
  GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE);
285
322
  call->is_client = args->server_transport_data == NULL;
323
+ call->stream_op_payload.context = call->context;
286
324
  grpc_slice path = grpc_empty_slice();
287
325
  if (call->is_client) {
288
326
  GPR_ASSERT(args->add_initial_metadata_count <
@@ -309,11 +347,17 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
309
347
  gpr_convert_clock_type(args->send_deadline, GPR_CLOCK_MONOTONIC);
310
348
 
311
349
  if (args->parent_call != NULL) {
350
+ child_call *cc = call->child_call =
351
+ gpr_arena_alloc(arena, sizeof(child_call));
352
+ call->child_call->parent = args->parent_call;
353
+
312
354
  GRPC_CALL_INTERNAL_REF(args->parent_call, "child");
313
355
  GPR_ASSERT(call->is_client);
314
356
  GPR_ASSERT(!args->parent_call->is_client);
315
357
 
316
- gpr_mu_lock(&args->parent_call->mu);
358
+ parent_call *pc = get_or_create_parent_call(args->parent_call);
359
+
360
+ gpr_mu_lock(&pc->child_list_mu);
317
361
 
318
362
  if (args->propagation_mask & GRPC_PROPAGATE_DEADLINE) {
319
363
  send_deadline = gpr_time_min(
@@ -327,44 +371,53 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
327
371
  * call. */
328
372
  if (args->propagation_mask & GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT) {
329
373
  if (0 == (args->propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT)) {
330
- add_init_error(&error,
331
- GRPC_ERROR_CREATE("Census tracing propagation requested "
332
- "without Census context propagation"));
374
+ add_init_error(&error, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
375
+ "Census tracing propagation requested "
376
+ "without Census context propagation"));
333
377
  }
334
378
  grpc_call_context_set(
335
379
  call, GRPC_CONTEXT_TRACING,
336
380
  args->parent_call->context[GRPC_CONTEXT_TRACING].value, NULL);
337
381
  } else if (args->propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT) {
338
- add_init_error(&error,
339
- GRPC_ERROR_CREATE("Census context propagation requested "
340
- "without Census tracing propagation"));
382
+ add_init_error(&error, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
383
+ "Census context propagation requested "
384
+ "without Census tracing propagation"));
341
385
  }
342
386
  if (args->propagation_mask & GRPC_PROPAGATE_CANCELLATION) {
343
387
  call->cancellation_is_inherited = 1;
388
+ if (gpr_atm_acq_load(&args->parent_call->received_final_op_atm)) {
389
+ cancel_with_error(exec_ctx, call, STATUS_FROM_API_OVERRIDE,
390
+ GRPC_ERROR_CANCELLED);
391
+ }
344
392
  }
345
393
 
346
- if (args->parent_call->first_child == NULL) {
347
- args->parent_call->first_child = call;
348
- call->sibling_next = call->sibling_prev = call;
394
+ if (pc->first_child == NULL) {
395
+ pc->first_child = call;
396
+ cc->sibling_next = cc->sibling_prev = call;
349
397
  } else {
350
- call->sibling_next = args->parent_call->first_child;
351
- call->sibling_prev = args->parent_call->first_child->sibling_prev;
352
- call->sibling_next->sibling_prev = call->sibling_prev->sibling_next =
353
- call;
398
+ cc->sibling_next = pc->first_child;
399
+ cc->sibling_prev = pc->first_child->child_call->sibling_prev;
400
+ cc->sibling_next->child_call->sibling_prev =
401
+ cc->sibling_prev->child_call->sibling_next = call;
354
402
  }
355
403
 
356
- gpr_mu_unlock(&args->parent_call->mu);
404
+ gpr_mu_unlock(&pc->child_list_mu);
357
405
  }
358
406
 
359
407
  call->send_deadline = send_deadline;
360
408
 
361
409
  GRPC_CHANNEL_INTERNAL_REF(args->channel, "call");
362
410
  /* initial refcount dropped by grpc_call_destroy */
411
+ grpc_call_element_args call_args = {
412
+ .call_stack = CALL_STACK_FROM_CALL(call),
413
+ .server_transport_data = args->server_transport_data,
414
+ .context = call->context,
415
+ .path = path,
416
+ .start_time = call->start_time,
417
+ .deadline = send_deadline,
418
+ .arena = call->arena};
363
419
  add_init_error(&error, grpc_call_stack_init(exec_ctx, channel_stack, 1,
364
- destroy_call, call, call->context,
365
- args->server_transport_data, path,
366
- call->start_time, send_deadline,
367
- CALL_STACK_FROM_CALL(call)));
420
+ destroy_call, call, &call_args));
368
421
  if (error != GRPC_ERROR_NONE) {
369
422
  cancel_with_error(exec_ctx, call, STATUS_FROM_SURFACE,
370
423
  GRPC_ERROR_REF(error));
@@ -421,6 +474,14 @@ void grpc_call_internal_unref(grpc_exec_ctx *exec_ctx, grpc_call *c REF_ARG) {
421
474
  GRPC_CALL_STACK_UNREF(exec_ctx, CALL_STACK_FROM_CALL(c), REF_REASON);
422
475
  }
423
476
 
477
+ static void release_call(grpc_exec_ctx *exec_ctx, void *call,
478
+ grpc_error *error) {
479
+ grpc_call *c = call;
480
+ grpc_channel *channel = c->channel;
481
+ grpc_channel_update_call_size_estimate(channel, gpr_arena_destroy(c->arena));
482
+ GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel, "call");
483
+ }
484
+
424
485
  static void set_status_value_directly(grpc_status_code status, void *dest);
425
486
  static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
426
487
  grpc_error *error) {
@@ -435,7 +496,10 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
435
496
  if (c->receiving_stream != NULL) {
436
497
  grpc_byte_stream_destroy(exec_ctx, c->receiving_stream);
437
498
  }
438
- gpr_mu_destroy(&c->mu);
499
+ parent_call *pc = get_parent_call(c);
500
+ if (pc != NULL) {
501
+ gpr_mu_destroy(&pc->child_list_mu);
502
+ }
439
503
  for (ii = 0; ii < c->send_extra_metadata_count; ii++) {
440
504
  GRPC_MDELEM_UNREF(exec_ctx, c->send_extra_metadata[ii].md);
441
505
  }
@@ -447,7 +511,6 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
447
511
  if (c->cq) {
448
512
  GRPC_CQ_INTERNAL_UNREF(c->cq, "bind");
449
513
  }
450
- grpc_channel *channel = c->channel;
451
514
 
452
515
  get_final_status(call, set_status_value_directly, &c->final_info.final_status,
453
516
  NULL);
@@ -456,41 +519,41 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
456
519
 
457
520
  for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
458
521
  GRPC_ERROR_UNREF(
459
- unpack_received_status(gpr_atm_no_barrier_load(&c->status[i])).error);
522
+ unpack_received_status(gpr_atm_acq_load(&c->status[i])).error);
460
523
  }
461
524
 
462
- grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c), &c->final_info, c);
463
- GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel, "call");
525
+ grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c), &c->final_info,
526
+ grpc_closure_init(&c->release_call, release_call, c,
527
+ grpc_schedule_on_exec_ctx));
464
528
  GPR_TIMER_END("destroy_call", 0);
465
529
  }
466
530
 
467
531
  void grpc_call_destroy(grpc_call *c) {
468
- int cancel;
469
- grpc_call *parent = c->parent;
532
+ child_call *cc = c->child_call;
470
533
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
471
534
 
472
535
  GPR_TIMER_BEGIN("grpc_call_destroy", 0);
473
536
  GRPC_API_TRACE("grpc_call_destroy(c=%p)", 1, (c));
474
537
 
475
- if (parent) {
476
- gpr_mu_lock(&parent->mu);
477
- if (c == parent->first_child) {
478
- parent->first_child = c->sibling_next;
479
- if (c == parent->first_child) {
480
- parent->first_child = NULL;
538
+ if (cc) {
539
+ parent_call *pc = get_parent_call(cc->parent);
540
+ gpr_mu_lock(&pc->child_list_mu);
541
+ if (c == pc->first_child) {
542
+ pc->first_child = cc->sibling_next;
543
+ if (c == pc->first_child) {
544
+ pc->first_child = NULL;
481
545
  }
482
- c->sibling_prev->sibling_next = c->sibling_next;
483
- c->sibling_next->sibling_prev = c->sibling_prev;
484
546
  }
485
- gpr_mu_unlock(&parent->mu);
486
- GRPC_CALL_INTERNAL_UNREF(&exec_ctx, parent, "child");
547
+ cc->sibling_prev->child_call->sibling_next = cc->sibling_next;
548
+ cc->sibling_next->child_call->sibling_prev = cc->sibling_prev;
549
+ gpr_mu_unlock(&pc->child_list_mu);
550
+ GRPC_CALL_INTERNAL_UNREF(&exec_ctx, cc->parent, "child");
487
551
  }
488
552
 
489
- gpr_mu_lock(&c->mu);
490
553
  GPR_ASSERT(!c->destroy_called);
491
554
  c->destroy_called = 1;
492
- cancel = c->sent_any_op && !c->received_final_op;
493
- gpr_mu_unlock(&c->mu);
555
+ bool cancel = gpr_atm_acq_load(&c->any_ops_sent_atm) != 0 &&
556
+ gpr_atm_acq_load(&c->received_final_op_atm) == 0;
494
557
  if (cancel) {
495
558
  cancel_with_error(&exec_ctx, c, STATUS_FROM_API_OVERRIDE,
496
559
  GRPC_ERROR_CANCELLED);
@@ -511,13 +574,12 @@ grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved) {
511
574
  }
512
575
 
513
576
  static void execute_op(grpc_exec_ctx *exec_ctx, grpc_call *call,
514
- grpc_transport_stream_op *op) {
577
+ grpc_transport_stream_op_batch *op) {
515
578
  grpc_call_element *elem;
516
579
 
517
580
  GPR_TIMER_BEGIN("execute_op", 0);
518
581
  elem = CALL_ELEM_FROM_CALL(call, 0);
519
- op->context = call->context;
520
- elem->filter->start_transport_stream_op(exec_ctx, elem, op);
582
+ elem->filter->start_transport_stream_op_batch(exec_ctx, elem, op);
521
583
  GPR_TIMER_END("execute_op", 0);
522
584
  }
523
585
 
@@ -555,60 +617,34 @@ grpc_call_error grpc_call_cancel_with_status(grpc_call *c,
555
617
  "c=%p, status=%d, description=%s, reserved=%p)",
556
618
  4, (c, (int)status, description, reserved));
557
619
  GPR_ASSERT(reserved == NULL);
558
- gpr_mu_lock(&c->mu);
559
620
  cancel_with_status(&exec_ctx, c, STATUS_FROM_API_OVERRIDE, status,
560
621
  description);
561
- gpr_mu_unlock(&c->mu);
562
622
  grpc_exec_ctx_finish(&exec_ctx);
563
623
  return GRPC_CALL_OK;
564
624
  }
565
625
 
566
- typedef struct termination_closure {
567
- grpc_closure closure;
568
- grpc_call *call;
569
- grpc_transport_stream_op op;
570
- } termination_closure;
571
-
572
- static void done_termination(grpc_exec_ctx *exec_ctx, void *tcp,
573
- grpc_error *error) {
574
- termination_closure *tc = tcp;
575
- GRPC_CALL_INTERNAL_UNREF(exec_ctx, tc->call, "termination");
576
- gpr_free(tc);
577
- }
578
-
579
- static void send_termination(grpc_exec_ctx *exec_ctx, void *tcp,
626
+ static void done_termination(grpc_exec_ctx *exec_ctx, void *call,
580
627
  grpc_error *error) {
581
- termination_closure *tc = tcp;
582
- memset(&tc->op, 0, sizeof(tc->op));
583
- tc->op.cancel_error = GRPC_ERROR_REF(error);
584
- /* reuse closure to catch completion */
585
- tc->op.on_complete = grpc_closure_init(&tc->closure, done_termination, tc,
586
- grpc_schedule_on_exec_ctx);
587
- execute_op(exec_ctx, tc->call, &tc->op);
588
- }
589
-
590
- static void terminate_with_error(grpc_exec_ctx *exec_ctx, grpc_call *c,
591
- grpc_error *error) {
592
- termination_closure *tc = gpr_malloc(sizeof(*tc));
593
- memset(tc, 0, sizeof(*tc));
594
- tc->call = c;
595
- GRPC_CALL_INTERNAL_REF(tc->call, "termination");
596
- grpc_closure_sched(exec_ctx, grpc_closure_init(&tc->closure, send_termination,
597
- tc, grpc_schedule_on_exec_ctx),
598
- error);
628
+ GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "termination");
599
629
  }
600
630
 
601
631
  static void cancel_with_error(grpc_exec_ctx *exec_ctx, grpc_call *c,
602
632
  status_source source, grpc_error *error) {
633
+ GRPC_CALL_INTERNAL_REF(c, "termination");
603
634
  set_status_from_error(exec_ctx, c, source, GRPC_ERROR_REF(error));
604
- terminate_with_error(exec_ctx, c, error);
635
+ grpc_transport_stream_op_batch *op = grpc_make_transport_stream_op(
636
+ grpc_closure_create(done_termination, c, grpc_schedule_on_exec_ctx));
637
+ op->cancel_stream = true;
638
+ op->payload->cancel_stream.cancel_error = error;
639
+ execute_op(exec_ctx, c, op);
605
640
  }
606
641
 
607
642
  static grpc_error *error_from_status(grpc_status_code status,
608
643
  const char *description) {
609
644
  return grpc_error_set_int(
610
- grpc_error_set_str(GRPC_ERROR_CREATE(description),
611
- GRPC_ERROR_STR_GRPC_MESSAGE, description),
645
+ grpc_error_set_str(GRPC_ERROR_CREATE_FROM_COPIED_STRING(description),
646
+ GRPC_ERROR_STR_GRPC_MESSAGE,
647
+ grpc_slice_from_copied_string(description)),
612
648
  GRPC_ERROR_INT_GRPC_STATUS, status);
613
649
  }
614
650
 
@@ -628,16 +664,15 @@ static bool get_final_status_from(
628
664
  void (*set_value)(grpc_status_code code, void *user_data),
629
665
  void *set_value_user_data, grpc_slice *details) {
630
666
  grpc_status_code code;
631
- const char *msg = NULL;
632
- grpc_error_get_status(error, call->send_deadline, &code, &msg, NULL);
667
+ grpc_slice slice = grpc_empty_slice();
668
+ grpc_error_get_status(error, call->send_deadline, &code, &slice, NULL);
633
669
  if (code == GRPC_STATUS_OK && !allow_ok_status) {
634
670
  return false;
635
671
  }
636
672
 
637
673
  set_value(code, set_value_user_data);
638
674
  if (details != NULL) {
639
- *details =
640
- msg == NULL ? grpc_empty_slice() : grpc_slice_from_copied_string(msg);
675
+ *details = grpc_slice_ref_internal(slice);
641
676
  }
642
677
  return true;
643
678
  }
@@ -715,9 +750,7 @@ static void set_incoming_compression_algorithm(
715
750
  grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(
716
751
  grpc_call *call) {
717
752
  grpc_compression_algorithm algorithm;
718
- gpr_mu_lock(&call->mu);
719
753
  algorithm = call->incoming_compression_algorithm;
720
- gpr_mu_unlock(&call->mu);
721
754
  return algorithm;
722
755
  }
723
756
 
@@ -729,9 +762,7 @@ static grpc_compression_algorithm compression_algorithm_for_level_locked(
729
762
 
730
763
  uint32_t grpc_call_test_only_get_message_flags(grpc_call *call) {
731
764
  uint32_t flags;
732
- gpr_mu_lock(&call->mu);
733
765
  flags = call->test_only_last_message_flags;
734
- gpr_mu_unlock(&call->mu);
735
766
  return flags;
736
767
  }
737
768
 
@@ -785,9 +816,7 @@ static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx,
785
816
 
786
817
  uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) {
787
818
  uint32_t encodings_accepted_by_peer;
788
- gpr_mu_lock(&call->mu);
789
819
  encodings_accepted_by_peer = call->encodings_accepted_by_peer;
790
- gpr_mu_unlock(&call->mu);
791
820
  return encodings_accepted_by_peer;
792
821
  }
793
822
 
@@ -906,18 +935,19 @@ static void recv_common_filter(grpc_exec_ctx *exec_ctx, grpc_call *call,
906
935
  grpc_error *error =
907
936
  status_code == GRPC_STATUS_OK
908
937
  ? GRPC_ERROR_NONE
909
- : grpc_error_set_int(GRPC_ERROR_CREATE("Error received from peer"),
938
+ : grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
939
+ "Error received from peer"),
910
940
  GRPC_ERROR_INT_GRPC_STATUS,
911
941
  (intptr_t)status_code);
912
942
 
913
943
  if (b->idx.named.grpc_message != NULL) {
914
- char *msg =
915
- grpc_slice_to_c_string(GRPC_MDVALUE(b->idx.named.grpc_message->md));
916
- error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, msg);
917
- gpr_free(msg);
944
+ error = grpc_error_set_str(
945
+ error, GRPC_ERROR_STR_GRPC_MESSAGE,
946
+ grpc_slice_ref_internal(GRPC_MDVALUE(b->idx.named.grpc_message->md)));
918
947
  grpc_metadata_batch_remove(exec_ctx, b, b->idx.named.grpc_message);
919
948
  } else if (error != GRPC_ERROR_NONE) {
920
- error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, "");
949
+ error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE,
950
+ grpc_empty_slice());
921
951
  }
922
952
 
923
953
  set_status_from_error(exec_ctx, call, STATUS_FROM_WIRE, error);
@@ -1034,16 +1064,17 @@ static batch_control *allocate_batch_control(grpc_call *call,
1034
1064
  const grpc_op *ops,
1035
1065
  size_t num_ops) {
1036
1066
  int slot = batch_slot_for_op(ops[0].op);
1037
- for (size_t i = 1; i < num_ops; i++) {
1038
- int op_slot = batch_slot_for_op(ops[i].op);
1039
- slot = GPR_MIN(slot, op_slot);
1067
+ batch_control **pslot = &call->active_batches[slot];
1068
+ if (*pslot == NULL) {
1069
+ *pslot = gpr_arena_alloc(call->arena, sizeof(batch_control));
1040
1070
  }
1041
- batch_control *bctl = &call->active_batches[slot];
1071
+ batch_control *bctl = *pslot;
1042
1072
  if (bctl->call != NULL) {
1043
1073
  return NULL;
1044
1074
  }
1045
1075
  memset(bctl, 0, sizeof(*bctl));
1046
1076
  bctl->call = call;
1077
+ bctl->op.payload = &call->stream_op_payload;
1047
1078
  return bctl;
1048
1079
  }
1049
1080
 
@@ -1056,7 +1087,7 @@ static void finish_batch_completion(grpc_exec_ctx *exec_ctx, void *user_data,
1056
1087
  }
1057
1088
 
1058
1089
  static grpc_error *consolidate_batch_errors(batch_control *bctl) {
1059
- size_t n = (size_t)gpr_atm_no_barrier_load(&bctl->num_errors);
1090
+ size_t n = (size_t)gpr_atm_acq_load(&bctl->num_errors);
1060
1091
  if (n == 0) {
1061
1092
  return GRPC_ERROR_NONE;
1062
1093
  } else if (n == 1) {
@@ -1066,8 +1097,8 @@ static grpc_error *consolidate_batch_errors(batch_control *bctl) {
1066
1097
  bctl->errors[0] = NULL;
1067
1098
  return e;
1068
1099
  } else {
1069
- grpc_error *error =
1070
- GRPC_ERROR_CREATE_REFERENCING("Call batch failed", bctl->errors, n);
1100
+ grpc_error *error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
1101
+ "Call batch failed", bctl->errors, n);
1071
1102
  for (size_t i = 0; i < n; i++) {
1072
1103
  GRPC_ERROR_UNREF(bctl->errors[i]);
1073
1104
  bctl->errors[i] = NULL;
@@ -1078,44 +1109,48 @@ static grpc_error *consolidate_batch_errors(batch_control *bctl) {
1078
1109
 
1079
1110
  static void post_batch_completion(grpc_exec_ctx *exec_ctx,
1080
1111
  batch_control *bctl) {
1081
- grpc_call *child_call;
1082
1112
  grpc_call *next_child_call;
1083
1113
  grpc_call *call = bctl->call;
1084
1114
  grpc_error *error = consolidate_batch_errors(bctl);
1085
1115
 
1086
- gpr_mu_lock(&call->mu);
1087
-
1088
- if (bctl->send_initial_metadata) {
1116
+ if (bctl->op.send_initial_metadata) {
1089
1117
  grpc_metadata_batch_destroy(
1090
1118
  exec_ctx,
1091
1119
  &call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */]);
1092
1120
  }
1093
- if (bctl->send_message) {
1121
+ if (bctl->op.send_message) {
1094
1122
  call->sending_message = false;
1095
1123
  }
1096
- if (bctl->send_final_op) {
1124
+ if (bctl->op.send_trailing_metadata) {
1097
1125
  grpc_metadata_batch_destroy(
1098
1126
  exec_ctx,
1099
1127
  &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */]);
1100
1128
  }
1101
- if (bctl->recv_final_op) {
1129
+ if (bctl->op.recv_trailing_metadata) {
1102
1130
  grpc_metadata_batch *md =
1103
1131
  &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
1104
1132
  recv_trailing_filter(exec_ctx, call, md);
1105
1133
 
1106
- call->received_final_op = true;
1107
1134
  /* propagate cancellation to any interested children */
1108
- child_call = call->first_child;
1109
- if (child_call != NULL) {
1110
- do {
1111
- next_child_call = child_call->sibling_next;
1112
- if (child_call->cancellation_is_inherited) {
1113
- GRPC_CALL_INTERNAL_REF(child_call, "propagate_cancel");
1114
- grpc_call_cancel(child_call, NULL);
1115
- GRPC_CALL_INTERNAL_UNREF(exec_ctx, child_call, "propagate_cancel");
1116
- }
1117
- child_call = next_child_call;
1118
- } while (child_call != call->first_child);
1135
+ gpr_atm_rel_store(&call->received_final_op_atm, 1);
1136
+ parent_call *pc = get_parent_call(call);
1137
+ if (pc != NULL) {
1138
+ grpc_call *child;
1139
+ gpr_mu_lock(&pc->child_list_mu);
1140
+ child = pc->first_child;
1141
+ if (child != NULL) {
1142
+ do {
1143
+ next_child_call = child->child_call->sibling_next;
1144
+ if (child->cancellation_is_inherited) {
1145
+ GRPC_CALL_INTERNAL_REF(child, "propagate_cancel");
1146
+ cancel_with_error(exec_ctx, child, STATUS_FROM_API_OVERRIDE,
1147
+ GRPC_ERROR_CANCELLED);
1148
+ GRPC_CALL_INTERNAL_UNREF(exec_ctx, child, "propagate_cancel");
1149
+ }
1150
+ child = next_child_call;
1151
+ } while (child != pc->first_child);
1152
+ }
1153
+ gpr_mu_unlock(&pc->child_list_mu);
1119
1154
  }
1120
1155
 
1121
1156
  if (call->is_client) {
@@ -1130,17 +1165,17 @@ static void post_batch_completion(grpc_exec_ctx *exec_ctx,
1130
1165
  GRPC_ERROR_UNREF(error);
1131
1166
  error = GRPC_ERROR_NONE;
1132
1167
  }
1133
- gpr_mu_unlock(&call->mu);
1134
1168
 
1135
- if (bctl->is_notify_tag_closure) {
1169
+ if (bctl->completion_data.notify_tag.is_closure) {
1136
1170
  /* unrefs bctl->error */
1137
1171
  bctl->call = NULL;
1138
- grpc_closure_run(exec_ctx, bctl->notify_tag, error);
1172
+ grpc_closure_run(exec_ctx, bctl->completion_data.notify_tag.tag, error);
1139
1173
  GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "completion");
1140
1174
  } else {
1141
1175
  /* unrefs bctl->error */
1142
- grpc_cq_end_op(exec_ctx, bctl->call->cq, bctl->notify_tag, error,
1143
- finish_batch_completion, bctl, &bctl->cq_completion);
1176
+ grpc_cq_end_op(
1177
+ exec_ctx, bctl->call->cq, bctl->completion_data.notify_tag.tag, error,
1178
+ finish_batch_completion, bctl, &bctl->completion_data.cq_completion);
1144
1179
  }
1145
1180
  }
1146
1181
 
@@ -1221,7 +1256,6 @@ static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
1221
1256
  grpc_error *error) {
1222
1257
  batch_control *bctl = bctlp;
1223
1258
  grpc_call *call = bctl->call;
1224
- gpr_mu_lock(&bctl->call->mu);
1225
1259
  if (error != GRPC_ERROR_NONE) {
1226
1260
  if (call->receiving_stream != NULL) {
1227
1261
  grpc_byte_stream_destroy(exec_ctx, call->receiving_stream);
@@ -1233,11 +1267,9 @@ static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
1233
1267
  }
1234
1268
  if (call->has_initial_md_been_received || error != GRPC_ERROR_NONE ||
1235
1269
  call->receiving_stream == NULL) {
1236
- gpr_mu_unlock(&bctl->call->mu);
1237
1270
  process_data_after_md(exec_ctx, bctlp);
1238
1271
  } else {
1239
1272
  call->saved_receiving_stream_ready_bctlp = bctlp;
1240
- gpr_mu_unlock(&bctl->call->mu);
1241
1273
  }
1242
1274
  }
1243
1275
 
@@ -1296,7 +1328,7 @@ static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx,
1296
1328
  static void add_batch_error(grpc_exec_ctx *exec_ctx, batch_control *bctl,
1297
1329
  grpc_error *error, bool has_cancelled) {
1298
1330
  if (error == GRPC_ERROR_NONE) return;
1299
- int idx = (int)gpr_atm_no_barrier_fetch_add(&bctl->num_errors, 1);
1331
+ int idx = (int)gpr_atm_full_fetch_add(&bctl->num_errors, 1);
1300
1332
  if (idx == 0 && !has_cancelled) {
1301
1333
  cancel_with_error(exec_ctx, bctl->call, STATUS_FROM_CORE,
1302
1334
  GRPC_ERROR_REF(error));
@@ -1309,8 +1341,6 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx,
1309
1341
  batch_control *bctl = bctlp;
1310
1342
  grpc_call *call = bctl->call;
1311
1343
 
1312
- gpr_mu_lock(&call->mu);
1313
-
1314
1344
  add_batch_error(exec_ctx, bctl, GRPC_ERROR_REF(error), false);
1315
1345
  if (error == GRPC_ERROR_NONE) {
1316
1346
  grpc_metadata_batch *md =
@@ -1336,11 +1366,9 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx,
1336
1366
  receiving_stream_ready, call->saved_receiving_stream_ready_bctlp,
1337
1367
  grpc_schedule_on_exec_ctx);
1338
1368
  call->saved_receiving_stream_ready_bctlp = NULL;
1339
- grpc_closure_sched(exec_ctx, saved_rsr_closure, GRPC_ERROR_REF(error));
1369
+ grpc_closure_run(exec_ctx, saved_rsr_closure, GRPC_ERROR_REF(error));
1340
1370
  }
1341
1371
 
1342
- gpr_mu_unlock(&call->mu);
1343
-
1344
1372
  finish_batch_step(exec_ctx, bctl);
1345
1373
  }
1346
1374
 
@@ -1390,12 +1418,13 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1390
1418
  if (bctl == NULL) {
1391
1419
  return GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
1392
1420
  }
1393
- bctl->notify_tag = notify_tag;
1394
- bctl->is_notify_tag_closure = (uint8_t)(is_notify_tag_closure != 0);
1421
+ bctl->completion_data.notify_tag.tag = notify_tag;
1422
+ bctl->completion_data.notify_tag.is_closure =
1423
+ (uint8_t)(is_notify_tag_closure != 0);
1395
1424
 
1396
- gpr_mu_lock(&call->mu);
1397
- grpc_transport_stream_op *stream_op = &bctl->op;
1398
- memset(stream_op, 0, sizeof(*stream_op));
1425
+ grpc_transport_stream_op_batch *stream_op = &bctl->op;
1426
+ grpc_transport_stream_op_batch_payload *stream_op_payload =
1427
+ &call->stream_op_payload;
1399
1428
  stream_op->covered_by_poller = true;
1400
1429
 
1401
1430
  /* rewrite batch ops into a transport op */
@@ -1449,8 +1478,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1449
1478
  error = GRPC_CALL_ERROR_INVALID_METADATA;
1450
1479
  goto done_with_error;
1451
1480
  }
1452
- bctl->send_initial_metadata = 1;
1453
- call->sent_initial_metadata = 1;
1481
+ stream_op->send_initial_metadata = true;
1482
+ call->sent_initial_metadata = true;
1454
1483
  if (!prepare_application_metadata(
1455
1484
  exec_ctx, call, (int)op->data.send_initial_metadata.count,
1456
1485
  op->data.send_initial_metadata.metadata, 0, call->is_client,
@@ -1460,9 +1489,10 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1460
1489
  }
1461
1490
  /* TODO(ctiller): just make these the same variable? */
1462
1491
  call->metadata_batch[0][0].deadline = call->send_deadline;
1463
- stream_op->send_initial_metadata =
1492
+ stream_op_payload->send_initial_metadata.send_initial_metadata =
1464
1493
  &call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */];
1465
- stream_op->send_initial_metadata_flags = op->flags;
1494
+ stream_op_payload->send_initial_metadata.send_initial_metadata_flags =
1495
+ op->flags;
1466
1496
  break;
1467
1497
  case GRPC_OP_SEND_MESSAGE:
1468
1498
  if (!are_write_flags_valid(op->flags)) {
@@ -1477,8 +1507,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1477
1507
  error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
1478
1508
  goto done_with_error;
1479
1509
  }
1480
- bctl->send_message = 1;
1481
- call->sending_message = 1;
1510
+ stream_op->send_message = true;
1511
+ call->sending_message = true;
1482
1512
  grpc_slice_buffer_stream_init(
1483
1513
  &call->sending_stream,
1484
1514
  &op->data.send_message.send_message->data.raw.slice_buffer,
@@ -1490,7 +1520,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1490
1520
  GRPC_COMPRESS_NONE) {
1491
1521
  call->sending_stream.base.flags |= GRPC_WRITE_INTERNAL_COMPRESS;
1492
1522
  }
1493
- stream_op->send_message = &call->sending_stream.base;
1523
+ stream_op_payload->send_message.send_message =
1524
+ &call->sending_stream.base;
1494
1525
  break;
1495
1526
  case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
1496
1527
  /* Flag validation: currently allow no flags */
@@ -1506,9 +1537,9 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1506
1537
  error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
1507
1538
  goto done_with_error;
1508
1539
  }
1509
- bctl->send_final_op = 1;
1510
- call->sent_final_op = 1;
1511
- stream_op->send_trailing_metadata =
1540
+ stream_op->send_trailing_metadata = true;
1541
+ call->sent_final_op = true;
1542
+ stream_op_payload->send_trailing_metadata.send_trailing_metadata =
1512
1543
  &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */];
1513
1544
  break;
1514
1545
  case GRPC_OP_SEND_STATUS_FROM_SERVER:
@@ -1530,8 +1561,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1530
1561
  error = GRPC_CALL_ERROR_INVALID_METADATA;
1531
1562
  goto done_with_error;
1532
1563
  }
1533
- bctl->send_final_op = 1;
1534
- call->sent_final_op = 1;
1564
+ stream_op->send_trailing_metadata = true;
1565
+ call->sent_final_op = true;
1535
1566
  GPR_ASSERT(call->send_extra_metadata_count == 0);
1536
1567
  call->send_extra_metadata_count = 1;
1537
1568
  call->send_extra_metadata[0].md = grpc_channel_get_reffed_status_elem(
@@ -1539,7 +1570,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1539
1570
  {
1540
1571
  grpc_error *override_error = GRPC_ERROR_NONE;
1541
1572
  if (op->data.send_status_from_server.status != GRPC_STATUS_OK) {
1542
- override_error = GRPC_ERROR_CREATE("Error from server send status");
1573
+ override_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
1574
+ "Error from server send status");
1543
1575
  }
1544
1576
  if (op->data.send_status_from_server.status_details != NULL) {
1545
1577
  call->send_extra_metadata[1].md = grpc_mdelem_from_slices(
@@ -1549,8 +1581,9 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1549
1581
  call->send_extra_metadata_count++;
1550
1582
  char *msg = grpc_slice_to_c_string(
1551
1583
  GRPC_MDVALUE(call->send_extra_metadata[1].md));
1552
- override_error = grpc_error_set_str(
1553
- override_error, GRPC_ERROR_STR_GRPC_MESSAGE, msg);
1584
+ override_error =
1585
+ grpc_error_set_str(override_error, GRPC_ERROR_STR_GRPC_MESSAGE,
1586
+ grpc_slice_from_copied_string(msg));
1554
1587
  gpr_free(msg);
1555
1588
  }
1556
1589
  set_status_from_error(exec_ctx, call, STATUS_FROM_API_OVERRIDE,
@@ -1568,7 +1601,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1568
1601
  error = GRPC_CALL_ERROR_INVALID_METADATA;
1569
1602
  goto done_with_error;
1570
1603
  }
1571
- stream_op->send_trailing_metadata =
1604
+ stream_op_payload->send_trailing_metadata.send_trailing_metadata =
1572
1605
  &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */];
1573
1606
  break;
1574
1607
  case GRPC_OP_RECV_INITIAL_METADATA:
@@ -1585,16 +1618,16 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1585
1618
  from server.c. In that case, it's coming from accept_stream, and in
1586
1619
  that case we're not necessarily covered by a poller. */
1587
1620
  stream_op->covered_by_poller = call->is_client;
1588
- call->received_initial_metadata = 1;
1621
+ call->received_initial_metadata = true;
1589
1622
  call->buffered_metadata[0] =
1590
1623
  op->data.recv_initial_metadata.recv_initial_metadata;
1591
1624
  grpc_closure_init(&call->receiving_initial_metadata_ready,
1592
1625
  receiving_initial_metadata_ready, bctl,
1593
1626
  grpc_schedule_on_exec_ctx);
1594
- bctl->recv_initial_metadata = 1;
1595
- stream_op->recv_initial_metadata =
1627
+ stream_op->recv_initial_metadata = true;
1628
+ stream_op_payload->recv_initial_metadata.recv_initial_metadata =
1596
1629
  &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */];
1597
- stream_op->recv_initial_metadata_ready =
1630
+ stream_op_payload->recv_initial_metadata.recv_initial_metadata_ready =
1598
1631
  &call->receiving_initial_metadata_ready;
1599
1632
  num_completion_callbacks_needed++;
1600
1633
  break;
@@ -1608,13 +1641,14 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1608
1641
  error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
1609
1642
  goto done_with_error;
1610
1643
  }
1611
- call->receiving_message = 1;
1612
- bctl->recv_message = 1;
1644
+ call->receiving_message = true;
1645
+ stream_op->recv_message = true;
1613
1646
  call->receiving_buffer = op->data.recv_message.recv_message;
1614
- stream_op->recv_message = &call->receiving_stream;
1647
+ stream_op_payload->recv_message.recv_message = &call->receiving_stream;
1615
1648
  grpc_closure_init(&call->receiving_stream_ready, receiving_stream_ready,
1616
1649
  bctl, grpc_schedule_on_exec_ctx);
1617
- stream_op->recv_message_ready = &call->receiving_stream_ready;
1650
+ stream_op_payload->recv_message.recv_message_ready =
1651
+ &call->receiving_stream_ready;
1618
1652
  num_completion_callbacks_needed++;
1619
1653
  break;
1620
1654
  case GRPC_OP_RECV_STATUS_ON_CLIENT:
@@ -1631,16 +1665,17 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1631
1665
  error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
1632
1666
  goto done_with_error;
1633
1667
  }
1634
- call->requested_final_op = 1;
1668
+ call->requested_final_op = true;
1635
1669
  call->buffered_metadata[1] =
1636
1670
  op->data.recv_status_on_client.trailing_metadata;
1637
1671
  call->final_op.client.status = op->data.recv_status_on_client.status;
1638
1672
  call->final_op.client.status_details =
1639
1673
  op->data.recv_status_on_client.status_details;
1640
- bctl->recv_final_op = 1;
1641
- stream_op->recv_trailing_metadata =
1674
+ stream_op->recv_trailing_metadata = true;
1675
+ stream_op->collect_stats = true;
1676
+ stream_op_payload->recv_trailing_metadata.recv_trailing_metadata =
1642
1677
  &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
1643
- stream_op->collect_stats =
1678
+ stream_op_payload->collect_stats.collect_stats =
1644
1679
  &call->final_info.stats.transport_stream_stats;
1645
1680
  break;
1646
1681
  case GRPC_OP_RECV_CLOSE_ON_SERVER:
@@ -1657,13 +1692,14 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1657
1692
  error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
1658
1693
  goto done_with_error;
1659
1694
  }
1660
- call->requested_final_op = 1;
1695
+ call->requested_final_op = true;
1661
1696
  call->final_op.server.cancelled =
1662
1697
  op->data.recv_close_on_server.cancelled;
1663
- bctl->recv_final_op = 1;
1664
- stream_op->recv_trailing_metadata =
1698
+ stream_op->recv_trailing_metadata = true;
1699
+ stream_op->collect_stats = true;
1700
+ stream_op_payload->recv_trailing_metadata.recv_trailing_metadata =
1665
1701
  &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
1666
- stream_op->collect_stats =
1702
+ stream_op_payload->collect_stats.collect_stats =
1667
1703
  &call->final_info.stats.transport_stream_stats;
1668
1704
  break;
1669
1705
  }
@@ -1675,12 +1711,10 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
1675
1711
  }
1676
1712
  gpr_ref_init(&bctl->steps_to_complete, num_completion_callbacks_needed);
1677
1713
 
1678
- stream_op->context = call->context;
1679
1714
  grpc_closure_init(&bctl->finish_batch, finish_batch, bctl,
1680
1715
  grpc_schedule_on_exec_ctx);
1681
1716
  stream_op->on_complete = &bctl->finish_batch;
1682
- call->sent_any_op = true;
1683
- gpr_mu_unlock(&call->mu);
1717
+ gpr_atm_rel_store(&call->any_ops_sent_atm, 1);
1684
1718
 
1685
1719
  execute_op(exec_ctx, call, stream_op);
1686
1720
 
@@ -1690,28 +1724,27 @@ done:
1690
1724
 
1691
1725
  done_with_error:
1692
1726
  /* reverse any mutations that occured */
1693
- if (bctl->send_initial_metadata) {
1694
- call->sent_initial_metadata = 0;
1727
+ if (stream_op->send_initial_metadata) {
1728
+ call->sent_initial_metadata = false;
1695
1729
  grpc_metadata_batch_clear(exec_ctx, &call->metadata_batch[0][0]);
1696
1730
  }
1697
- if (bctl->send_message) {
1698
- call->sending_message = 0;
1731
+ if (stream_op->send_message) {
1732
+ call->sending_message = false;
1699
1733
  grpc_byte_stream_destroy(exec_ctx, &call->sending_stream.base);
1700
1734
  }
1701
- if (bctl->send_final_op) {
1702
- call->sent_final_op = 0;
1735
+ if (stream_op->send_trailing_metadata) {
1736
+ call->sent_final_op = false;
1703
1737
  grpc_metadata_batch_clear(exec_ctx, &call->metadata_batch[0][1]);
1704
1738
  }
1705
- if (bctl->recv_initial_metadata) {
1706
- call->received_initial_metadata = 0;
1739
+ if (stream_op->recv_initial_metadata) {
1740
+ call->received_initial_metadata = false;
1707
1741
  }
1708
- if (bctl->recv_message) {
1709
- call->receiving_message = 0;
1742
+ if (stream_op->recv_message) {
1743
+ call->receiving_message = false;
1710
1744
  }
1711
- if (bctl->recv_final_op) {
1712
- call->requested_final_op = 0;
1745
+ if (stream_op->recv_trailing_metadata) {
1746
+ call->requested_final_op = false;
1713
1747
  }
1714
- gpr_mu_unlock(&call->mu);
1715
1748
  goto done;
1716
1749
  }
1717
1750
 
@@ -1760,10 +1793,8 @@ uint8_t grpc_call_is_client(grpc_call *call) { return call->is_client; }
1760
1793
 
1761
1794
  grpc_compression_algorithm grpc_call_compression_for_level(
1762
1795
  grpc_call *call, grpc_compression_level level) {
1763
- gpr_mu_lock(&call->mu);
1764
1796
  grpc_compression_algorithm algo =
1765
1797
  compression_algorithm_for_level_locked(call, level);
1766
- gpr_mu_unlock(&call->mu);
1767
1798
  return algo;
1768
1799
  }
1769
1800