grpc 1.6.7 → 1.7.0.pre1

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 (277) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +579 -77
  3. data/include/grpc/byte_buffer.h +1 -63
  4. data/include/grpc/compression.h +27 -5
  5. data/include/grpc/fork.h +24 -0
  6. data/include/grpc/grpc.h +12 -6
  7. data/include/grpc/grpc_security.h +28 -7
  8. data/include/grpc/impl/codegen/atm.h +1 -0
  9. data/include/grpc/impl/codegen/byte_buffer.h +86 -0
  10. data/include/grpc/impl/codegen/compression_types.h +63 -5
  11. data/include/grpc/impl/codegen/fork.h +48 -0
  12. data/include/grpc/impl/codegen/grpc_types.h +26 -9
  13. data/include/grpc/impl/codegen/port_platform.h +11 -4
  14. data/include/grpc/impl/codegen/slice.h +6 -1
  15. data/include/grpc/impl/codegen/sync.h +3 -1
  16. data/include/grpc/impl/codegen/sync_custom.h +36 -0
  17. data/include/grpc/module.modulemap +75 -3
  18. data/include/grpc/slice.h +1 -5
  19. data/include/grpc/support/sync_custom.h +24 -0
  20. data/src/core/ext/census/base_resources.c +14 -14
  21. data/src/core/ext/census/context.c +7 -5
  22. data/src/core/ext/census/grpc_filter.c +12 -14
  23. data/src/core/ext/census/mlog.c +2 -1
  24. data/src/core/ext/census/resource.c +13 -9
  25. data/src/core/ext/filters/client_channel/channel_connectivity.c +15 -8
  26. data/src/core/ext/filters/client_channel/client_channel.c +418 -439
  27. data/src/core/ext/filters/client_channel/client_channel_factory.c +4 -5
  28. data/src/core/ext/filters/client_channel/client_channel_plugin.c +2 -2
  29. data/src/core/ext/filters/client_channel/http_connect_handshaker.c +7 -5
  30. data/src/core/ext/filters/client_channel/http_proxy.c +17 -21
  31. data/src/core/ext/filters/client_channel/lb_policy.c +1 -1
  32. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c +7 -7
  33. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c +371 -257
  34. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c +7 -5
  35. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c +25 -14
  36. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c +16 -16
  37. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c +33 -28
  38. data/src/core/ext/filters/client_channel/lb_policy_factory.c +10 -8
  39. data/src/core/ext/filters/client_channel/lb_policy_factory.h +1 -1
  40. data/src/core/ext/filters/client_channel/proxy_mapper_registry.c +1 -1
  41. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c +7 -6
  42. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c +62 -28
  43. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c +29 -23
  44. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c +25 -14
  45. data/src/core/ext/filters/client_channel/retry_throttle.c +9 -6
  46. data/src/core/ext/filters/client_channel/subchannel.c +30 -30
  47. data/src/core/ext/filters/client_channel/subchannel.h +1 -4
  48. data/src/core/ext/filters/client_channel/subchannel_index.c +31 -15
  49. data/src/core/ext/filters/client_channel/subchannel_index.h +7 -0
  50. data/src/core/ext/filters/client_channel/uri_parser.c +4 -3
  51. data/src/core/ext/filters/deadline/deadline_filter.c +78 -39
  52. data/src/core/ext/filters/deadline/deadline_filter.h +7 -1
  53. data/src/core/ext/filters/http/client/http_client_filter.c +14 -14
  54. data/src/core/ext/filters/http/http_filters_plugin.c +1 -1
  55. data/src/core/ext/filters/http/message_compress/message_compress_filter.c +240 -175
  56. data/src/core/ext/filters/http/server/http_server_filter.c +48 -36
  57. data/src/core/ext/filters/load_reporting/{load_reporting_filter.c → server_load_reporting_filter.c} +11 -12
  58. data/src/core/ext/filters/load_reporting/{load_reporting_filter.h → server_load_reporting_filter.h} +6 -5
  59. data/src/core/ext/filters/load_reporting/{load_reporting.c → server_load_reporting_plugin.c} +19 -13
  60. data/src/core/ext/filters/load_reporting/{load_reporting.h → server_load_reporting_plugin.h} +4 -3
  61. data/src/core/ext/filters/max_age/max_age_filter.c +2 -3
  62. data/src/core/ext/filters/message_size/message_size_filter.c +4 -2
  63. data/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c +0 -1
  64. data/src/core/ext/transport/chttp2/client/chttp2_connector.c +5 -5
  65. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +1 -1
  66. data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c +1 -1
  67. data/src/core/ext/transport/chttp2/server/chttp2_server.c +20 -18
  68. data/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +1 -0
  69. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +493 -210
  70. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +1 -0
  71. data/src/core/ext/transport/chttp2/transport/flow_control.c +9 -8
  72. data/src/core/ext/transport/chttp2/transport/frame_data.c +2 -2
  73. data/src/core/ext/transport/chttp2/transport/frame_goaway.c +2 -2
  74. data/src/core/ext/transport/chttp2/transport/frame_ping.c +5 -4
  75. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +1 -1
  76. data/src/core/ext/transport/chttp2/transport/frame_settings.c +10 -9
  77. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +9 -5
  78. data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +62 -41
  79. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +52 -8
  80. data/src/core/ext/transport/chttp2/transport/hpack_table.c +2 -2
  81. data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +3 -2
  82. data/src/core/ext/transport/chttp2/transport/internal.h +60 -30
  83. data/src/core/ext/transport/chttp2/transport/parsing.c +16 -5
  84. data/src/core/ext/transport/chttp2/transport/stream_lists.c +36 -16
  85. data/src/core/ext/transport/chttp2/transport/stream_map.c +6 -4
  86. data/src/core/ext/transport/chttp2/transport/writing.c +133 -105
  87. data/src/core/ext/transport/inproc/inproc_transport.c +61 -65
  88. data/src/core/lib/channel/channel_args.c +112 -12
  89. data/src/core/lib/channel/channel_args.h +31 -0
  90. data/src/core/lib/channel/channel_stack.c +1 -15
  91. data/src/core/lib/channel/channel_stack.h +3 -10
  92. data/src/core/lib/channel/channel_stack_builder.c +41 -10
  93. data/src/core/lib/channel/channel_stack_builder.h +10 -0
  94. data/src/core/lib/channel/connected_channel.c +94 -23
  95. data/src/core/lib/channel/handshaker.c +8 -6
  96. data/src/core/lib/channel/handshaker_registry.c +1 -1
  97. data/src/core/lib/compression/algorithm_metadata.h +14 -0
  98. data/src/core/lib/compression/compression.c +101 -1
  99. data/src/core/lib/compression/stream_compression.c +32 -146
  100. data/src/core/lib/compression/stream_compression.h +28 -4
  101. data/src/core/lib/compression/stream_compression_gzip.c +228 -0
  102. data/src/core/lib/{iomgr/ev_epoll_thread_pool_linux.h → compression/stream_compression_gzip.h} +5 -7
  103. data/src/core/lib/compression/stream_compression_identity.c +94 -0
  104. data/src/core/lib/{iomgr/ev_epoll_limited_pollers_linux.h → compression/stream_compression_identity.h} +7 -8
  105. data/src/core/lib/debug/stats.c +174 -0
  106. data/src/core/lib/debug/stats.h +61 -0
  107. data/src/core/lib/debug/stats_data.c +687 -0
  108. data/src/core/lib/debug/stats_data.h +470 -0
  109. data/src/core/lib/debug/trace.c +3 -3
  110. data/src/core/lib/debug/trace.h +1 -1
  111. data/src/core/lib/http/format_request.c +1 -1
  112. data/src/core/lib/http/httpcli.c +8 -7
  113. data/src/core/lib/http/httpcli_security_connector.c +2 -1
  114. data/src/core/lib/http/parser.c +4 -3
  115. data/src/core/lib/iomgr/call_combiner.c +202 -0
  116. data/src/core/lib/iomgr/call_combiner.h +121 -0
  117. data/src/core/lib/iomgr/closure.c +18 -4
  118. data/src/core/lib/iomgr/combiner.c +11 -4
  119. data/src/core/lib/iomgr/error.c +26 -24
  120. data/src/core/lib/iomgr/ev_epoll1_linux.c +395 -212
  121. data/src/core/lib/iomgr/ev_epollex_linux.c +141 -128
  122. data/src/core/lib/iomgr/ev_epollsig_linux.c +44 -41
  123. data/src/core/lib/iomgr/ev_poll_posix.c +99 -75
  124. data/src/core/lib/iomgr/ev_posix.c +5 -9
  125. data/src/core/lib/iomgr/ev_posix.h +1 -1
  126. data/src/core/lib/iomgr/exec_ctx.h +6 -1
  127. data/src/core/lib/iomgr/executor.c +142 -36
  128. data/src/core/lib/iomgr/executor.h +6 -1
  129. data/src/core/lib/iomgr/fork_posix.c +88 -0
  130. data/src/core/lib/iomgr/fork_windows.c +39 -0
  131. data/src/core/lib/iomgr/iocp_windows.c +2 -0
  132. data/src/core/lib/iomgr/iomgr.c +2 -8
  133. data/src/core/lib/iomgr/is_epollexclusive_available.c +6 -6
  134. data/src/core/lib/iomgr/load_file.c +2 -1
  135. data/src/core/lib/iomgr/polling_entity.c +9 -9
  136. data/src/core/lib/iomgr/polling_entity.h +7 -1
  137. data/src/core/lib/iomgr/pollset.h +1 -1
  138. data/src/core/lib/iomgr/pollset_uv.c +1 -1
  139. data/src/core/lib/iomgr/pollset_windows.c +3 -3
  140. data/src/core/lib/iomgr/port.h +4 -0
  141. data/src/core/lib/iomgr/resolve_address_posix.c +8 -7
  142. data/src/core/lib/iomgr/resolve_address_windows.c +1 -1
  143. data/src/core/lib/iomgr/resource_quota.c +24 -19
  144. data/src/core/lib/iomgr/socket_factory_posix.c +4 -4
  145. data/src/core/lib/iomgr/socket_mutator.c +4 -4
  146. data/src/core/lib/iomgr/socket_utils_windows.c +0 -4
  147. data/src/core/lib/iomgr/tcp_client_posix.c +5 -4
  148. data/src/core/lib/iomgr/tcp_posix.c +181 -20
  149. data/src/core/lib/iomgr/tcp_server_posix.c +8 -7
  150. data/src/core/lib/iomgr/tcp_server_utils_posix_common.c +1 -1
  151. data/src/core/lib/iomgr/timer.h +4 -0
  152. data/src/core/lib/iomgr/timer_generic.c +138 -3
  153. data/src/core/lib/iomgr/timer_generic.h +3 -0
  154. data/src/core/lib/iomgr/timer_heap.c +4 -4
  155. data/src/core/lib/iomgr/timer_manager.c +2 -2
  156. data/src/core/lib/iomgr/timer_uv.c +2 -0
  157. data/src/core/lib/iomgr/udp_server.c +10 -8
  158. data/src/core/lib/iomgr/unix_sockets_posix.c +4 -2
  159. data/src/core/lib/iomgr/wakeup_fd_cv.c +9 -8
  160. data/src/core/lib/iomgr/wakeup_fd_cv.h +2 -2
  161. data/src/core/lib/json/json.c +1 -1
  162. data/src/core/lib/json/json_string.c +13 -13
  163. data/src/core/lib/profiling/timers.h +18 -8
  164. data/src/core/lib/security/credentials/composite/composite_credentials.c +4 -10
  165. data/src/core/lib/security/credentials/google_default/google_default_credentials.c +2 -1
  166. data/src/core/lib/security/credentials/jwt/jwt_verifier.c +11 -6
  167. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +4 -4
  168. data/src/core/lib/security/credentials/plugin/plugin_credentials.c +132 -50
  169. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +2 -0
  170. data/src/core/lib/security/transport/client_auth_filter.c +68 -135
  171. data/src/core/lib/security/transport/secure_endpoint.c +110 -90
  172. data/src/core/lib/security/transport/secure_endpoint.h +8 -3
  173. data/src/core/lib/security/transport/security_connector.c +10 -12
  174. data/src/core/lib/security/transport/security_handshaker.c +45 -24
  175. data/src/core/lib/security/transport/server_auth_filter.c +71 -20
  176. data/src/core/lib/slice/b64.c +2 -2
  177. data/src/core/lib/slice/slice.c +16 -14
  178. data/src/core/lib/slice/slice_buffer.c +5 -4
  179. data/src/core/lib/slice/slice_hash_table.c +3 -2
  180. data/src/core/lib/slice/slice_intern.c +8 -5
  181. data/src/core/lib/support/block_annotate.h +22 -0
  182. data/src/core/lib/support/fork.c +62 -0
  183. data/src/core/lib/support/fork.h +35 -0
  184. data/src/core/lib/support/log_linux.c +1 -1
  185. data/src/core/lib/support/string.c +15 -1
  186. data/src/core/lib/support/string.h +3 -0
  187. data/src/core/lib/support/thd_internal.h +6 -0
  188. data/src/core/lib/support/thd_posix.c +56 -0
  189. data/src/core/lib/support/thd_windows.c +2 -0
  190. data/src/core/lib/surface/alarm.c +22 -15
  191. data/src/core/lib/surface/byte_buffer.c +4 -2
  192. data/src/core/lib/surface/call.c +442 -141
  193. data/src/core/lib/surface/call.h +6 -6
  194. data/src/core/lib/surface/call_log_batch.c +1 -1
  195. data/src/core/lib/surface/call_test_only.h +12 -0
  196. data/src/core/lib/surface/channel.c +39 -4
  197. data/src/core/lib/surface/channel_init.c +6 -6
  198. data/src/core/lib/surface/channel_ping.c +2 -2
  199. data/src/core/lib/surface/completion_queue.c +56 -57
  200. data/src/core/lib/surface/init.c +17 -3
  201. data/src/core/lib/surface/init_secure.c +5 -1
  202. data/src/core/lib/surface/lame_client.cc +9 -10
  203. data/src/core/lib/surface/server.c +81 -72
  204. data/src/core/lib/surface/version.c +2 -2
  205. data/src/core/lib/transport/byte_stream.c +1 -0
  206. data/src/core/lib/transport/byte_stream.h +3 -1
  207. data/src/core/lib/transport/connectivity_state.c +2 -1
  208. data/src/core/lib/transport/metadata.c +7 -4
  209. data/src/core/lib/transport/metadata_batch.c +18 -16
  210. data/src/core/lib/transport/metadata_batch.h +1 -0
  211. data/src/core/lib/transport/service_config.c +5 -3
  212. data/src/core/lib/transport/static_metadata.c +395 -614
  213. data/src/core/lib/transport/static_metadata.h +165 -133
  214. data/src/core/lib/transport/status_conversion.c +1 -1
  215. data/src/core/lib/transport/transport.c +20 -20
  216. data/src/core/lib/transport/transport.h +8 -5
  217. data/src/core/lib/transport/transport_impl.h +0 -3
  218. data/src/core/lib/transport/transport_op_string.c +8 -1
  219. data/src/core/plugin_registry/grpc_plugin_registry.c +4 -4
  220. data/src/core/tsi/fake_transport_security.c +133 -2
  221. data/src/core/tsi/fake_transport_security.h +5 -0
  222. data/src/core/tsi/ssl_transport_security.c +105 -8
  223. data/src/core/tsi/ssl_transport_security.h +30 -7
  224. data/src/core/tsi/transport_security.h +8 -2
  225. data/src/core/tsi/transport_security_grpc.c +20 -13
  226. data/src/core/tsi/transport_security_grpc.h +13 -9
  227. data/src/ruby/ext/grpc/rb_call_credentials.c +6 -2
  228. data/src/ruby/ext/grpc/rb_grpc.c +1 -1
  229. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +30 -20
  230. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +50 -35
  231. data/src/ruby/lib/grpc.rb +1 -0
  232. data/src/ruby/lib/grpc/generic/active_call.rb +34 -9
  233. data/src/ruby/lib/grpc/generic/bidi_call.rb +19 -10
  234. data/src/ruby/lib/grpc/generic/client_stub.rb +95 -38
  235. data/src/ruby/lib/grpc/generic/interceptor_registry.rb +53 -0
  236. data/src/ruby/lib/grpc/generic/interceptors.rb +186 -0
  237. data/src/ruby/lib/grpc/generic/rpc_desc.rb +66 -20
  238. data/src/ruby/lib/grpc/generic/rpc_server.rb +15 -3
  239. data/src/ruby/lib/grpc/google_rpc_status_utils.rb +1 -2
  240. data/src/ruby/lib/grpc/version.rb +1 -1
  241. data/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services_pb.rb +1 -0
  242. data/src/ruby/spec/channel_connection_spec.rb +1 -34
  243. data/src/ruby/spec/client_server_spec.rb +188 -82
  244. data/src/ruby/spec/generic/active_call_spec.rb +65 -11
  245. data/src/ruby/spec/generic/client_interceptors_spec.rb +153 -0
  246. data/src/ruby/spec/generic/interceptor_registry_spec.rb +65 -0
  247. data/src/ruby/spec/generic/rpc_desc_spec.rb +38 -0
  248. data/src/ruby/spec/generic/rpc_server_spec.rb +1 -34
  249. data/src/ruby/spec/generic/server_interceptors_spec.rb +218 -0
  250. data/src/ruby/spec/spec_helper.rb +4 -0
  251. data/src/ruby/spec/support/helpers.rb +73 -0
  252. data/src/ruby/spec/support/services.rb +147 -0
  253. data/third_party/cares/ares_build.h +21 -62
  254. data/third_party/cares/cares/ares.h +23 -1
  255. data/third_party/cares/cares/ares__close_sockets.c +2 -2
  256. data/third_party/cares/cares/ares_create_query.c +3 -3
  257. data/third_party/cares/cares/ares_expand_name.c +6 -2
  258. data/third_party/cares/cares/ares_expand_string.c +1 -1
  259. data/third_party/cares/cares/ares_getnameinfo.c +27 -7
  260. data/third_party/cares/cares/ares_init.c +407 -39
  261. data/third_party/cares/cares/ares_library_init.c +10 -0
  262. data/third_party/cares/cares/ares_library_init.h +2 -1
  263. data/third_party/cares/cares/ares_nowarn.c +6 -6
  264. data/third_party/cares/cares/ares_nowarn.h +2 -2
  265. data/third_party/cares/cares/ares_parse_naptr_reply.c +6 -1
  266. data/third_party/cares/cares/ares_private.h +11 -0
  267. data/third_party/cares/cares/ares_process.c +126 -37
  268. data/third_party/cares/cares/ares_version.h +2 -2
  269. data/third_party/cares/cares/ares_writev.c +2 -2
  270. data/third_party/cares/cares/config-win32.h +8 -34
  271. data/third_party/cares/cares/inet_net_pton.c +2 -2
  272. data/third_party/cares/cares/setup_once.h +5 -5
  273. data/third_party/cares/config_darwin/ares_config.h +98 -196
  274. data/third_party/cares/config_linux/ares_config.h +103 -203
  275. metadata +47 -20
  276. data/src/core/lib/iomgr/ev_epoll_limited_pollers_linux.c +0 -1957
  277. data/src/core/lib/iomgr/ev_epoll_thread_pool_linux.c +0 -1182
@@ -37,7 +37,8 @@ void gpr_timers_set_log_filename(const char *filename);
37
37
 
38
38
  void gpr_timer_set_enabled(int enabled);
39
39
 
40
- #if !(defined(GRPC_STAP_PROFILER) + defined(GRPC_BASIC_PROFILER))
40
+ #if !(defined(GRPC_STAP_PROFILER) + defined(GRPC_BASIC_PROFILER) + \
41
+ defined(GRPC_CUSTOM_PROFILER))
41
42
  /* No profiling. No-op all the things. */
42
43
  #define GPR_TIMER_MARK(tag, important) \
43
44
  do { \
@@ -56,6 +57,12 @@ void gpr_timer_set_enabled(int enabled);
56
57
  #if defined(GRPC_STAP_PROFILER) && defined(GRPC_BASIC_PROFILER)
57
58
  #error "GRPC_STAP_PROFILER and GRPC_BASIC_PROFILER are mutually exclusive."
58
59
  #endif
60
+ #if defined(GRPC_STAP_PROFILER) && defined(GRPC_CUSTOM_PROFILER)
61
+ #error "GRPC_STAP_PROFILER and GRPC_CUSTOM_PROFILER are mutually exclusive."
62
+ #endif
63
+ #if defined(GRPC_CUSTOM_PROFILER) && defined(GRPC_BASIC_PROFILER)
64
+ #error "GRPC_CUSTOM_PROFILER and GRPC_BASIC_PROFILER are mutually exclusive."
65
+ #endif
59
66
 
60
67
  /* Generic profiling interface. */
61
68
  #define GPR_TIMER_MARK(tag, important) \
@@ -80,22 +87,25 @@ void gpr_timer_set_enabled(int enabled);
80
87
  #ifdef __cplusplus
81
88
  }
82
89
 
83
- #if (defined(GRPC_STAP_PROFILER) + defined(GRPC_BASIC_PROFILER))
90
+ #if (defined(GRPC_STAP_PROFILER) + defined(GRPC_BASIC_PROFILER) + \
91
+ defined(GRPC_CUSTOM_PROFILER))
84
92
  namespace grpc {
85
93
  class ProfileScope {
86
94
  public:
87
- ProfileScope(const char *desc, bool important) : desc_(desc) {
88
- GPR_TIMER_BEGIN(desc_, important ? 1 : 0);
95
+ ProfileScope(const char *desc, bool important, const char *file, int line)
96
+ : desc_(desc) {
97
+ gpr_timer_begin(desc_, important ? 1 : 0, file, line);
89
98
  }
90
- ~ProfileScope() { GPR_TIMER_END(desc_, 0); }
99
+ ~ProfileScope() { gpr_timer_end(desc_, 0, "n/a", 0); }
91
100
 
92
101
  private:
93
102
  const char *const desc_;
94
103
  };
95
- }
104
+ } // namespace grpc
96
105
 
97
- #define GPR_TIMER_SCOPE(tag, important) \
98
- ::grpc::ProfileScope _profile_scope_##__LINE__((tag), (important))
106
+ #define GPR_TIMER_SCOPE(tag, important) \
107
+ ::grpc::ProfileScope _profile_scope_##__LINE__((tag), (important), __FILE__, \
108
+ __LINE__)
99
109
  #else
100
110
  #define GPR_TIMER_SCOPE(tag, important) \
101
111
  do { \
@@ -87,6 +87,7 @@ static bool composite_call_get_request_metadata(
87
87
  ctx->on_request_metadata = on_request_metadata;
88
88
  GRPC_CLOSURE_INIT(&ctx->internal_on_request_metadata,
89
89
  composite_call_metadata_cb, ctx, grpc_schedule_on_exec_ctx);
90
+ bool synchronous = true;
90
91
  while (ctx->creds_index < ctx->composite_creds->inner.num_creds) {
91
92
  grpc_call_credentials *inner_creds =
92
93
  ctx->composite_creds->inner.creds_array[ctx->creds_index++];
@@ -95,19 +96,12 @@ static bool composite_call_get_request_metadata(
95
96
  ctx->md_array, &ctx->internal_on_request_metadata, error)) {
96
97
  if (*error != GRPC_ERROR_NONE) break;
97
98
  } else {
99
+ synchronous = false; // Async return.
98
100
  break;
99
101
  }
100
102
  }
101
- // If we got through all creds synchronously or we got a synchronous
102
- // error on one of them, return synchronously.
103
- if (ctx->creds_index == ctx->composite_creds->inner.num_creds ||
104
- *error != GRPC_ERROR_NONE) {
105
- gpr_free(ctx);
106
- return true;
107
- }
108
- // At least one inner cred is returning asynchronously, so we'll
109
- // return asynchronously as well.
110
- return false;
103
+ if (synchronous) gpr_free(ctx);
104
+ return synchronous;
111
105
  }
112
106
 
113
107
  static void composite_call_cancel_get_request_metadata(
@@ -79,7 +79,8 @@ static void on_compute_engine_detection_http_response(grpc_exec_ctx *exec_ctx,
79
79
  detector->is_done = 1;
80
80
  GRPC_LOG_IF_ERROR(
81
81
  "Pollset kick",
82
- grpc_pollset_kick(grpc_polling_entity_pollset(&detector->pollent), NULL));
82
+ grpc_pollset_kick(exec_ctx,
83
+ grpc_polling_entity_pollset(&detector->pollent), NULL));
83
84
  gpr_mu_unlock(g_polling_mu);
84
85
  }
85
86
 
@@ -442,7 +442,7 @@ static EVP_PKEY *extract_pkey_from_x509(const char *x509_str) {
442
442
 
443
443
  end:
444
444
  BIO_free(bio);
445
- if (x509 != NULL) X509_free(x509);
445
+ X509_free(x509);
446
446
  return result;
447
447
  }
448
448
 
@@ -496,6 +496,8 @@ static EVP_PKEY *pkey_from_jwk(grpc_exec_ctx *exec_ctx, const grpc_json *json,
496
496
  const grpc_json *key_prop;
497
497
  RSA *rsa = NULL;
498
498
  EVP_PKEY *result = NULL;
499
+ BIGNUM *tmp_n = NULL;
500
+ BIGNUM *tmp_e = NULL;
499
501
 
500
502
  GPR_ASSERT(kty != NULL && json != NULL);
501
503
  if (strcmp(kty, "RSA") != 0) {
@@ -507,8 +509,6 @@ static EVP_PKEY *pkey_from_jwk(grpc_exec_ctx *exec_ctx, const grpc_json *json,
507
509
  gpr_log(GPR_ERROR, "Could not create rsa key.");
508
510
  goto end;
509
511
  }
510
- BIGNUM *tmp_n = NULL;
511
- BIGNUM *tmp_e = NULL;
512
512
  for (key_prop = json->child; key_prop != NULL; key_prop = key_prop->next) {
513
513
  if (strcmp(key_prop->key, "n") == 0) {
514
514
  tmp_n =
@@ -528,11 +528,16 @@ static EVP_PKEY *pkey_from_jwk(grpc_exec_ctx *exec_ctx, const grpc_json *json,
528
528
  gpr_log(GPR_ERROR, "Cannot set RSA key from inputs.");
529
529
  goto end;
530
530
  }
531
+ /* RSA_set0_key takes ownership on success. */
532
+ tmp_n = NULL;
533
+ tmp_e = NULL;
531
534
  result = EVP_PKEY_new();
532
535
  EVP_PKEY_set1_RSA(result, rsa); /* uprefs rsa. */
533
536
 
534
537
  end:
535
- if (rsa != NULL) RSA_free(rsa);
538
+ RSA_free(rsa);
539
+ BN_free(tmp_n);
540
+ BN_free(tmp_e);
536
541
  return result;
537
542
  }
538
543
 
@@ -618,7 +623,7 @@ static int verify_jwt_signature(EVP_PKEY *key, const char *alg,
618
623
  result = 1;
619
624
 
620
625
  end:
621
- if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx);
626
+ EVP_MD_CTX_destroy(md_ctx);
622
627
  return result;
623
628
  }
624
629
 
@@ -658,7 +663,7 @@ static void on_keys_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
658
663
 
659
664
  end:
660
665
  if (json != NULL) grpc_json_destroy(json);
661
- if (verification_key != NULL) EVP_PKEY_free(verification_key);
666
+ EVP_PKEY_free(verification_key);
662
667
  ctx->user_cb(exec_ctx, ctx->user_data, status, claims);
663
668
  verifier_cb_ctx_destroy(exec_ctx, ctx);
664
669
  }
@@ -296,10 +296,10 @@ static bool oauth2_token_fetcher_get_request_metadata(
296
296
  gpr_mu_unlock(&c->mu);
297
297
  if (start_fetch) {
298
298
  grpc_call_credentials_ref(creds);
299
- c->fetch_func(exec_ctx, grpc_credentials_metadata_request_create(creds),
300
- &c->httpcli_context, &c->pollent,
301
- on_oauth2_token_fetcher_http_response,
302
- gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), refresh_threshold));
299
+ c->fetch_func(
300
+ exec_ctx, grpc_credentials_metadata_request_create(creds),
301
+ &c->httpcli_context, &c->pollent, on_oauth2_token_fetcher_http_response,
302
+ gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), refresh_threshold));
303
303
  }
304
304
  return false;
305
305
  }
@@ -31,6 +31,9 @@
31
31
  #include "src/core/lib/surface/api_trace.h"
32
32
  #include "src/core/lib/surface/validate_metadata.h"
33
33
 
34
+ grpc_tracer_flag grpc_plugin_credentials_trace =
35
+ GRPC_TRACER_INITIALIZER(false, "plugin_credentials");
36
+
34
37
  static void plugin_destruct(grpc_exec_ctx *exec_ctx,
35
38
  grpc_call_credentials *creds) {
36
39
  grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds;
@@ -53,6 +56,62 @@ static void pending_request_remove_locked(
53
56
  }
54
57
  }
55
58
 
59
+ // Checks if the request has been cancelled.
60
+ // If not, removes it from the pending list, so that it cannot be
61
+ // cancelled out from under us.
62
+ // When this returns, r->cancelled indicates whether the request was
63
+ // cancelled before completion.
64
+ static void pending_request_complete(
65
+ grpc_exec_ctx *exec_ctx, grpc_plugin_credentials_pending_request *r) {
66
+ gpr_mu_lock(&r->creds->mu);
67
+ if (!r->cancelled) pending_request_remove_locked(r->creds, r);
68
+ gpr_mu_unlock(&r->creds->mu);
69
+ // Ref to credentials not needed anymore.
70
+ grpc_call_credentials_unref(exec_ctx, &r->creds->base);
71
+ }
72
+
73
+ static grpc_error *process_plugin_result(
74
+ grpc_exec_ctx *exec_ctx, grpc_plugin_credentials_pending_request *r,
75
+ const grpc_metadata *md, size_t num_md, grpc_status_code status,
76
+ const char *error_details) {
77
+ grpc_error *error = GRPC_ERROR_NONE;
78
+ if (status != GRPC_STATUS_OK) {
79
+ char *msg;
80
+ gpr_asprintf(&msg, "Getting metadata from plugin failed with error: %s",
81
+ error_details);
82
+ error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
83
+ gpr_free(msg);
84
+ } else {
85
+ bool seen_illegal_header = false;
86
+ for (size_t i = 0; i < num_md; ++i) {
87
+ if (!GRPC_LOG_IF_ERROR("validate_metadata_from_plugin",
88
+ grpc_validate_header_key_is_legal(md[i].key))) {
89
+ seen_illegal_header = true;
90
+ break;
91
+ } else if (!grpc_is_binary_header(md[i].key) &&
92
+ !GRPC_LOG_IF_ERROR(
93
+ "validate_metadata_from_plugin",
94
+ grpc_validate_header_nonbin_value_is_legal(md[i].value))) {
95
+ gpr_log(GPR_ERROR, "Plugin added invalid metadata value.");
96
+ seen_illegal_header = true;
97
+ break;
98
+ }
99
+ }
100
+ if (seen_illegal_header) {
101
+ error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal metadata");
102
+ } else {
103
+ for (size_t i = 0; i < num_md; ++i) {
104
+ grpc_mdelem mdelem = grpc_mdelem_from_slices(
105
+ exec_ctx, grpc_slice_ref_internal(md[i].key),
106
+ grpc_slice_ref_internal(md[i].value));
107
+ grpc_credentials_mdelem_array_add(r->md_array, mdelem);
108
+ GRPC_MDELEM_UNREF(exec_ctx, mdelem);
109
+ }
110
+ }
111
+ }
112
+ return error;
113
+ }
114
+
56
115
  static void plugin_md_request_metadata_ready(void *request,
57
116
  const grpc_metadata *md,
58
117
  size_t num_md,
@@ -64,54 +123,24 @@ static void plugin_md_request_metadata_ready(void *request,
64
123
  NULL, NULL);
65
124
  grpc_plugin_credentials_pending_request *r =
66
125
  (grpc_plugin_credentials_pending_request *)request;
67
- // Check if the request has been cancelled.
68
- // If not, remove it from the pending list, so that it cannot be
69
- // cancelled out from under us.
70
- gpr_mu_lock(&r->creds->mu);
71
- if (!r->cancelled) pending_request_remove_locked(r->creds, r);
72
- gpr_mu_unlock(&r->creds->mu);
73
- grpc_call_credentials_unref(&exec_ctx, &r->creds->base);
126
+ if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
127
+ gpr_log(GPR_INFO,
128
+ "plugin_credentials[%p]: request %p: plugin returned "
129
+ "asynchronously",
130
+ r->creds, r);
131
+ }
132
+ // Remove request from pending list if not previously cancelled.
133
+ pending_request_complete(&exec_ctx, r);
74
134
  // If it has not been cancelled, process it.
75
135
  if (!r->cancelled) {
76
- if (status != GRPC_STATUS_OK) {
77
- char *msg;
78
- gpr_asprintf(&msg, "Getting metadata from plugin failed with error: %s",
79
- error_details);
80
- GRPC_CLOSURE_SCHED(&exec_ctx, r->on_request_metadata,
81
- GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg));
82
- gpr_free(msg);
83
- } else {
84
- bool seen_illegal_header = false;
85
- for (size_t i = 0; i < num_md; ++i) {
86
- if (!GRPC_LOG_IF_ERROR("validate_metadata_from_plugin",
87
- grpc_validate_header_key_is_legal(md[i].key))) {
88
- seen_illegal_header = true;
89
- break;
90
- } else if (!grpc_is_binary_header(md[i].key) &&
91
- !GRPC_LOG_IF_ERROR(
92
- "validate_metadata_from_plugin",
93
- grpc_validate_header_nonbin_value_is_legal(
94
- md[i].value))) {
95
- gpr_log(GPR_ERROR, "Plugin added invalid metadata value.");
96
- seen_illegal_header = true;
97
- break;
98
- }
99
- }
100
- if (seen_illegal_header) {
101
- GRPC_CLOSURE_SCHED(
102
- &exec_ctx, r->on_request_metadata,
103
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal metadata"));
104
- } else {
105
- for (size_t i = 0; i < num_md; ++i) {
106
- grpc_mdelem mdelem = grpc_mdelem_from_slices(
107
- &exec_ctx, grpc_slice_ref_internal(md[i].key),
108
- grpc_slice_ref_internal(md[i].value));
109
- grpc_credentials_mdelem_array_add(r->md_array, mdelem);
110
- GRPC_MDELEM_UNREF(&exec_ctx, mdelem);
111
- }
112
- GRPC_CLOSURE_SCHED(&exec_ctx, r->on_request_metadata, GRPC_ERROR_NONE);
113
- }
114
- }
136
+ grpc_error *error =
137
+ process_plugin_result(&exec_ctx, r, md, num_md, status, error_details);
138
+ GRPC_CLOSURE_SCHED(&exec_ctx, r->on_request_metadata, error);
139
+ } else if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
140
+ gpr_log(GPR_INFO,
141
+ "plugin_credentials[%p]: request %p: plugin was previously "
142
+ "cancelled",
143
+ r->creds, r);
115
144
  }
116
145
  gpr_free(r);
117
146
  grpc_exec_ctx_finish(&exec_ctx);
@@ -125,6 +154,7 @@ static bool plugin_get_request_metadata(grpc_exec_ctx *exec_ctx,
125
154
  grpc_closure *on_request_metadata,
126
155
  grpc_error **error) {
127
156
  grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds;
157
+ bool retval = true; // Synchronous return.
128
158
  if (c->plugin.get_metadata != NULL) {
129
159
  // Create pending_request object.
130
160
  grpc_plugin_credentials_pending_request *pending_request =
@@ -142,12 +172,60 @@ static bool plugin_get_request_metadata(grpc_exec_ctx *exec_ctx,
142
172
  c->pending_requests = pending_request;
143
173
  gpr_mu_unlock(&c->mu);
144
174
  // Invoke the plugin. The callback holds a ref to us.
175
+ if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
176
+ gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: invoking plugin",
177
+ c, pending_request);
178
+ }
145
179
  grpc_call_credentials_ref(creds);
146
- c->plugin.get_metadata(c->plugin.state, context,
147
- plugin_md_request_metadata_ready, pending_request);
148
- return false;
180
+ grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX];
181
+ size_t num_creds_md = 0;
182
+ grpc_status_code status = GRPC_STATUS_OK;
183
+ const char *error_details = NULL;
184
+ if (!c->plugin.get_metadata(c->plugin.state, context,
185
+ plugin_md_request_metadata_ready,
186
+ pending_request, creds_md, &num_creds_md,
187
+ &status, &error_details)) {
188
+ if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
189
+ gpr_log(GPR_INFO,
190
+ "plugin_credentials[%p]: request %p: plugin will return "
191
+ "asynchronously",
192
+ c, pending_request);
193
+ }
194
+ return false; // Asynchronous return.
195
+ }
196
+ // Returned synchronously.
197
+ // Remove request from pending list if not previously cancelled.
198
+ pending_request_complete(exec_ctx, pending_request);
199
+ // If the request was cancelled, the error will have been returned
200
+ // asynchronously by plugin_cancel_get_request_metadata(), so return
201
+ // false. Otherwise, process the result.
202
+ if (pending_request->cancelled) {
203
+ if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
204
+ gpr_log(GPR_INFO,
205
+ "plugin_credentials[%p]: request %p was cancelled, error "
206
+ "will be returned asynchronously",
207
+ c, pending_request);
208
+ }
209
+ retval = false;
210
+ } else {
211
+ if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
212
+ gpr_log(GPR_INFO,
213
+ "plugin_credentials[%p]: request %p: plugin returned "
214
+ "synchronously",
215
+ c, pending_request);
216
+ }
217
+ *error = process_plugin_result(exec_ctx, pending_request, creds_md,
218
+ num_creds_md, status, error_details);
219
+ }
220
+ // Clean up.
221
+ for (size_t i = 0; i < num_creds_md; ++i) {
222
+ grpc_slice_unref_internal(exec_ctx, creds_md[i].key);
223
+ grpc_slice_unref_internal(exec_ctx, creds_md[i].value);
224
+ }
225
+ gpr_free((void *)error_details);
226
+ gpr_free(pending_request);
149
227
  }
150
- return true;
228
+ return retval;
151
229
  }
152
230
 
153
231
  static void plugin_cancel_get_request_metadata(
@@ -159,6 +237,10 @@ static void plugin_cancel_get_request_metadata(
159
237
  c->pending_requests;
160
238
  pending_request != NULL; pending_request = pending_request->next) {
161
239
  if (pending_request->md_array == md_array) {
240
+ if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
241
+ gpr_log(GPR_INFO, "plugin_credentials[%p]: cancelling request %p", c,
242
+ pending_request);
243
+ }
162
244
  pending_request->cancelled = true;
163
245
  GRPC_CLOSURE_SCHED(exec_ctx, pending_request->on_request_metadata,
164
246
  GRPC_ERROR_REF(error));
@@ -21,6 +21,8 @@
21
21
 
22
22
  #include "src/core/lib/security/credentials/credentials.h"
23
23
 
24
+ extern grpc_tracer_flag grpc_plugin_credentials_trace;
25
+
24
26
  struct grpc_plugin_credentials;
25
27
 
26
28
  typedef struct grpc_plugin_credentials_pending_request {
@@ -39,6 +39,8 @@
39
39
 
40
40
  /* We can have a per-call credentials. */
41
41
  typedef struct {
42
+ grpc_call_stack *owning_call;
43
+ grpc_call_combiner *call_combiner;
42
44
  grpc_call_credentials *creds;
43
45
  bool have_host;
44
46
  bool have_method;
@@ -49,17 +51,12 @@ typedef struct {
49
51
  pollset_set so that work can progress when this call wants work to progress
50
52
  */
51
53
  grpc_polling_entity *pollent;
52
- gpr_atm security_context_set;
53
- gpr_mu security_context_mu;
54
54
  grpc_credentials_mdelem_array md_array;
55
55
  grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT];
56
56
  grpc_auth_metadata_context auth_md_context;
57
- grpc_closure closure;
58
- // Either 0 (no cancellation and no async operation in flight),
59
- // a grpc_closure* (if the lowest bit is 0),
60
- // or a grpc_error* (if the lowest bit is 1).
61
- gpr_atm cancellation_state;
62
- grpc_closure cancel_closure;
57
+ grpc_closure async_result_closure;
58
+ grpc_closure check_call_host_cancel_closure;
59
+ grpc_closure get_request_metadata_cancel_closure;
63
60
  } call_data;
64
61
 
65
62
  /* We can have a per-channel credentials. */
@@ -68,43 +65,6 @@ typedef struct {
68
65
  grpc_auth_context *auth_context;
69
66
  } channel_data;
70
67
 
71
- static void decode_cancel_state(gpr_atm cancel_state, grpc_closure **func,
72
- grpc_error **error) {
73
- // If the lowest bit is 1, the value is a grpc_error*.
74
- // Otherwise, if non-zdero, the value is a grpc_closure*.
75
- if (cancel_state & 1) {
76
- *error = (grpc_error *)(cancel_state & ~(gpr_atm)1);
77
- } else if (cancel_state != 0) {
78
- *func = (grpc_closure *)cancel_state;
79
- }
80
- }
81
-
82
- static gpr_atm encode_cancel_state_error(grpc_error *error) {
83
- // Set the lowest bit to 1 to indicate that it's an error.
84
- return (gpr_atm)1 | (gpr_atm)error;
85
- }
86
-
87
- // Returns an error if the call has been cancelled. Otherwise, sets the
88
- // cancellation function to be called upon cancellation.
89
- static grpc_error *set_cancel_func(grpc_call_element *elem,
90
- grpc_iomgr_cb_func func) {
91
- call_data *calld = (call_data *)elem->call_data;
92
- // Decode original state.
93
- gpr_atm original_state = gpr_atm_acq_load(&calld->cancellation_state);
94
- grpc_error *original_error = GRPC_ERROR_NONE;
95
- grpc_closure *original_func = NULL;
96
- decode_cancel_state(original_state, &original_func, &original_error);
97
- // If error is set, return it.
98
- if (original_error != GRPC_ERROR_NONE) return GRPC_ERROR_REF(original_error);
99
- // Otherwise, store func.
100
- GRPC_CLOSURE_INIT(&calld->cancel_closure, func, elem,
101
- grpc_schedule_on_exec_ctx);
102
- GPR_ASSERT(((gpr_atm)&calld->cancel_closure & (gpr_atm)1) == 0);
103
- gpr_atm_rel_store(&calld->cancellation_state,
104
- (gpr_atm)&calld->cancel_closure);
105
- return GRPC_ERROR_NONE;
106
- }
107
-
108
68
  static void reset_auth_metadata_context(
109
69
  grpc_auth_metadata_context *auth_md_context) {
110
70
  if (auth_md_context->service_url != NULL) {
@@ -153,7 +113,8 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *arg,
153
113
  } else {
154
114
  error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS,
155
115
  GRPC_STATUS_UNAUTHENTICATED);
156
- grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, batch, error);
116
+ grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, batch, error,
117
+ calld->call_combiner);
157
118
  }
158
119
  }
159
120
 
@@ -191,8 +152,12 @@ static void cancel_get_request_metadata(grpc_exec_ctx *exec_ctx, void *arg,
191
152
  grpc_error *error) {
192
153
  grpc_call_element *elem = (grpc_call_element *)arg;
193
154
  call_data *calld = (call_data *)elem->call_data;
194
- grpc_call_credentials_cancel_get_request_metadata(
195
- exec_ctx, calld->creds, &calld->md_array, GRPC_ERROR_REF(error));
155
+ if (error != GRPC_ERROR_NONE) {
156
+ grpc_call_credentials_cancel_get_request_metadata(
157
+ exec_ctx, calld->creds, &calld->md_array, GRPC_ERROR_REF(error));
158
+ }
159
+ GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call,
160
+ "cancel_get_request_metadata");
196
161
  }
197
162
 
198
163
  static void send_security_metadata(grpc_exec_ctx *exec_ctx,
@@ -223,7 +188,8 @@ static void send_security_metadata(grpc_exec_ctx *exec_ctx,
223
188
  grpc_error_set_int(
224
189
  GRPC_ERROR_CREATE_FROM_STATIC_STRING(
225
190
  "Incompatible credentials set on channel and call."),
226
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAUTHENTICATED));
191
+ GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAUTHENTICATED),
192
+ calld->call_combiner);
227
193
  return;
228
194
  }
229
195
  } else {
@@ -234,22 +200,25 @@ static void send_security_metadata(grpc_exec_ctx *exec_ctx,
234
200
  build_auth_metadata_context(&chand->security_connector->base,
235
201
  chand->auth_context, calld);
236
202
 
237
- grpc_error *cancel_error = set_cancel_func(elem, cancel_get_request_metadata);
238
- if (cancel_error != GRPC_ERROR_NONE) {
239
- grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, batch,
240
- cancel_error);
241
- return;
242
- }
243
203
  GPR_ASSERT(calld->pollent != NULL);
244
- GRPC_CLOSURE_INIT(&calld->closure, on_credentials_metadata, batch,
245
- grpc_schedule_on_exec_ctx);
204
+
205
+ GRPC_CLOSURE_INIT(&calld->async_result_closure, on_credentials_metadata,
206
+ batch, grpc_schedule_on_exec_ctx);
246
207
  grpc_error *error = GRPC_ERROR_NONE;
247
208
  if (grpc_call_credentials_get_request_metadata(
248
209
  exec_ctx, calld->creds, calld->pollent, calld->auth_md_context,
249
- &calld->md_array, &calld->closure, &error)) {
210
+ &calld->md_array, &calld->async_result_closure, &error)) {
250
211
  // Synchronous return; invoke on_credentials_metadata() directly.
251
212
  on_credentials_metadata(exec_ctx, batch, error);
252
213
  GRPC_ERROR_UNREF(error);
214
+ } else {
215
+ // Async return; register cancellation closure with call combiner.
216
+ GRPC_CALL_STACK_REF(calld->owning_call, "cancel_get_request_metadata");
217
+ grpc_call_combiner_set_notify_on_cancel(
218
+ exec_ctx, calld->call_combiner,
219
+ GRPC_CLOSURE_INIT(&calld->get_request_metadata_cancel_closure,
220
+ cancel_get_request_metadata, elem,
221
+ grpc_schedule_on_exec_ctx));
253
222
  }
254
223
  }
255
224
 
@@ -258,7 +227,6 @@ static void on_host_checked(grpc_exec_ctx *exec_ctx, void *arg,
258
227
  grpc_transport_stream_op_batch *batch = (grpc_transport_stream_op_batch *)arg;
259
228
  grpc_call_element *elem = batch->handler_private.extra_arg;
260
229
  call_data *calld = elem->call_data;
261
-
262
230
  if (error == GRPC_ERROR_NONE) {
263
231
  send_security_metadata(exec_ctx, elem, batch);
264
232
  } else {
@@ -271,7 +239,8 @@ static void on_host_checked(grpc_exec_ctx *exec_ctx, void *arg,
271
239
  exec_ctx, batch,
272
240
  grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg),
273
241
  GRPC_ERROR_INT_GRPC_STATUS,
274
- GRPC_STATUS_UNAUTHENTICATED));
242
+ GRPC_STATUS_UNAUTHENTICATED),
243
+ calld->call_combiner);
275
244
  gpr_free(error_msg);
276
245
  }
277
246
  }
@@ -281,9 +250,12 @@ static void cancel_check_call_host(grpc_exec_ctx *exec_ctx, void *arg,
281
250
  grpc_call_element *elem = (grpc_call_element *)arg;
282
251
  call_data *calld = (call_data *)elem->call_data;
283
252
  channel_data *chand = (channel_data *)elem->channel_data;
284
- grpc_channel_security_connector_cancel_check_call_host(
285
- exec_ctx, chand->security_connector, &calld->closure,
286
- GRPC_ERROR_REF(error));
253
+ if (error != GRPC_ERROR_NONE) {
254
+ grpc_channel_security_connector_cancel_check_call_host(
255
+ exec_ctx, chand->security_connector, &calld->async_result_closure,
256
+ GRPC_ERROR_REF(error));
257
+ }
258
+ GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "cancel_check_call_host");
287
259
  }
288
260
 
289
261
  static void auth_start_transport_stream_op_batch(
@@ -295,52 +267,19 @@ static void auth_start_transport_stream_op_batch(
295
267
  call_data *calld = elem->call_data;
296
268
  channel_data *chand = elem->channel_data;
297
269
 
298
- if (batch->cancel_stream) {
299
- while (true) {
300
- // Decode the original cancellation state.
301
- gpr_atm original_state = gpr_atm_acq_load(&calld->cancellation_state);
302
- grpc_error *cancel_error = GRPC_ERROR_NONE;
303
- grpc_closure *func = NULL;
304
- decode_cancel_state(original_state, &func, &cancel_error);
305
- // If we had already set a cancellation error, there's nothing
306
- // more to do.
307
- if (cancel_error != GRPC_ERROR_NONE) break;
308
- // If there's a cancel func, call it.
309
- // Note that even if the cancel func has been changed by some
310
- // other thread between when we decoded it and now, it will just
311
- // be a no-op.
312
- cancel_error = GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error);
313
- if (func != NULL) {
314
- GRPC_CLOSURE_SCHED(exec_ctx, func, GRPC_ERROR_REF(cancel_error));
315
- }
316
- // Encode the new error into cancellation state.
317
- if (gpr_atm_full_cas(&calld->cancellation_state, original_state,
318
- encode_cancel_state_error(cancel_error))) {
319
- break; // Success.
320
- }
321
- // The cas failed, so try again.
322
- }
323
- } else {
324
- /* double checked lock over security context to ensure it's set once */
325
- if (gpr_atm_acq_load(&calld->security_context_set) == 0) {
326
- gpr_mu_lock(&calld->security_context_mu);
327
- if (gpr_atm_acq_load(&calld->security_context_set) == 0) {
328
- GPR_ASSERT(batch->payload->context != NULL);
329
- if (batch->payload->context[GRPC_CONTEXT_SECURITY].value == NULL) {
330
- batch->payload->context[GRPC_CONTEXT_SECURITY].value =
331
- grpc_client_security_context_create();
332
- batch->payload->context[GRPC_CONTEXT_SECURITY].destroy =
333
- grpc_client_security_context_destroy;
334
- }
335
- grpc_client_security_context *sec_ctx =
336
- batch->payload->context[GRPC_CONTEXT_SECURITY].value;
337
- GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter");
338
- sec_ctx->auth_context =
339
- GRPC_AUTH_CONTEXT_REF(chand->auth_context, "client_auth_filter");
340
- gpr_atm_rel_store(&calld->security_context_set, 1);
341
- }
342
- gpr_mu_unlock(&calld->security_context_mu);
270
+ if (!batch->cancel_stream) {
271
+ GPR_ASSERT(batch->payload->context != NULL);
272
+ if (batch->payload->context[GRPC_CONTEXT_SECURITY].value == NULL) {
273
+ batch->payload->context[GRPC_CONTEXT_SECURITY].value =
274
+ grpc_client_security_context_create();
275
+ batch->payload->context[GRPC_CONTEXT_SECURITY].destroy =
276
+ grpc_client_security_context_destroy;
343
277
  }
278
+ grpc_client_security_context *sec_ctx =
279
+ batch->payload->context[GRPC_CONTEXT_SECURITY].value;
280
+ GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter");
281
+ sec_ctx->auth_context =
282
+ GRPC_AUTH_CONTEXT_REF(chand->auth_context, "client_auth_filter");
344
283
  }
345
284
 
346
285
  if (batch->send_initial_metadata) {
@@ -365,26 +304,27 @@ static void auth_start_transport_stream_op_batch(
365
304
  }
366
305
  }
367
306
  if (calld->have_host) {
368
- grpc_error *cancel_error = set_cancel_func(elem, cancel_check_call_host);
369
- if (cancel_error != GRPC_ERROR_NONE) {
370
- grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, batch,
371
- cancel_error);
307
+ batch->handler_private.extra_arg = elem;
308
+ GRPC_CLOSURE_INIT(&calld->async_result_closure, on_host_checked, batch,
309
+ grpc_schedule_on_exec_ctx);
310
+ char *call_host = grpc_slice_to_c_string(calld->host);
311
+ grpc_error *error = GRPC_ERROR_NONE;
312
+ if (grpc_channel_security_connector_check_call_host(
313
+ exec_ctx, chand->security_connector, call_host,
314
+ chand->auth_context, &calld->async_result_closure, &error)) {
315
+ // Synchronous return; invoke on_host_checked() directly.
316
+ on_host_checked(exec_ctx, batch, error);
317
+ GRPC_ERROR_UNREF(error);
372
318
  } else {
373
- char *call_host = grpc_slice_to_c_string(calld->host);
374
- batch->handler_private.extra_arg = elem;
375
- grpc_error *error = GRPC_ERROR_NONE;
376
- if (grpc_channel_security_connector_check_call_host(
377
- exec_ctx, chand->security_connector, call_host,
378
- chand->auth_context,
379
- GRPC_CLOSURE_INIT(&calld->closure, on_host_checked, batch,
380
- grpc_schedule_on_exec_ctx),
381
- &error)) {
382
- // Synchronous return; invoke on_host_checked() directly.
383
- on_host_checked(exec_ctx, batch, error);
384
- GRPC_ERROR_UNREF(error);
385
- }
386
- gpr_free(call_host);
319
+ // Async return; register cancellation closure with call combiner.
320
+ GRPC_CALL_STACK_REF(calld->owning_call, "cancel_check_call_host");
321
+ grpc_call_combiner_set_notify_on_cancel(
322
+ exec_ctx, calld->call_combiner,
323
+ GRPC_CLOSURE_INIT(&calld->check_call_host_cancel_closure,
324
+ cancel_check_call_host, elem,
325
+ grpc_schedule_on_exec_ctx));
387
326
  }
327
+ gpr_free(call_host);
388
328
  GPR_TIMER_END("auth_start_transport_stream_op_batch", 0);
389
329
  return; /* early exit */
390
330
  }
@@ -400,8 +340,8 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
400
340
  grpc_call_element *elem,
401
341
  const grpc_call_element_args *args) {
402
342
  call_data *calld = elem->call_data;
403
- memset(calld, 0, sizeof(*calld));
404
- gpr_mu_init(&calld->security_context_mu);
343
+ calld->owning_call = args->call_stack;
344
+ calld->call_combiner = args->call_combiner;
405
345
  return GRPC_ERROR_NONE;
406
346
  }
407
347
 
@@ -426,12 +366,6 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
426
366
  grpc_slice_unref_internal(exec_ctx, calld->method);
427
367
  }
428
368
  reset_auth_metadata_context(&calld->auth_md_context);
429
- gpr_mu_destroy(&calld->security_context_mu);
430
- gpr_atm cancel_state = gpr_atm_acq_load(&calld->cancellation_state);
431
- grpc_error *cancel_error = GRPC_ERROR_NONE;
432
- grpc_closure *cancel_func = NULL;
433
- decode_cancel_state(cancel_state, &cancel_func, &cancel_error);
434
- GRPC_ERROR_UNREF(cancel_error);
435
369
  }
436
370
 
437
371
  /* Constructor for channel_data */
@@ -490,6 +424,5 @@ const grpc_channel_filter grpc_client_auth_filter = {
490
424
  sizeof(channel_data),
491
425
  init_channel_elem,
492
426
  destroy_channel_elem,
493
- grpc_call_next_get_peer,
494
427
  grpc_channel_next_get_info,
495
428
  "client-auth"};