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
@@ -99,7 +99,7 @@ static grpc_server_retry_throttle_data* grpc_server_retry_throttle_data_create(
99
99
  int max_milli_tokens, int milli_token_ratio,
100
100
  grpc_server_retry_throttle_data* old_throttle_data) {
101
101
  grpc_server_retry_throttle_data* throttle_data =
102
- gpr_malloc(sizeof(*throttle_data));
102
+ (grpc_server_retry_throttle_data*)gpr_malloc(sizeof(*throttle_data));
103
103
  memset(throttle_data, 0, sizeof(*throttle_data));
104
104
  gpr_ref_init(&throttle_data->refs, 1);
105
105
  throttle_data->max_milli_tokens = max_milli_tokens;
@@ -131,20 +131,22 @@ static grpc_server_retry_throttle_data* grpc_server_retry_throttle_data_create(
131
131
  //
132
132
 
133
133
  static void* copy_server_name(void* key, void* unused) {
134
- return gpr_strdup(key);
134
+ return gpr_strdup((const char*)key);
135
135
  }
136
136
 
137
137
  static long compare_server_name(void* key1, void* key2, void* unused) {
138
- return strcmp(key1, key2);
138
+ return strcmp((const char*)key1, (const char*)key2);
139
139
  }
140
140
 
141
141
  static void destroy_server_retry_throttle_data(void* value, void* unused) {
142
- grpc_server_retry_throttle_data* throttle_data = value;
142
+ grpc_server_retry_throttle_data* throttle_data =
143
+ (grpc_server_retry_throttle_data*)value;
143
144
  grpc_server_retry_throttle_data_unref(throttle_data);
144
145
  }
145
146
 
146
147
  static void* copy_server_retry_throttle_data(void* value, void* unused) {
147
- grpc_server_retry_throttle_data* throttle_data = value;
148
+ grpc_server_retry_throttle_data* throttle_data =
149
+ (grpc_server_retry_throttle_data*)value;
148
150
  return grpc_server_retry_throttle_data_ref(throttle_data);
149
151
  }
150
152
 
@@ -175,7 +177,8 @@ grpc_server_retry_throttle_data* grpc_retry_throttle_map_get_data_for_server(
175
177
  const char* server_name, int max_milli_tokens, int milli_token_ratio) {
176
178
  gpr_mu_lock(&g_mu);
177
179
  grpc_server_retry_throttle_data* throttle_data =
178
- gpr_avl_get(g_avl, (char*)server_name, NULL);
180
+ (grpc_server_retry_throttle_data*)gpr_avl_get(g_avl, (char*)server_name,
181
+ NULL);
179
182
  if (throttle_data == NULL) {
180
183
  // Entry not found. Create a new one.
181
184
  throttle_data = grpc_server_retry_throttle_data_create(
@@ -32,6 +32,7 @@
32
32
  #include "src/core/ext/filters/client_channel/uri_parser.h"
33
33
  #include "src/core/lib/channel/channel_args.h"
34
34
  #include "src/core/lib/channel/connected_channel.h"
35
+ #include "src/core/lib/debug/stats.h"
35
36
  #include "src/core/lib/iomgr/sockaddr_utils.h"
36
37
  #include "src/core/lib/iomgr/timer.h"
37
38
  #include "src/core/lib/profiling/timers.h"
@@ -157,7 +158,7 @@ static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *subchannel,
157
158
 
158
159
  static void connection_destroy(grpc_exec_ctx *exec_ctx, void *arg,
159
160
  grpc_error *error) {
160
- grpc_connected_subchannel *c = arg;
161
+ grpc_connected_subchannel *c = (grpc_connected_subchannel *)arg;
161
162
  grpc_channel_stack_destroy(exec_ctx, CHANNEL_STACK_FROM_CONNECTION(c));
162
163
  gpr_free(c);
163
164
  }
@@ -181,7 +182,7 @@ void grpc_connected_subchannel_unref(grpc_exec_ctx *exec_ctx,
181
182
 
182
183
  static void subchannel_destroy(grpc_exec_ctx *exec_ctx, void *arg,
183
184
  grpc_error *error) {
184
- grpc_subchannel *c = arg;
185
+ grpc_subchannel *c = (grpc_subchannel *)arg;
185
186
  gpr_free((void *)c->filters);
186
187
  grpc_channel_args_destroy(exec_ctx, c->args);
187
188
  grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker);
@@ -290,21 +291,24 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
290
291
  return c;
291
292
  }
292
293
 
293
- c = gpr_zalloc(sizeof(*c));
294
+ GRPC_STATS_INC_CLIENT_SUBCHANNELS_CREATED(exec_ctx);
295
+ c = (grpc_subchannel *)gpr_zalloc(sizeof(*c));
294
296
  c->key = key;
295
297
  gpr_atm_no_barrier_store(&c->ref_pair, 1 << INTERNAL_REF_BITS);
296
298
  c->connector = connector;
297
299
  grpc_connector_ref(c->connector);
298
300
  c->num_filters = args->filter_count;
299
301
  if (c->num_filters > 0) {
300
- c->filters = gpr_malloc(sizeof(grpc_channel_filter *) * c->num_filters);
302
+ c->filters = (const grpc_channel_filter **)gpr_malloc(
303
+ sizeof(grpc_channel_filter *) * c->num_filters);
301
304
  memcpy((void *)c->filters, args->filters,
302
305
  sizeof(grpc_channel_filter *) * c->num_filters);
303
306
  } else {
304
307
  c->filters = NULL;
305
308
  }
306
309
  c->pollset_set = grpc_pollset_set_create();
307
- grpc_resolved_address *addr = gpr_malloc(sizeof(*addr));
310
+ grpc_resolved_address *addr =
311
+ (grpc_resolved_address *)gpr_malloc(sizeof(*addr));
308
312
  grpc_get_subchannel_address_arg(exec_ctx, args->args, addr);
309
313
  grpc_resolved_address *new_address = NULL;
310
314
  grpc_channel_args *new_args = NULL;
@@ -400,7 +404,7 @@ grpc_connectivity_state grpc_subchannel_check_connectivity(grpc_subchannel *c,
400
404
 
401
405
  static void on_external_state_watcher_done(grpc_exec_ctx *exec_ctx, void *arg,
402
406
  grpc_error *error) {
403
- external_state_watcher *w = arg;
407
+ external_state_watcher *w = (external_state_watcher *)arg;
404
408
  grpc_closure *follow_up = w->notify;
405
409
  if (w->pollset_set != NULL) {
406
410
  grpc_pollset_set_del_pollset_set(exec_ctx, w->subchannel->pollset_set,
@@ -416,7 +420,7 @@ static void on_external_state_watcher_done(grpc_exec_ctx *exec_ctx, void *arg,
416
420
  }
417
421
 
418
422
  static void on_alarm(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
419
- grpc_subchannel *c = arg;
423
+ grpc_subchannel *c = (grpc_subchannel *)arg;
420
424
  gpr_mu_lock(&c->mu);
421
425
  c->have_alarm = false;
422
426
  if (c->disconnected) {
@@ -501,7 +505,7 @@ void grpc_subchannel_notify_on_state_change(
501
505
  }
502
506
  gpr_mu_unlock(&c->mu);
503
507
  } else {
504
- w = gpr_malloc(sizeof(*w));
508
+ w = (external_state_watcher *)gpr_malloc(sizeof(*w));
505
509
  w->subchannel = c;
506
510
  w->pollset_set = interested_parties;
507
511
  w->notify = notify;
@@ -533,7 +537,7 @@ void grpc_connected_subchannel_process_transport_op(
533
537
 
534
538
  static void subchannel_on_child_state_changed(grpc_exec_ctx *exec_ctx, void *p,
535
539
  grpc_error *error) {
536
- state_watcher *sw = p;
540
+ state_watcher *sw = (state_watcher *)p;
537
541
  grpc_subchannel *c = sw->subchannel;
538
542
  gpr_mu *mu = &c->mu;
539
543
 
@@ -623,7 +627,7 @@ static bool publish_transport_locked(grpc_exec_ctx *exec_ctx,
623
627
  memset(&c->connecting_result, 0, sizeof(c->connecting_result));
624
628
 
625
629
  /* initialize state watcher */
626
- sw_subchannel = gpr_malloc(sizeof(*sw_subchannel));
630
+ sw_subchannel = (state_watcher *)gpr_malloc(sizeof(*sw_subchannel));
627
631
  sw_subchannel->subchannel = c;
628
632
  sw_subchannel->connectivity_state = GRPC_CHANNEL_READY;
629
633
  GRPC_CLOSURE_INIT(&sw_subchannel->closure, subchannel_on_child_state_changed,
@@ -660,7 +664,7 @@ static bool publish_transport_locked(grpc_exec_ctx *exec_ctx,
660
664
 
661
665
  static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *arg,
662
666
  grpc_error *error) {
663
- grpc_subchannel *c = arg;
667
+ grpc_subchannel *c = (grpc_subchannel *)arg;
664
668
  grpc_channel_args *delete_channel_args = c->connecting_result.channel_args;
665
669
 
666
670
  GRPC_SUBCHANNEL_WEAK_REF(c, "connected");
@@ -696,7 +700,7 @@ static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *arg,
696
700
 
697
701
  static void subchannel_call_destroy(grpc_exec_ctx *exec_ctx, void *call,
698
702
  grpc_error *error) {
699
- grpc_subchannel_call *c = call;
703
+ grpc_subchannel_call *c = (grpc_subchannel_call *)call;
700
704
  GPR_ASSERT(c->schedule_closure_after_destroy != NULL);
701
705
  GPR_TIMER_BEGIN("grpc_subchannel_call_unref.destroy", 0);
702
706
  grpc_connected_subchannel *connection = c->connection;
@@ -724,20 +728,14 @@ void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx,
724
728
  GRPC_CALL_STACK_UNREF(exec_ctx, SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON);
725
729
  }
726
730
 
727
- char *grpc_subchannel_call_get_peer(grpc_exec_ctx *exec_ctx,
728
- grpc_subchannel_call *call) {
729
- grpc_call_stack *call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call);
730
- grpc_call_element *top_elem = grpc_call_stack_element(call_stack, 0);
731
- return top_elem->filter->get_peer(exec_ctx, top_elem);
732
- }
733
-
734
731
  void grpc_subchannel_call_process_op(grpc_exec_ctx *exec_ctx,
735
732
  grpc_subchannel_call *call,
736
- grpc_transport_stream_op_batch *op) {
733
+ grpc_transport_stream_op_batch *batch) {
737
734
  GPR_TIMER_BEGIN("grpc_subchannel_call_process_op", 0);
738
735
  grpc_call_stack *call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call);
739
736
  grpc_call_element *top_elem = grpc_call_stack_element(call_stack, 0);
740
- top_elem->filter->start_transport_stream_op_batch(exec_ctx, top_elem, op);
737
+ GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch);
738
+ top_elem->filter->start_transport_stream_op_batch(exec_ctx, top_elem, batch);
741
739
  GPR_TIMER_END("grpc_subchannel_call_process_op", 0);
742
740
  }
743
741
 
@@ -756,17 +754,19 @@ grpc_error *grpc_connected_subchannel_create_call(
756
754
  const grpc_connected_subchannel_call_args *args,
757
755
  grpc_subchannel_call **call) {
758
756
  grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con);
759
- *call = gpr_arena_alloc(
757
+ *call = (grpc_subchannel_call *)gpr_arena_alloc(
760
758
  args->arena, sizeof(grpc_subchannel_call) + chanstk->call_stack_size);
761
759
  grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call);
762
760
  (*call)->connection = GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call");
763
- const grpc_call_element_args call_args = {.call_stack = callstk,
764
- .server_transport_data = NULL,
765
- .context = args->context,
766
- .path = args->path,
767
- .start_time = args->start_time,
768
- .deadline = args->deadline,
769
- .arena = args->arena};
761
+ const grpc_call_element_args call_args = {
762
+ .call_stack = callstk,
763
+ .server_transport_data = NULL,
764
+ .context = args->context,
765
+ .path = args->path,
766
+ .start_time = args->start_time,
767
+ .deadline = args->deadline,
768
+ .arena = args->arena,
769
+ .call_combiner = args->call_combiner};
770
770
  grpc_error *error = grpc_call_stack_init(
771
771
  exec_ctx, chanstk, 1, subchannel_call_destroy, *call, &call_args);
772
772
  if (error != GRPC_ERROR_NONE) {
@@ -811,6 +811,6 @@ const char *grpc_get_subchannel_address_uri_arg(const grpc_channel_args *args) {
811
811
 
812
812
  grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address *addr) {
813
813
  return grpc_channel_arg_string_create(
814
- GRPC_ARG_SUBCHANNEL_ADDRESS,
814
+ (char *)GRPC_ARG_SUBCHANNEL_ADDRESS,
815
815
  addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup(""));
816
816
  }
@@ -106,6 +106,7 @@ typedef struct {
106
106
  gpr_timespec deadline;
107
107
  gpr_arena *arena;
108
108
  grpc_call_context_element *context;
109
+ grpc_call_combiner *call_combiner;
109
110
  } grpc_connected_subchannel_call_args;
110
111
 
111
112
  grpc_error *grpc_connected_subchannel_create_call(
@@ -150,10 +151,6 @@ void grpc_subchannel_call_process_op(grpc_exec_ctx *exec_ctx,
150
151
  grpc_subchannel_call *subchannel_call,
151
152
  grpc_transport_stream_op_batch *op);
152
153
 
153
- /** continue querying for peer */
154
- char *grpc_subchannel_call_get_peer(grpc_exec_ctx *exec_ctx,
155
- grpc_subchannel_call *subchannel_call);
156
-
157
154
  /** Must be called once per call. Sets the 'then_schedule_closure' argument for
158
155
  call stack destruction. */
159
156
  void grpc_subchannel_call_set_cleanup_closure(
@@ -34,6 +34,8 @@ static gpr_avl g_subchannel_index;
34
34
 
35
35
  static gpr_mu g_mu;
36
36
 
37
+ static gpr_refcount g_refcount;
38
+
37
39
  struct grpc_subchannel_key {
38
40
  grpc_subchannel_args args;
39
41
  };
@@ -43,11 +45,11 @@ static bool g_force_creation = false;
43
45
  static grpc_subchannel_key *create_key(
44
46
  const grpc_subchannel_args *args,
45
47
  grpc_channel_args *(*copy_channel_args)(const grpc_channel_args *args)) {
46
- grpc_subchannel_key *k = gpr_malloc(sizeof(*k));
48
+ grpc_subchannel_key *k = (grpc_subchannel_key *)gpr_malloc(sizeof(*k));
47
49
  k->args.filter_count = args->filter_count;
48
50
  if (k->args.filter_count > 0) {
49
- k->args.filters =
50
- gpr_malloc(sizeof(*k->args.filters) * k->args.filter_count);
51
+ k->args.filters = (const grpc_channel_filter **)gpr_malloc(
52
+ sizeof(*k->args.filters) * k->args.filter_count);
51
53
  memcpy((grpc_channel_filter *)k->args.filters, args->filters,
52
54
  sizeof(*k->args.filters) * k->args.filter_count);
53
55
  } else {
@@ -88,24 +90,26 @@ void grpc_subchannel_key_destroy(grpc_exec_ctx *exec_ctx,
88
90
 
89
91
  static void sck_avl_destroy(void *p, void *user_data) {
90
92
  grpc_exec_ctx *exec_ctx = (grpc_exec_ctx *)user_data;
91
- grpc_subchannel_key_destroy(exec_ctx, p);
93
+ grpc_subchannel_key_destroy(exec_ctx, (grpc_subchannel_key *)p);
92
94
  }
93
95
 
94
96
  static void *sck_avl_copy(void *p, void *unused) {
95
- return subchannel_key_copy(p);
97
+ return subchannel_key_copy((grpc_subchannel_key *)p);
96
98
  }
97
99
 
98
100
  static long sck_avl_compare(void *a, void *b, void *unused) {
99
- return grpc_subchannel_key_compare(a, b);
101
+ return grpc_subchannel_key_compare((grpc_subchannel_key *)a,
102
+ (grpc_subchannel_key *)b);
100
103
  }
101
104
 
102
105
  static void scv_avl_destroy(void *p, void *user_data) {
103
106
  grpc_exec_ctx *exec_ctx = (grpc_exec_ctx *)user_data;
104
- GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, p, "subchannel_index");
107
+ GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, (grpc_subchannel *)p,
108
+ "subchannel_index");
105
109
  }
106
110
 
107
111
  static void *scv_avl_copy(void *p, void *unused) {
108
- GRPC_SUBCHANNEL_WEAK_REF(p, "subchannel_index");
112
+ GRPC_SUBCHANNEL_WEAK_REF((grpc_subchannel *)p, "subchannel_index");
109
113
  return p;
110
114
  }
111
115
 
@@ -119,15 +123,27 @@ static const gpr_avl_vtable subchannel_avl_vtable = {
119
123
  void grpc_subchannel_index_init(void) {
120
124
  g_subchannel_index = gpr_avl_create(&subchannel_avl_vtable);
121
125
  gpr_mu_init(&g_mu);
126
+ gpr_ref_init(&g_refcount, 1);
122
127
  }
123
128
 
124
129
  void grpc_subchannel_index_shutdown(void) {
125
- grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
126
- gpr_mu_destroy(&g_mu);
127
- gpr_avl_unref(g_subchannel_index, &exec_ctx);
128
- grpc_exec_ctx_finish(&exec_ctx);
130
+ // TODO(juanlishen): This refcounting mechanism may lead to memory leackage.
131
+ // To solve that, we should force polling to flush any pending callbacks, then
132
+ // shutdown safely.
133
+ grpc_subchannel_index_unref();
134
+ }
135
+
136
+ void grpc_subchannel_index_unref(void) {
137
+ if (gpr_unref(&g_refcount)) {
138
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
139
+ gpr_mu_destroy(&g_mu);
140
+ gpr_avl_unref(g_subchannel_index, &exec_ctx);
141
+ grpc_exec_ctx_finish(&exec_ctx);
142
+ }
129
143
  }
130
144
 
145
+ void grpc_subchannel_index_ref(void) { gpr_ref_non_zero(&g_refcount); }
146
+
131
147
  grpc_subchannel *grpc_subchannel_index_find(grpc_exec_ctx *exec_ctx,
132
148
  grpc_subchannel_key *key) {
133
149
  // Lock, and take a reference to the subchannel index.
@@ -137,7 +153,7 @@ grpc_subchannel *grpc_subchannel_index_find(grpc_exec_ctx *exec_ctx,
137
153
  gpr_mu_unlock(&g_mu);
138
154
 
139
155
  grpc_subchannel *c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(
140
- gpr_avl_get(index, key, exec_ctx), "index_find");
156
+ (grpc_subchannel *)gpr_avl_get(index, key, exec_ctx), "index_find");
141
157
  gpr_avl_unref(index, exec_ctx);
142
158
 
143
159
  return c;
@@ -159,7 +175,7 @@ grpc_subchannel *grpc_subchannel_index_register(grpc_exec_ctx *exec_ctx,
159
175
  gpr_mu_unlock(&g_mu);
160
176
 
161
177
  // - Check to see if a subchannel already exists
162
- c = gpr_avl_get(index, key, exec_ctx);
178
+ c = (grpc_subchannel *)gpr_avl_get(index, key, exec_ctx);
163
179
  if (c != NULL) {
164
180
  c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "index_register");
165
181
  }
@@ -207,7 +223,7 @@ void grpc_subchannel_index_unregister(grpc_exec_ctx *exec_ctx,
207
223
 
208
224
  // Check to see if this key still refers to the previously
209
225
  // registered subchannel
210
- grpc_subchannel *c = gpr_avl_get(index, key, exec_ctx);
226
+ grpc_subchannel *c = (grpc_subchannel *)gpr_avl_get(index, key, exec_ctx);
211
227
  if (c != constructed) {
212
228
  gpr_avl_unref(index, exec_ctx);
213
229
  break;
@@ -59,6 +59,13 @@ void grpc_subchannel_index_init(void);
59
59
  /** Shutdown the subchannel index (global) */
60
60
  void grpc_subchannel_index_shutdown(void);
61
61
 
62
+ /** Increment the refcount (non-zero) of subchannel index (global). */
63
+ void grpc_subchannel_index_ref(void);
64
+
65
+ /** Decrement the refcount of subchannel index (global). If the refcount drops
66
+ to zero, unref the subchannel index and destroy its mutex. */
67
+ void grpc_subchannel_index_unref(void);
68
+
62
69
  /** \em TEST ONLY.
63
70
  * If \a force_creation is true, all key comparisons will be false, resulting in
64
71
  * new subchannels always being created. Otherwise, the keys will be compared as
@@ -45,7 +45,7 @@ static grpc_uri *bad_uri(const char *uri_text, size_t pos, const char *section,
45
45
  gpr_log(GPR_ERROR, "%s%s'", line_prefix, uri_text);
46
46
  gpr_free(line_prefix);
47
47
 
48
- line_prefix = gpr_malloc(pfx_len + 1);
48
+ line_prefix = (char *)gpr_malloc(pfx_len + 1);
49
49
  memset(line_prefix, ' ', pfx_len);
50
50
  line_prefix[pfx_len] = 0;
51
51
  gpr_log(GPR_ERROR, "%s^ here", line_prefix);
@@ -156,7 +156,8 @@ static void parse_query_parts(grpc_uri *uri) {
156
156
 
157
157
  gpr_string_split(uri->query, QUERY_PARTS_SEPARATOR, &uri->query_parts,
158
158
  &uri->num_query_parts);
159
- uri->query_parts_values = gpr_malloc(uri->num_query_parts * sizeof(char **));
159
+ uri->query_parts_values =
160
+ (char **)gpr_malloc(uri->num_query_parts * sizeof(char **));
160
161
  for (size_t i = 0; i < uri->num_query_parts; i++) {
161
162
  char **query_param_parts;
162
163
  size_t num_query_param_parts;
@@ -269,7 +270,7 @@ grpc_uri *grpc_uri_parse(grpc_exec_ctx *exec_ctx, const char *uri_text,
269
270
  fragment_end = i;
270
271
  }
271
272
 
272
- uri = gpr_zalloc(sizeof(*uri));
273
+ uri = (grpc_uri *)gpr_zalloc(sizeof(*uri));
273
274
  uri->scheme =
274
275
  decode_and_copy_component(exec_ctx, uri_text, scheme_begin, scheme_end);
275
276
  uri->authority = decode_and_copy_component(exec_ctx, uri_text,
@@ -34,22 +34,56 @@
34
34
  // grpc_deadline_state
35
35
  //
36
36
 
37
+ // The on_complete callback used when sending a cancel_error batch down the
38
+ // filter stack. Yields the call combiner when the batch returns.
39
+ static void yield_call_combiner(grpc_exec_ctx* exec_ctx, void* arg,
40
+ grpc_error* ignored) {
41
+ grpc_deadline_state* deadline_state = (grpc_deadline_state*)arg;
42
+ GRPC_CALL_COMBINER_STOP(exec_ctx, deadline_state->call_combiner,
43
+ "got on_complete from cancel_stream batch");
44
+ GRPC_CALL_STACK_UNREF(exec_ctx, deadline_state->call_stack, "deadline_timer");
45
+ }
46
+
47
+ // This is called via the call combiner, so access to deadline_state is
48
+ // synchronized.
49
+ static void send_cancel_op_in_call_combiner(grpc_exec_ctx* exec_ctx, void* arg,
50
+ grpc_error* error) {
51
+ grpc_call_element* elem = (grpc_call_element*)arg;
52
+ grpc_deadline_state* deadline_state = (grpc_deadline_state*)elem->call_data;
53
+ grpc_transport_stream_op_batch* batch = grpc_make_transport_stream_op(
54
+ GRPC_CLOSURE_INIT(&deadline_state->timer_callback, yield_call_combiner,
55
+ deadline_state, grpc_schedule_on_exec_ctx));
56
+ batch->cancel_stream = true;
57
+ batch->payload->cancel_stream.cancel_error = GRPC_ERROR_REF(error);
58
+ elem->filter->start_transport_stream_op_batch(exec_ctx, elem, batch);
59
+ }
60
+
37
61
  // Timer callback.
38
62
  static void timer_callback(grpc_exec_ctx* exec_ctx, void* arg,
39
63
  grpc_error* error) {
40
64
  grpc_call_element* elem = (grpc_call_element*)arg;
41
65
  grpc_deadline_state* deadline_state = (grpc_deadline_state*)elem->call_data;
42
66
  if (error != GRPC_ERROR_CANCELLED) {
43
- grpc_call_element_signal_error(
44
- exec_ctx, elem,
45
- grpc_error_set_int(
46
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Deadline Exceeded"),
47
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_DEADLINE_EXCEEDED));
67
+ error = grpc_error_set_int(
68
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Deadline Exceeded"),
69
+ GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_DEADLINE_EXCEEDED);
70
+ grpc_call_combiner_cancel(exec_ctx, deadline_state->call_combiner,
71
+ GRPC_ERROR_REF(error));
72
+ GRPC_CLOSURE_INIT(&deadline_state->timer_callback,
73
+ send_cancel_op_in_call_combiner, elem,
74
+ grpc_schedule_on_exec_ctx);
75
+ GRPC_CALL_COMBINER_START(exec_ctx, deadline_state->call_combiner,
76
+ &deadline_state->timer_callback, error,
77
+ "deadline exceeded -- sending cancel_stream op");
78
+ } else {
79
+ GRPC_CALL_STACK_UNREF(exec_ctx, deadline_state->call_stack,
80
+ "deadline_timer");
48
81
  }
49
- GRPC_CALL_STACK_UNREF(exec_ctx, deadline_state->call_stack, "deadline_timer");
50
82
  }
51
83
 
52
84
  // Starts the deadline timer.
85
+ // This is called via the call combiner, so access to deadline_state is
86
+ // synchronized.
53
87
  static void start_timer_if_needed(grpc_exec_ctx* exec_ctx,
54
88
  grpc_call_element* elem,
55
89
  gpr_timespec deadline) {
@@ -58,51 +92,39 @@ static void start_timer_if_needed(grpc_exec_ctx* exec_ctx,
58
92
  return;
59
93
  }
60
94
  grpc_deadline_state* deadline_state = (grpc_deadline_state*)elem->call_data;
61
- grpc_deadline_timer_state cur_state;
62
95
  grpc_closure* closure = NULL;
63
- retry:
64
- cur_state =
65
- (grpc_deadline_timer_state)gpr_atm_acq_load(&deadline_state->timer_state);
66
- switch (cur_state) {
96
+ switch (deadline_state->timer_state) {
67
97
  case GRPC_DEADLINE_STATE_PENDING:
68
98
  // Note: We do not start the timer if there is already a timer
69
99
  return;
70
100
  case GRPC_DEADLINE_STATE_FINISHED:
71
- if (gpr_atm_rel_cas(&deadline_state->timer_state,
72
- GRPC_DEADLINE_STATE_FINISHED,
73
- GRPC_DEADLINE_STATE_PENDING)) {
74
- // If we've already created and destroyed a timer, we always create a
75
- // new closure: we have no other guarantee that the inlined closure is
76
- // not in use (it may hold a pending call to timer_callback)
77
- closure = GRPC_CLOSURE_CREATE(timer_callback, elem,
78
- grpc_schedule_on_exec_ctx);
79
- } else {
80
- goto retry;
81
- }
101
+ deadline_state->timer_state = GRPC_DEADLINE_STATE_PENDING;
102
+ // If we've already created and destroyed a timer, we always create a
103
+ // new closure: we have no other guarantee that the inlined closure is
104
+ // not in use (it may hold a pending call to timer_callback)
105
+ closure =
106
+ GRPC_CLOSURE_CREATE(timer_callback, elem, grpc_schedule_on_exec_ctx);
82
107
  break;
83
108
  case GRPC_DEADLINE_STATE_INITIAL:
84
- if (gpr_atm_rel_cas(&deadline_state->timer_state,
85
- GRPC_DEADLINE_STATE_INITIAL,
86
- GRPC_DEADLINE_STATE_PENDING)) {
87
- closure =
88
- GRPC_CLOSURE_INIT(&deadline_state->timer_callback, timer_callback,
89
- elem, grpc_schedule_on_exec_ctx);
90
- } else {
91
- goto retry;
92
- }
109
+ deadline_state->timer_state = GRPC_DEADLINE_STATE_PENDING;
110
+ closure =
111
+ GRPC_CLOSURE_INIT(&deadline_state->timer_callback, timer_callback,
112
+ elem, grpc_schedule_on_exec_ctx);
93
113
  break;
94
114
  }
95
- GPR_ASSERT(closure);
115
+ GPR_ASSERT(closure != NULL);
96
116
  GRPC_CALL_STACK_REF(deadline_state->call_stack, "deadline_timer");
97
117
  grpc_timer_init(exec_ctx, &deadline_state->timer, deadline, closure,
98
118
  gpr_now(GPR_CLOCK_MONOTONIC));
99
119
  }
100
120
 
101
121
  // Cancels the deadline timer.
122
+ // This is called via the call combiner, so access to deadline_state is
123
+ // synchronized.
102
124
  static void cancel_timer_if_needed(grpc_exec_ctx* exec_ctx,
103
125
  grpc_deadline_state* deadline_state) {
104
- if (gpr_atm_rel_cas(&deadline_state->timer_state, GRPC_DEADLINE_STATE_PENDING,
105
- GRPC_DEADLINE_STATE_FINISHED)) {
126
+ if (deadline_state->timer_state == GRPC_DEADLINE_STATE_PENDING) {
127
+ deadline_state->timer_state = GRPC_DEADLINE_STATE_FINISHED;
106
128
  grpc_timer_cancel(exec_ctx, &deadline_state->timer);
107
129
  } else {
108
130
  // timer was either in STATE_INITAL (nothing to cancel)
@@ -131,22 +153,39 @@ static void inject_on_complete_cb(grpc_deadline_state* deadline_state,
131
153
  // Callback and associated state for starting the timer after call stack
132
154
  // initialization has been completed.
133
155
  struct start_timer_after_init_state {
156
+ bool in_call_combiner;
134
157
  grpc_call_element* elem;
135
158
  gpr_timespec deadline;
136
159
  grpc_closure closure;
137
160
  };
138
161
  static void start_timer_after_init(grpc_exec_ctx* exec_ctx, void* arg,
139
162
  grpc_error* error) {
140
- struct start_timer_after_init_state* state = arg;
163
+ struct start_timer_after_init_state* state =
164
+ (struct start_timer_after_init_state*)arg;
165
+ grpc_deadline_state* deadline_state =
166
+ (grpc_deadline_state*)state->elem->call_data;
167
+ if (!state->in_call_combiner) {
168
+ // We are initially called without holding the call combiner, so we
169
+ // need to bounce ourselves into it.
170
+ state->in_call_combiner = true;
171
+ GRPC_CALL_COMBINER_START(exec_ctx, deadline_state->call_combiner,
172
+ &state->closure, GRPC_ERROR_REF(error),
173
+ "scheduling deadline timer");
174
+ return;
175
+ }
141
176
  start_timer_if_needed(exec_ctx, state->elem, state->deadline);
142
177
  gpr_free(state);
178
+ GRPC_CALL_COMBINER_STOP(exec_ctx, deadline_state->call_combiner,
179
+ "done scheduling deadline timer");
143
180
  }
144
181
 
145
182
  void grpc_deadline_state_init(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
146
183
  grpc_call_stack* call_stack,
184
+ grpc_call_combiner* call_combiner,
147
185
  gpr_timespec deadline) {
148
186
  grpc_deadline_state* deadline_state = (grpc_deadline_state*)elem->call_data;
149
187
  deadline_state->call_stack = call_stack;
188
+ deadline_state->call_combiner = call_combiner;
150
189
  // Deadline will always be infinite on servers, so the timer will only be
151
190
  // set on clients with a finite deadline.
152
191
  deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC);
@@ -158,7 +197,8 @@ void grpc_deadline_state_init(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
158
197
  // call stack initialization is finished. To avoid that problem, we
159
198
  // create a closure to start the timer, and we schedule that closure
160
199
  // to be run after call stack initialization is done.
161
- struct start_timer_after_init_state* state = gpr_malloc(sizeof(*state));
200
+ struct start_timer_after_init_state* state =
201
+ (struct start_timer_after_init_state*)gpr_zalloc(sizeof(*state));
162
202
  state->elem = elem;
163
203
  state->deadline = deadline;
164
204
  GRPC_CLOSURE_INIT(&state->closure, start_timer_after_init, state,
@@ -232,7 +272,8 @@ typedef struct server_call_data {
232
272
  static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
233
273
  grpc_call_element* elem,
234
274
  const grpc_call_element_args* args) {
235
- grpc_deadline_state_init(exec_ctx, elem, args->call_stack, args->deadline);
275
+ grpc_deadline_state_init(exec_ctx, elem, args->call_stack,
276
+ args->call_combiner, args->deadline);
236
277
  return GRPC_ERROR_NONE;
237
278
  }
238
279
 
@@ -310,7 +351,6 @@ const grpc_channel_filter grpc_client_deadline_filter = {
310
351
  0, // sizeof(channel_data)
311
352
  init_channel_elem,
312
353
  destroy_channel_elem,
313
- grpc_call_next_get_peer,
314
354
  grpc_channel_next_get_info,
315
355
  "deadline",
316
356
  };
@@ -325,7 +365,6 @@ const grpc_channel_filter grpc_server_deadline_filter = {
325
365
  0, // sizeof(channel_data)
326
366
  init_channel_elem,
327
367
  destroy_channel_elem,
328
- grpc_call_next_get_peer,
329
368
  grpc_channel_next_get_info,
330
369
  "deadline",
331
370
  };