Browse Source

Merge branch 'master' of github.com:grpc/grpc into compression_md_level_bis

David Garcia Quintas 10 năm trước cách đây
mục cha
commit
533add5a87
100 tập tin đã thay đổi với 1884 bổ sung1143 xóa
  1. 350 25
      BUILD
  2. 322 25
      Makefile
  3. 1 3
      binding.gyp
  4. 49 21
      build.yaml
  5. 1 5
      config.m4
  6. 3 6
      gRPC.podspec
  7. 0 1
      grpc.def
  8. 2 5
      grpc.gemspec
  9. 1 0
      include/grpc++/impl/codegen/async_stream.h
  10. 1 0
      include/grpc++/impl/codegen/async_unary_call.h
  11. 20 4
      include/grpc++/impl/codegen/call.h
  12. 1 1
      include/grpc++/impl/codegen/core_codegen_interface.h
  13. 1 0
      include/grpc++/impl/codegen/sync_stream.h
  14. 0 39
      include/grpc++/support/config_protobuf.h
  15. 2 5
      package.xml
  16. 9 2
      src/compiler/config.h
  17. 7 109
      src/compiler/csharp_generator.cc
  18. 2 2
      src/core/ext/census/grpc_filter.c
  19. 6 5
      src/core/ext/client_config/client_channel.c
  20. 2 2
      src/core/ext/client_config/lb_policy.c
  21. 4 2
      src/core/ext/client_config/lb_policy.h
  22. 2 2
      src/core/ext/client_config/subchannel.c
  23. 2 1
      src/core/ext/client_config/subchannel.h
  24. 3 2
      src/core/ext/client_config/subchannel_call_holder.c
  25. 2 1
      src/core/ext/client_config/subchannel_call_holder.h
  26. 14 12
      src/core/ext/lb_policy/pick_first/pick_first.c
  27. 12 10
      src/core/ext/lb_policy/round_robin/round_robin.c
  28. 1 1
      src/core/ext/load_reporting/load_reporting_filter.c
  29. 8 0
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  30. 14 4
      src/core/ext/transport/cronet/transport/cronet_transport.c
  31. 8 7
      src/core/lib/channel/channel_stack.c
  32. 14 11
      src/core/lib/channel/channel_stack.h
  33. 1 1
      src/core/lib/channel/compress_filter.c
  34. 6 5
      src/core/lib/channel/connected_channel.c
  35. 1 1
      src/core/lib/channel/http_client_filter.c
  36. 1 1
      src/core/lib/channel/http_server_filter.c
  37. 12 11
      src/core/lib/http/httpcli.c
  38. 3 2
      src/core/lib/http/httpcli.h
  39. 104 0
      src/core/lib/iomgr/polling_entity.c
  40. 81 0
      src/core/lib/iomgr/polling_entity.h
  41. 4 1
      src/core/lib/iomgr/pollset_set_windows.c
  42. 2 1
      src/core/lib/iomgr/timer.c
  43. 7 6
      src/core/lib/security/credentials/composite/composite_credentials.c
  44. 2 2
      src/core/lib/security/credentials/credentials.c
  45. 4 2
      src/core/lib/security/credentials/credentials.h
  46. 1 1
      src/core/lib/security/credentials/fake/fake_credentials.c
  47. 15 10
      src/core/lib/security/credentials/google_default/google_default_credentials.c
  48. 1 1
      src/core/lib/security/credentials/iam/iam_credentials.c
  49. 1 1
      src/core/lib/security/credentials/jwt/jwt_credentials.c
  50. 7 4
      src/core/lib/security/credentials/jwt/jwt_verifier.c
  51. 7 7
      src/core/lib/security/credentials/oauth2/oauth2_credentials.c
  52. 1 1
      src/core/lib/security/credentials/oauth2/oauth2_credentials.h
  53. 1 1
      src/core/lib/security/credentials/plugin/plugin_credentials.c
  54. 22 15
      src/core/lib/security/transport/client_auth_filter.c
  55. 11 7
      src/core/lib/security/transport/server_auth_filter.c
  56. 27 11
      src/core/lib/surface/call.c
  57. 2 0
      src/core/lib/surface/call.h
  58. 24 6
      src/core/lib/surface/channel.c
  59. 5 0
      src/core/lib/surface/channel.h
  60. 1 1
      src/core/lib/surface/lame_client.c
  61. 4 4
      src/core/lib/surface/server.c
  62. 13 4
      src/core/lib/transport/transport.c
  63. 3 3
      src/core/lib/transport/transport.h
  64. 4 0
      src/core/lib/transport/transport_impl.h
  65. 12 5
      src/core/plugin_registry/grpc_cronet_plugin_registry.c
  66. 90 0
      src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs
  67. 3 3
      src/csharp/Grpc.Core.Tests/ChannelTest.cs
  68. 4 0
      src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
  69. 6 6
      src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs
  70. 2 2
      src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs
  71. 1 1
      src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
  72. 1 1
      src/csharp/Grpc.Core.Tests/PInvokeTest.cs
  73. 1 1
      src/csharp/Grpc.Core.Tests/ServerTest.cs
  74. 57 0
      src/csharp/Grpc.Core.Tests/ShutdownHookClientTest.cs
  75. 69 0
      src/csharp/Grpc.Core.Tests/ShutdownHookPendingCallTest.cs
  76. 58 0
      src/csharp/Grpc.Core.Tests/ShutdownHookServerTest.cs
  77. 4 0
      src/csharp/Grpc.Core/AsyncClientStreamingCall.cs
  78. 4 0
      src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs
  79. 4 0
      src/csharp/Grpc.Core/AsyncServerStreamingCall.cs
  80. 4 0
      src/csharp/Grpc.Core/AsyncUnaryCall.cs
  81. 7 1
      src/csharp/Grpc.Core/CallOptions.cs
  82. 43 12
      src/csharp/Grpc.Core/Channel.cs
  83. 1 1
      src/csharp/Grpc.Core/ChannelState.cs
  84. 115 6
      src/csharp/Grpc.Core/GrpcEnvironment.cs
  85. 26 2
      src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
  86. 68 31
      src/csharp/Grpc.Core/Server.cs
  87. 3 7
      src/csharp/Grpc.Core/ServerServiceDefinition.cs
  88. 15 122
      src/csharp/Grpc.Examples/MathGrpc.cs
  89. 2 32
      src/csharp/Grpc.HealthCheck/HealthGrpc.cs
  90. 1 1
      src/csharp/Grpc.IntegrationTesting/GenericService.cs
  91. 2 63
      src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
  92. 4 192
      src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
  93. 6 226
      src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
  94. 4 0
      src/csharp/tests.json
  95. 2 0
      src/objective-c/GRPCClient/GRPCCall+Cronet.h
  96. 2 0
      src/objective-c/GRPCClient/GRPCCall+Cronet.m
  97. 2 1
      src/objective-c/GRPCClient/private/GRPCChannel.h
  98. 8 0
      src/objective-c/GRPCClient/private/GRPCChannel.m
  99. 8 1
      src/objective-c/GRPCClient/private/GRPCHost.m
  100. 3 3
      src/proto/math/math.proto

+ 350 - 25
BUILD

@@ -187,6 +187,7 @@ cc_library(
     "src/core/lib/iomgr/iomgr.h",
     "src/core/lib/iomgr/iomgr.h",
     "src/core/lib/iomgr/iomgr_internal.h",
     "src/core/lib/iomgr/iomgr_internal.h",
     "src/core/lib/iomgr/iomgr_posix.h",
     "src/core/lib/iomgr/iomgr_posix.h",
+    "src/core/lib/iomgr/polling_entity.h",
     "src/core/lib/iomgr/pollset.h",
     "src/core/lib/iomgr/pollset.h",
     "src/core/lib/iomgr/pollset_set.h",
     "src/core/lib/iomgr/pollset_set.h",
     "src/core/lib/iomgr/pollset_set_windows.h",
     "src/core/lib/iomgr/pollset_set_windows.h",
@@ -295,7 +296,6 @@ cc_library(
     "src/core/ext/client_config/subchannel_call_holder.h",
     "src/core/ext/client_config/subchannel_call_holder.h",
     "src/core/ext/client_config/subchannel_index.h",
     "src/core/ext/client_config/subchannel_index.h",
     "src/core/ext/client_config/uri_parser.h",
     "src/core/ext/client_config/uri_parser.h",
-    "third_party/objective_c/Cronet/cronet_c_for_grpc.h",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
     "src/core/ext/load_reporting/load_reporting.h",
     "src/core/ext/load_reporting/load_reporting.h",
@@ -334,6 +334,7 @@ cc_library(
     "src/core/lib/iomgr/iomgr.c",
     "src/core/lib/iomgr/iomgr.c",
     "src/core/lib/iomgr/iomgr_posix.c",
     "src/core/lib/iomgr/iomgr_posix.c",
     "src/core/lib/iomgr/iomgr_windows.c",
     "src/core/lib/iomgr/iomgr_windows.c",
+    "src/core/lib/iomgr/polling_entity.c",
     "src/core/lib/iomgr/pollset_set_windows.c",
     "src/core/lib/iomgr/pollset_set_windows.c",
     "src/core/lib/iomgr/pollset_windows.c",
     "src/core/lib/iomgr/pollset_windows.c",
     "src/core/lib/iomgr/resolve_address_posix.c",
     "src/core/lib/iomgr/resolve_address_posix.c",
@@ -462,9 +463,6 @@ cc_library(
     "src/core/ext/client_config/uri_parser.c",
     "src/core/ext/client_config/uri_parser.c",
     "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
     "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
     "src/core/ext/transport/chttp2/client/insecure/channel_create.c",
     "src/core/ext/transport/chttp2/client/insecure/channel_create.c",
-    "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c",
-    "src/core/ext/transport/cronet/transport/cronet_api_dummy.c",
-    "src/core/ext/transport/cronet/transport/cronet_transport.c",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
     "src/core/ext/lb_policy/pick_first/pick_first.c",
     "src/core/ext/lb_policy/pick_first/pick_first.c",
@@ -512,7 +510,6 @@ cc_library(
     "include/grpc/impl/codegen/sync_posix.h",
     "include/grpc/impl/codegen/sync_posix.h",
     "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/time.h",
     "include/grpc/impl/codegen/time.h",
-    "include/grpc/grpc_cronet.h",
     "include/grpc/grpc_security.h",
     "include/grpc/grpc_security.h",
     "include/grpc/grpc_security_constants.h",
     "include/grpc/grpc_security_constants.h",
     "include/grpc/census.h",
     "include/grpc/census.h",
@@ -534,6 +531,346 @@ cc_library(
 
 
 
 
 
 
+cc_library(
+  name = "grpc_cronet",
+  srcs = [
+    "src/core/lib/channel/channel_args.h",
+    "src/core/lib/channel/channel_stack.h",
+    "src/core/lib/channel/channel_stack_builder.h",
+    "src/core/lib/channel/compress_filter.h",
+    "src/core/lib/channel/connected_channel.h",
+    "src/core/lib/channel/context.h",
+    "src/core/lib/channel/http_client_filter.h",
+    "src/core/lib/channel/http_server_filter.h",
+    "src/core/lib/compression/algorithm_metadata.h",
+    "src/core/lib/compression/message_compress.h",
+    "src/core/lib/debug/trace.h",
+    "src/core/lib/http/format_request.h",
+    "src/core/lib/http/httpcli.h",
+    "src/core/lib/http/parser.h",
+    "src/core/lib/iomgr/closure.h",
+    "src/core/lib/iomgr/endpoint.h",
+    "src/core/lib/iomgr/endpoint_pair.h",
+    "src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
+    "src/core/lib/iomgr/ev_poll_posix.h",
+    "src/core/lib/iomgr/ev_posix.h",
+    "src/core/lib/iomgr/exec_ctx.h",
+    "src/core/lib/iomgr/executor.h",
+    "src/core/lib/iomgr/iocp_windows.h",
+    "src/core/lib/iomgr/iomgr.h",
+    "src/core/lib/iomgr/iomgr_internal.h",
+    "src/core/lib/iomgr/iomgr_posix.h",
+    "src/core/lib/iomgr/polling_entity.h",
+    "src/core/lib/iomgr/pollset.h",
+    "src/core/lib/iomgr/pollset_set.h",
+    "src/core/lib/iomgr/pollset_set_windows.h",
+    "src/core/lib/iomgr/pollset_windows.h",
+    "src/core/lib/iomgr/resolve_address.h",
+    "src/core/lib/iomgr/sockaddr.h",
+    "src/core/lib/iomgr/sockaddr_posix.h",
+    "src/core/lib/iomgr/sockaddr_utils.h",
+    "src/core/lib/iomgr/sockaddr_windows.h",
+    "src/core/lib/iomgr/socket_utils_posix.h",
+    "src/core/lib/iomgr/socket_windows.h",
+    "src/core/lib/iomgr/tcp_client.h",
+    "src/core/lib/iomgr/tcp_posix.h",
+    "src/core/lib/iomgr/tcp_server.h",
+    "src/core/lib/iomgr/tcp_windows.h",
+    "src/core/lib/iomgr/time_averaged_stats.h",
+    "src/core/lib/iomgr/timer.h",
+    "src/core/lib/iomgr/timer_heap.h",
+    "src/core/lib/iomgr/udp_server.h",
+    "src/core/lib/iomgr/unix_sockets_posix.h",
+    "src/core/lib/iomgr/wakeup_fd_pipe.h",
+    "src/core/lib/iomgr/wakeup_fd_posix.h",
+    "src/core/lib/iomgr/workqueue.h",
+    "src/core/lib/iomgr/workqueue_posix.h",
+    "src/core/lib/iomgr/workqueue_windows.h",
+    "src/core/lib/json/json.h",
+    "src/core/lib/json/json_common.h",
+    "src/core/lib/json/json_reader.h",
+    "src/core/lib/json/json_writer.h",
+    "src/core/lib/surface/api_trace.h",
+    "src/core/lib/surface/call.h",
+    "src/core/lib/surface/call_test_only.h",
+    "src/core/lib/surface/channel.h",
+    "src/core/lib/surface/channel_init.h",
+    "src/core/lib/surface/channel_stack_type.h",
+    "src/core/lib/surface/completion_queue.h",
+    "src/core/lib/surface/event_string.h",
+    "src/core/lib/surface/init.h",
+    "src/core/lib/surface/lame_client.h",
+    "src/core/lib/surface/server.h",
+    "src/core/lib/surface/surface_trace.h",
+    "src/core/lib/transport/byte_stream.h",
+    "src/core/lib/transport/connectivity_state.h",
+    "src/core/lib/transport/metadata.h",
+    "src/core/lib/transport/metadata_batch.h",
+    "src/core/lib/transport/static_metadata.h",
+    "src/core/lib/transport/transport.h",
+    "src/core/lib/transport/transport_impl.h",
+    "third_party/objective_c/Cronet/cronet_c_for_grpc.h",
+    "src/core/ext/transport/chttp2/transport/bin_encoder.h",
+    "src/core/ext/transport/chttp2/transport/chttp2_transport.h",
+    "src/core/ext/transport/chttp2/transport/frame.h",
+    "src/core/ext/transport/chttp2/transport/frame_data.h",
+    "src/core/ext/transport/chttp2/transport/frame_goaway.h",
+    "src/core/ext/transport/chttp2/transport/frame_ping.h",
+    "src/core/ext/transport/chttp2/transport/frame_rst_stream.h",
+    "src/core/ext/transport/chttp2/transport/frame_settings.h",
+    "src/core/ext/transport/chttp2/transport/frame_window_update.h",
+    "src/core/ext/transport/chttp2/transport/hpack_encoder.h",
+    "src/core/ext/transport/chttp2/transport/hpack_parser.h",
+    "src/core/ext/transport/chttp2/transport/hpack_table.h",
+    "src/core/ext/transport/chttp2/transport/http2_errors.h",
+    "src/core/ext/transport/chttp2/transport/huffsyms.h",
+    "src/core/ext/transport/chttp2/transport/incoming_metadata.h",
+    "src/core/ext/transport/chttp2/transport/internal.h",
+    "src/core/ext/transport/chttp2/transport/status_conversion.h",
+    "src/core/ext/transport/chttp2/transport/stream_map.h",
+    "src/core/ext/transport/chttp2/transport/timeout_encoding.h",
+    "src/core/ext/transport/chttp2/transport/varint.h",
+    "src/core/ext/transport/chttp2/alpn/alpn.h",
+    "src/core/ext/client_config/client_channel.h",
+    "src/core/ext/client_config/client_channel_factory.h",
+    "src/core/ext/client_config/client_config.h",
+    "src/core/ext/client_config/connector.h",
+    "src/core/ext/client_config/initial_connect_string.h",
+    "src/core/ext/client_config/lb_policy.h",
+    "src/core/ext/client_config/lb_policy_factory.h",
+    "src/core/ext/client_config/lb_policy_registry.h",
+    "src/core/ext/client_config/parse_address.h",
+    "src/core/ext/client_config/resolver.h",
+    "src/core/ext/client_config/resolver_factory.h",
+    "src/core/ext/client_config/resolver_registry.h",
+    "src/core/ext/client_config/subchannel.h",
+    "src/core/ext/client_config/subchannel_call_holder.h",
+    "src/core/ext/client_config/subchannel_index.h",
+    "src/core/ext/client_config/uri_parser.h",
+    "src/core/lib/security/context/security_context.h",
+    "src/core/lib/security/credentials/composite/composite_credentials.h",
+    "src/core/lib/security/credentials/credentials.h",
+    "src/core/lib/security/credentials/fake/fake_credentials.h",
+    "src/core/lib/security/credentials/google_default/google_default_credentials.h",
+    "src/core/lib/security/credentials/iam/iam_credentials.h",
+    "src/core/lib/security/credentials/jwt/json_token.h",
+    "src/core/lib/security/credentials/jwt/jwt_credentials.h",
+    "src/core/lib/security/credentials/jwt/jwt_verifier.h",
+    "src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
+    "src/core/lib/security/credentials/plugin/plugin_credentials.h",
+    "src/core/lib/security/credentials/ssl/ssl_credentials.h",
+    "src/core/lib/security/transport/auth_filters.h",
+    "src/core/lib/security/transport/handshake.h",
+    "src/core/lib/security/transport/secure_endpoint.h",
+    "src/core/lib/security/transport/security_connector.h",
+    "src/core/lib/security/util/b64.h",
+    "src/core/lib/security/util/json_util.h",
+    "src/core/lib/tsi/fake_transport_security.h",
+    "src/core/lib/tsi/ssl_transport_security.h",
+    "src/core/lib/tsi/ssl_types.h",
+    "src/core/lib/tsi/transport_security.h",
+    "src/core/lib/tsi/transport_security_interface.h",
+    "src/core/lib/surface/init.c",
+    "src/core/lib/channel/channel_args.c",
+    "src/core/lib/channel/channel_stack.c",
+    "src/core/lib/channel/channel_stack_builder.c",
+    "src/core/lib/channel/compress_filter.c",
+    "src/core/lib/channel/connected_channel.c",
+    "src/core/lib/channel/http_client_filter.c",
+    "src/core/lib/channel/http_server_filter.c",
+    "src/core/lib/compression/compression_algorithm.c",
+    "src/core/lib/compression/message_compress.c",
+    "src/core/lib/debug/trace.c",
+    "src/core/lib/http/format_request.c",
+    "src/core/lib/http/httpcli.c",
+    "src/core/lib/http/parser.c",
+    "src/core/lib/iomgr/closure.c",
+    "src/core/lib/iomgr/endpoint.c",
+    "src/core/lib/iomgr/endpoint_pair_posix.c",
+    "src/core/lib/iomgr/endpoint_pair_windows.c",
+    "src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
+    "src/core/lib/iomgr/ev_poll_posix.c",
+    "src/core/lib/iomgr/ev_posix.c",
+    "src/core/lib/iomgr/exec_ctx.c",
+    "src/core/lib/iomgr/executor.c",
+    "src/core/lib/iomgr/iocp_windows.c",
+    "src/core/lib/iomgr/iomgr.c",
+    "src/core/lib/iomgr/iomgr_posix.c",
+    "src/core/lib/iomgr/iomgr_windows.c",
+    "src/core/lib/iomgr/polling_entity.c",
+    "src/core/lib/iomgr/pollset_set_windows.c",
+    "src/core/lib/iomgr/pollset_windows.c",
+    "src/core/lib/iomgr/resolve_address_posix.c",
+    "src/core/lib/iomgr/resolve_address_windows.c",
+    "src/core/lib/iomgr/sockaddr_utils.c",
+    "src/core/lib/iomgr/socket_utils_common_posix.c",
+    "src/core/lib/iomgr/socket_utils_linux.c",
+    "src/core/lib/iomgr/socket_utils_posix.c",
+    "src/core/lib/iomgr/socket_windows.c",
+    "src/core/lib/iomgr/tcp_client_posix.c",
+    "src/core/lib/iomgr/tcp_client_windows.c",
+    "src/core/lib/iomgr/tcp_posix.c",
+    "src/core/lib/iomgr/tcp_server_posix.c",
+    "src/core/lib/iomgr/tcp_server_windows.c",
+    "src/core/lib/iomgr/tcp_windows.c",
+    "src/core/lib/iomgr/time_averaged_stats.c",
+    "src/core/lib/iomgr/timer.c",
+    "src/core/lib/iomgr/timer_heap.c",
+    "src/core/lib/iomgr/udp_server.c",
+    "src/core/lib/iomgr/unix_sockets_posix.c",
+    "src/core/lib/iomgr/unix_sockets_posix_noop.c",
+    "src/core/lib/iomgr/wakeup_fd_eventfd.c",
+    "src/core/lib/iomgr/wakeup_fd_nospecial.c",
+    "src/core/lib/iomgr/wakeup_fd_pipe.c",
+    "src/core/lib/iomgr/wakeup_fd_posix.c",
+    "src/core/lib/iomgr/workqueue_posix.c",
+    "src/core/lib/iomgr/workqueue_windows.c",
+    "src/core/lib/json/json.c",
+    "src/core/lib/json/json_reader.c",
+    "src/core/lib/json/json_string.c",
+    "src/core/lib/json/json_writer.c",
+    "src/core/lib/surface/alarm.c",
+    "src/core/lib/surface/api_trace.c",
+    "src/core/lib/surface/byte_buffer.c",
+    "src/core/lib/surface/byte_buffer_reader.c",
+    "src/core/lib/surface/call.c",
+    "src/core/lib/surface/call_details.c",
+    "src/core/lib/surface/call_log_batch.c",
+    "src/core/lib/surface/channel.c",
+    "src/core/lib/surface/channel_init.c",
+    "src/core/lib/surface/channel_ping.c",
+    "src/core/lib/surface/channel_stack_type.c",
+    "src/core/lib/surface/completion_queue.c",
+    "src/core/lib/surface/event_string.c",
+    "src/core/lib/surface/lame_client.c",
+    "src/core/lib/surface/metadata_array.c",
+    "src/core/lib/surface/server.c",
+    "src/core/lib/surface/validate_metadata.c",
+    "src/core/lib/surface/version.c",
+    "src/core/lib/transport/byte_stream.c",
+    "src/core/lib/transport/connectivity_state.c",
+    "src/core/lib/transport/metadata.c",
+    "src/core/lib/transport/metadata_batch.c",
+    "src/core/lib/transport/static_metadata.c",
+    "src/core/lib/transport/transport.c",
+    "src/core/lib/transport/transport_op_string.c",
+    "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c",
+    "src/core/ext/transport/cronet/transport/cronet_api_dummy.c",
+    "src/core/ext/transport/cronet/transport/cronet_transport.c",
+    "src/core/ext/transport/chttp2/client/secure/secure_channel_create.c",
+    "src/core/ext/transport/chttp2/transport/bin_encoder.c",
+    "src/core/ext/transport/chttp2/transport/chttp2_plugin.c",
+    "src/core/ext/transport/chttp2/transport/chttp2_transport.c",
+    "src/core/ext/transport/chttp2/transport/frame_data.c",
+    "src/core/ext/transport/chttp2/transport/frame_goaway.c",
+    "src/core/ext/transport/chttp2/transport/frame_ping.c",
+    "src/core/ext/transport/chttp2/transport/frame_rst_stream.c",
+    "src/core/ext/transport/chttp2/transport/frame_settings.c",
+    "src/core/ext/transport/chttp2/transport/frame_window_update.c",
+    "src/core/ext/transport/chttp2/transport/hpack_encoder.c",
+    "src/core/ext/transport/chttp2/transport/hpack_parser.c",
+    "src/core/ext/transport/chttp2/transport/hpack_table.c",
+    "src/core/ext/transport/chttp2/transport/huffsyms.c",
+    "src/core/ext/transport/chttp2/transport/incoming_metadata.c",
+    "src/core/ext/transport/chttp2/transport/parsing.c",
+    "src/core/ext/transport/chttp2/transport/status_conversion.c",
+    "src/core/ext/transport/chttp2/transport/stream_lists.c",
+    "src/core/ext/transport/chttp2/transport/stream_map.c",
+    "src/core/ext/transport/chttp2/transport/timeout_encoding.c",
+    "src/core/ext/transport/chttp2/transport/varint.c",
+    "src/core/ext/transport/chttp2/transport/writing.c",
+    "src/core/ext/transport/chttp2/alpn/alpn.c",
+    "src/core/ext/client_config/channel_connectivity.c",
+    "src/core/ext/client_config/client_channel.c",
+    "src/core/ext/client_config/client_channel_factory.c",
+    "src/core/ext/client_config/client_config.c",
+    "src/core/ext/client_config/client_config_plugin.c",
+    "src/core/ext/client_config/connector.c",
+    "src/core/ext/client_config/default_initial_connect_string.c",
+    "src/core/ext/client_config/initial_connect_string.c",
+    "src/core/ext/client_config/lb_policy.c",
+    "src/core/ext/client_config/lb_policy_factory.c",
+    "src/core/ext/client_config/lb_policy_registry.c",
+    "src/core/ext/client_config/parse_address.c",
+    "src/core/ext/client_config/resolver.c",
+    "src/core/ext/client_config/resolver_factory.c",
+    "src/core/ext/client_config/resolver_registry.c",
+    "src/core/ext/client_config/subchannel.c",
+    "src/core/ext/client_config/subchannel_call_holder.c",
+    "src/core/ext/client_config/subchannel_index.c",
+    "src/core/ext/client_config/uri_parser.c",
+    "src/core/lib/http/httpcli_security_connector.c",
+    "src/core/lib/security/context/security_context.c",
+    "src/core/lib/security/credentials/composite/composite_credentials.c",
+    "src/core/lib/security/credentials/credentials.c",
+    "src/core/lib/security/credentials/credentials_metadata.c",
+    "src/core/lib/security/credentials/fake/fake_credentials.c",
+    "src/core/lib/security/credentials/google_default/credentials_posix.c",
+    "src/core/lib/security/credentials/google_default/credentials_windows.c",
+    "src/core/lib/security/credentials/google_default/google_default_credentials.c",
+    "src/core/lib/security/credentials/iam/iam_credentials.c",
+    "src/core/lib/security/credentials/jwt/json_token.c",
+    "src/core/lib/security/credentials/jwt/jwt_credentials.c",
+    "src/core/lib/security/credentials/jwt/jwt_verifier.c",
+    "src/core/lib/security/credentials/oauth2/oauth2_credentials.c",
+    "src/core/lib/security/credentials/plugin/plugin_credentials.c",
+    "src/core/lib/security/credentials/ssl/ssl_credentials.c",
+    "src/core/lib/security/transport/client_auth_filter.c",
+    "src/core/lib/security/transport/handshake.c",
+    "src/core/lib/security/transport/secure_endpoint.c",
+    "src/core/lib/security/transport/security_connector.c",
+    "src/core/lib/security/transport/server_auth_filter.c",
+    "src/core/lib/security/util/b64.c",
+    "src/core/lib/security/util/json_util.c",
+    "src/core/lib/surface/init_secure.c",
+    "src/core/lib/tsi/fake_transport_security.c",
+    "src/core/lib/tsi/ssl_transport_security.c",
+    "src/core/lib/tsi/transport_security.c",
+    "src/core/plugin_registry/grpc_cronet_plugin_registry.c",
+  ],
+  hdrs = [
+    "include/grpc/byte_buffer.h",
+    "include/grpc/byte_buffer_reader.h",
+    "include/grpc/compression.h",
+    "include/grpc/grpc.h",
+    "include/grpc/status.h",
+    "include/grpc/impl/codegen/byte_buffer.h",
+    "include/grpc/impl/codegen/byte_buffer_reader.h",
+    "include/grpc/impl/codegen/compression_types.h",
+    "include/grpc/impl/codegen/connectivity_state.h",
+    "include/grpc/impl/codegen/grpc_types.h",
+    "include/grpc/impl/codegen/propagation_bits.h",
+    "include/grpc/impl/codegen/status.h",
+    "include/grpc/impl/codegen/alloc.h",
+    "include/grpc/impl/codegen/atm.h",
+    "include/grpc/impl/codegen/atm_gcc_atomic.h",
+    "include/grpc/impl/codegen/atm_gcc_sync.h",
+    "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/port_platform.h",
+    "include/grpc/impl/codegen/slice.h",
+    "include/grpc/impl/codegen/slice_buffer.h",
+    "include/grpc/impl/codegen/sync.h",
+    "include/grpc/impl/codegen/sync_generic.h",
+    "include/grpc/impl/codegen/sync_posix.h",
+    "include/grpc/impl/codegen/sync_windows.h",
+    "include/grpc/impl/codegen/time.h",
+    "include/grpc/grpc_cronet.h",
+    "include/grpc/grpc_security.h",
+    "include/grpc/grpc_security_constants.h",
+  ],
+  includes = [
+    "include",
+    ".",
+  ],
+  deps = [
+    "//external:libssl",
+    ":gpr",
+  ],
+)
+
+
+
 cc_library(
 cc_library(
   name = "grpc_unsecure",
   name = "grpc_unsecure",
   srcs = [
   srcs = [
@@ -563,6 +900,7 @@ cc_library(
     "src/core/lib/iomgr/iomgr.h",
     "src/core/lib/iomgr/iomgr.h",
     "src/core/lib/iomgr/iomgr_internal.h",
     "src/core/lib/iomgr/iomgr_internal.h",
     "src/core/lib/iomgr/iomgr_posix.h",
     "src/core/lib/iomgr/iomgr_posix.h",
+    "src/core/lib/iomgr/polling_entity.h",
     "src/core/lib/iomgr/pollset.h",
     "src/core/lib/iomgr/pollset.h",
     "src/core/lib/iomgr/pollset_set.h",
     "src/core/lib/iomgr/pollset_set.h",
     "src/core/lib/iomgr/pollset_set_windows.h",
     "src/core/lib/iomgr/pollset_set_windows.h",
@@ -687,6 +1025,7 @@ cc_library(
     "src/core/lib/iomgr/iomgr.c",
     "src/core/lib/iomgr/iomgr.c",
     "src/core/lib/iomgr/iomgr_posix.c",
     "src/core/lib/iomgr/iomgr_posix.c",
     "src/core/lib/iomgr/iomgr_windows.c",
     "src/core/lib/iomgr/iomgr_windows.c",
+    "src/core/lib/iomgr/polling_entity.c",
     "src/core/lib/iomgr/pollset_set_windows.c",
     "src/core/lib/iomgr/pollset_set_windows.c",
     "src/core/lib/iomgr/pollset_windows.c",
     "src/core/lib/iomgr/pollset_windows.c",
     "src/core/lib/iomgr/resolve_address_posix.c",
     "src/core/lib/iomgr/resolve_address_posix.c",
@@ -925,7 +1264,6 @@ cc_library(
     "include/grpc++/impl/client_unary_call.h",
     "include/grpc++/impl/client_unary_call.h",
     "include/grpc++/impl/grpc_library.h",
     "include/grpc++/impl/grpc_library.h",
     "include/grpc++/impl/method_handler_impl.h",
     "include/grpc++/impl/method_handler_impl.h",
-    "include/grpc++/impl/proto_utils.h",
     "include/grpc++/impl/rpc_method.h",
     "include/grpc++/impl/rpc_method.h",
     "include/grpc++/impl/rpc_service_method.h",
     "include/grpc++/impl/rpc_service_method.h",
     "include/grpc++/impl/serialization_traits.h",
     "include/grpc++/impl/serialization_traits.h",
@@ -950,6 +1288,7 @@ cc_library(
     "include/grpc++/support/async_unary_call.h",
     "include/grpc++/support/async_unary_call.h",
     "include/grpc++/support/byte_buffer.h",
     "include/grpc++/support/byte_buffer.h",
     "include/grpc++/support/channel_arguments.h",
     "include/grpc++/support/channel_arguments.h",
+    "include/grpc++/support/config.h",
     "include/grpc++/support/slice.h",
     "include/grpc++/support/slice.h",
     "include/grpc++/support/status.h",
     "include/grpc++/support/status.h",
     "include/grpc++/support/status_code_enum.h",
     "include/grpc++/support/status_code_enum.h",
@@ -966,11 +1305,11 @@ cc_library(
     "include/grpc++/impl/codegen/client_unary_call.h",
     "include/grpc++/impl/codegen/client_unary_call.h",
     "include/grpc++/impl/codegen/completion_queue.h",
     "include/grpc++/impl/codegen/completion_queue.h",
     "include/grpc++/impl/codegen/completion_queue_tag.h",
     "include/grpc++/impl/codegen/completion_queue_tag.h",
+    "include/grpc++/impl/codegen/config.h",
     "include/grpc++/impl/codegen/core_codegen_interface.h",
     "include/grpc++/impl/codegen/core_codegen_interface.h",
     "include/grpc++/impl/codegen/create_auth_context.h",
     "include/grpc++/impl/codegen/create_auth_context.h",
     "include/grpc++/impl/codegen/grpc_library.h",
     "include/grpc++/impl/codegen/grpc_library.h",
     "include/grpc++/impl/codegen/method_handler_impl.h",
     "include/grpc++/impl/codegen/method_handler_impl.h",
-    "include/grpc++/impl/codegen/proto_utils.h",
     "include/grpc++/impl/codegen/rpc_method.h",
     "include/grpc++/impl/codegen/rpc_method.h",
     "include/grpc++/impl/codegen/rpc_service_method.h",
     "include/grpc++/impl/codegen/rpc_service_method.h",
     "include/grpc++/impl/codegen/security/auth_context.h",
     "include/grpc++/impl/codegen/security/auth_context.h",
@@ -1008,10 +1347,6 @@ cc_library(
     "include/grpc/impl/codegen/sync_posix.h",
     "include/grpc/impl/codegen/sync_posix.h",
     "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/time.h",
     "include/grpc/impl/codegen/time.h",
-    "include/grpc++/impl/codegen/config.h",
-    "include/grpc++/impl/codegen/config_protobuf.h",
-    "include/grpc++/support/config.h",
-    "include/grpc++/support/config_protobuf.h",
   ],
   ],
   includes = [
   includes = [
     "include",
     "include",
@@ -1073,7 +1408,6 @@ cc_library(
     "include/grpc++/impl/client_unary_call.h",
     "include/grpc++/impl/client_unary_call.h",
     "include/grpc++/impl/grpc_library.h",
     "include/grpc++/impl/grpc_library.h",
     "include/grpc++/impl/method_handler_impl.h",
     "include/grpc++/impl/method_handler_impl.h",
-    "include/grpc++/impl/proto_utils.h",
     "include/grpc++/impl/rpc_method.h",
     "include/grpc++/impl/rpc_method.h",
     "include/grpc++/impl/rpc_service_method.h",
     "include/grpc++/impl/rpc_service_method.h",
     "include/grpc++/impl/serialization_traits.h",
     "include/grpc++/impl/serialization_traits.h",
@@ -1098,6 +1432,7 @@ cc_library(
     "include/grpc++/support/async_unary_call.h",
     "include/grpc++/support/async_unary_call.h",
     "include/grpc++/support/byte_buffer.h",
     "include/grpc++/support/byte_buffer.h",
     "include/grpc++/support/channel_arguments.h",
     "include/grpc++/support/channel_arguments.h",
+    "include/grpc++/support/config.h",
     "include/grpc++/support/slice.h",
     "include/grpc++/support/slice.h",
     "include/grpc++/support/status.h",
     "include/grpc++/support/status.h",
     "include/grpc++/support/status_code_enum.h",
     "include/grpc++/support/status_code_enum.h",
@@ -1114,11 +1449,11 @@ cc_library(
     "include/grpc++/impl/codegen/client_unary_call.h",
     "include/grpc++/impl/codegen/client_unary_call.h",
     "include/grpc++/impl/codegen/completion_queue.h",
     "include/grpc++/impl/codegen/completion_queue.h",
     "include/grpc++/impl/codegen/completion_queue_tag.h",
     "include/grpc++/impl/codegen/completion_queue_tag.h",
+    "include/grpc++/impl/codegen/config.h",
     "include/grpc++/impl/codegen/core_codegen_interface.h",
     "include/grpc++/impl/codegen/core_codegen_interface.h",
     "include/grpc++/impl/codegen/create_auth_context.h",
     "include/grpc++/impl/codegen/create_auth_context.h",
     "include/grpc++/impl/codegen/grpc_library.h",
     "include/grpc++/impl/codegen/grpc_library.h",
     "include/grpc++/impl/codegen/method_handler_impl.h",
     "include/grpc++/impl/codegen/method_handler_impl.h",
-    "include/grpc++/impl/codegen/proto_utils.h",
     "include/grpc++/impl/codegen/rpc_method.h",
     "include/grpc++/impl/codegen/rpc_method.h",
     "include/grpc++/impl/codegen/rpc_service_method.h",
     "include/grpc++/impl/codegen/rpc_service_method.h",
     "include/grpc++/impl/codegen/security/auth_context.h",
     "include/grpc++/impl/codegen/security/auth_context.h",
@@ -1156,10 +1491,6 @@ cc_library(
     "include/grpc/impl/codegen/sync_posix.h",
     "include/grpc/impl/codegen/sync_posix.h",
     "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/time.h",
     "include/grpc/impl/codegen/time.h",
-    "include/grpc++/impl/codegen/config.h",
-    "include/grpc++/impl/codegen/config_protobuf.h",
-    "include/grpc++/support/config.h",
-    "include/grpc++/support/config_protobuf.h",
   ],
   ],
   includes = [
   includes = [
     "include",
     "include",
@@ -1201,9 +1532,6 @@ cc_library(
     "src/compiler/ruby_generator.cc",
     "src/compiler/ruby_generator.cc",
   ],
   ],
   hdrs = [
   hdrs = [
-    "include/grpc++/support/config.h",
-    "include/grpc++/support/config_protobuf.h",
-    "include/grpc++/impl/codegen/config.h",
     "include/grpc++/impl/codegen/config_protobuf.h",
     "include/grpc++/impl/codegen/config_protobuf.h",
   ],
   ],
   includes = [
   includes = [
@@ -1383,6 +1711,7 @@ objc_library(
     "src/core/lib/iomgr/iomgr.c",
     "src/core/lib/iomgr/iomgr.c",
     "src/core/lib/iomgr/iomgr_posix.c",
     "src/core/lib/iomgr/iomgr_posix.c",
     "src/core/lib/iomgr/iomgr_windows.c",
     "src/core/lib/iomgr/iomgr_windows.c",
+    "src/core/lib/iomgr/polling_entity.c",
     "src/core/lib/iomgr/pollset_set_windows.c",
     "src/core/lib/iomgr/pollset_set_windows.c",
     "src/core/lib/iomgr/pollset_windows.c",
     "src/core/lib/iomgr/pollset_windows.c",
     "src/core/lib/iomgr/resolve_address_posix.c",
     "src/core/lib/iomgr/resolve_address_posix.c",
@@ -1511,9 +1840,6 @@ objc_library(
     "src/core/ext/client_config/uri_parser.c",
     "src/core/ext/client_config/uri_parser.c",
     "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
     "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
     "src/core/ext/transport/chttp2/client/insecure/channel_create.c",
     "src/core/ext/transport/chttp2/client/insecure/channel_create.c",
-    "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c",
-    "src/core/ext/transport/cronet/transport/cronet_api_dummy.c",
-    "src/core/ext/transport/cronet/transport/cronet_transport.c",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
     "src/core/ext/lb_policy/pick_first/pick_first.c",
     "src/core/ext/lb_policy/pick_first/pick_first.c",
@@ -1561,7 +1887,6 @@ objc_library(
     "include/grpc/impl/codegen/sync_posix.h",
     "include/grpc/impl/codegen/sync_posix.h",
     "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/time.h",
     "include/grpc/impl/codegen/time.h",
-    "include/grpc/grpc_cronet.h",
     "include/grpc/grpc_security.h",
     "include/grpc/grpc_security.h",
     "include/grpc/grpc_security_constants.h",
     "include/grpc/grpc_security_constants.h",
     "include/grpc/census.h",
     "include/grpc/census.h",
@@ -1591,6 +1916,7 @@ objc_library(
     "src/core/lib/iomgr/iomgr.h",
     "src/core/lib/iomgr/iomgr.h",
     "src/core/lib/iomgr/iomgr_internal.h",
     "src/core/lib/iomgr/iomgr_internal.h",
     "src/core/lib/iomgr/iomgr_posix.h",
     "src/core/lib/iomgr/iomgr_posix.h",
+    "src/core/lib/iomgr/polling_entity.h",
     "src/core/lib/iomgr/pollset.h",
     "src/core/lib/iomgr/pollset.h",
     "src/core/lib/iomgr/pollset_set.h",
     "src/core/lib/iomgr/pollset_set.h",
     "src/core/lib/iomgr/pollset_set_windows.h",
     "src/core/lib/iomgr/pollset_set_windows.h",
@@ -1699,7 +2025,6 @@ objc_library(
     "src/core/ext/client_config/subchannel_call_holder.h",
     "src/core/ext/client_config/subchannel_call_holder.h",
     "src/core/ext/client_config/subchannel_index.h",
     "src/core/ext/client_config/subchannel_index.h",
     "src/core/ext/client_config/uri_parser.h",
     "src/core/ext/client_config/uri_parser.h",
-    "third_party/objective_c/Cronet/cronet_c_for_grpc.h",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
     "src/core/ext/load_reporting/load_reporting.h",
     "src/core/ext/load_reporting/load_reporting.h",

+ 322 - 25
Makefile

@@ -1163,14 +1163,14 @@ $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a: third_party/protobuf/configure
 
 
 static: static_c static_cxx
 static: static_c static_cxx
 
 
-static_c: pc_c pc_c_unsecure cache.mk pc_c_zookeeper $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a static_zookeeper_libs
+static_c: pc_c pc_c_unsecure cache.mk pc_c_zookeeper $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a static_zookeeper_libs
 
 
 
 
 static_cxx: pc_cxx pc_cxx_unsecure cache.mk  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
 static_cxx: pc_cxx pc_cxx_unsecure cache.mk  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
 
 
 shared: shared_c shared_cxx
 shared: shared_c shared_cxx
 
 
-shared_c: pc_c pc_c_unsecure cache.mk pc_c_zookeeper $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT) shared_zookeeper_libs
+shared_c: pc_c pc_c_unsecure cache.mk pc_c_zookeeper $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT) shared_zookeeper_libs
 
 
 shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT)
 shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT)
 
 
@@ -1791,6 +1791,8 @@ ifeq ($(CONFIG),opt)
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[STRIP]   Stripping libgrpc.a"
 	$(E) "[STRIP]   Stripping libgrpc.a"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc.a
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc.a
+	$(E) "[STRIP]   Stripping libgrpc_cronet.a"
+	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a
 	$(E) "[STRIP]   Stripping libgrpc_unsecure.a"
 	$(E) "[STRIP]   Stripping libgrpc_unsecure.a"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
 ifeq ($(HAS_ZOOKEEPER),true)
 ifeq ($(HAS_ZOOKEEPER),true)
@@ -1813,6 +1815,8 @@ ifeq ($(CONFIG),opt)
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT)
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT)
 	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT)"
 	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT)"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT)
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT)
+	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT)"
+	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT)
 	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT)"
 	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT)"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT)
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT)
 ifeq ($(HAS_ZOOKEEPER),true)
 ifeq ($(HAS_ZOOKEEPER),true)
@@ -2123,6 +2127,9 @@ install-static_c: static_c strip-static_c install-pkg-config_c
 	$(E) "[INSTALL] Installing libgrpc.a"
 	$(E) "[INSTALL] Installing libgrpc.a"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc.a $(prefix)/lib/libgrpc.a
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc.a $(prefix)/lib/libgrpc.a
+	$(E) "[INSTALL] Installing libgrpc_cronet.a"
+	$(Q) $(INSTALL) -d $(prefix)/lib
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(prefix)/lib/libgrpc_cronet.a
 	$(E) "[INSTALL] Installing libgrpc_unsecure.a"
 	$(E) "[INSTALL] Installing libgrpc_unsecure.a"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(prefix)/lib/libgrpc_unsecure.a
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(prefix)/lib/libgrpc_unsecure.a
@@ -2160,6 +2167,15 @@ ifeq ($(SYSTEM),MINGW32)
 else ifneq ($(SYSTEM),Darwin)
 else ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc.so.0
 	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc.so.0
 	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc.so
 	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc.so
+endif
+	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT)"
+	$(Q) $(INSTALL) -d $(prefix)/lib
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT)
+ifeq ($(SYSTEM),MINGW32)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_cronet-imp.a $(prefix)/lib/libgrpc_cronet-imp.a
+else ifneq ($(SYSTEM),Darwin)
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc_cronet.so.0
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc_cronet.so
 endif
 endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT)"
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) -d $(prefix)/lib
@@ -2486,6 +2502,7 @@ LIBGRPC_SRC = \
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr_posix.c \
     src/core/lib/iomgr/iomgr_posix.c \
     src/core/lib/iomgr/iomgr_windows.c \
     src/core/lib/iomgr/iomgr_windows.c \
+    src/core/lib/iomgr/polling_entity.c \
     src/core/lib/iomgr/pollset_set_windows.c \
     src/core/lib/iomgr/pollset_set_windows.c \
     src/core/lib/iomgr/pollset_windows.c \
     src/core/lib/iomgr/pollset_windows.c \
     src/core/lib/iomgr/resolve_address_posix.c \
     src/core/lib/iomgr/resolve_address_posix.c \
@@ -2614,9 +2631,6 @@ LIBGRPC_SRC = \
     src/core/ext/client_config/uri_parser.c \
     src/core/ext/client_config/uri_parser.c \
     src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
     src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
     src/core/ext/transport/chttp2/client/insecure/channel_create.c \
     src/core/ext/transport/chttp2/client/insecure/channel_create.c \
-    src/core/ext/transport/cronet/client/secure/cronet_channel_create.c \
-    src/core/ext/transport/cronet/transport/cronet_api_dummy.c \
-    src/core/ext/transport/cronet/transport/cronet_transport.c \
     src/core/ext/lb_policy/grpclb/load_balancer_api.c \
     src/core/ext/lb_policy/grpclb/load_balancer_api.c \
     src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     third_party/nanopb/pb_common.c \
     third_party/nanopb/pb_common.c \
@@ -2667,7 +2681,6 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/sync_posix.h \
     include/grpc/impl/codegen/sync_posix.h \
     include/grpc/impl/codegen/sync_windows.h \
     include/grpc/impl/codegen/sync_windows.h \
     include/grpc/impl/codegen/time.h \
     include/grpc/impl/codegen/time.h \
-    include/grpc/grpc_cronet.h \
     include/grpc/grpc_security.h \
     include/grpc/grpc_security.h \
     include/grpc/grpc_security_constants.h \
     include/grpc/grpc_security_constants.h \
     include/grpc/census.h \
     include/grpc/census.h \
@@ -2724,6 +2737,248 @@ endif
 endif
 endif
 
 
 
 
+LIBGRPC_CRONET_SRC = \
+    src/core/lib/surface/init.c \
+    src/core/lib/channel/channel_args.c \
+    src/core/lib/channel/channel_stack.c \
+    src/core/lib/channel/channel_stack_builder.c \
+    src/core/lib/channel/compress_filter.c \
+    src/core/lib/channel/connected_channel.c \
+    src/core/lib/channel/http_client_filter.c \
+    src/core/lib/channel/http_server_filter.c \
+    src/core/lib/compression/compression_algorithm.c \
+    src/core/lib/compression/message_compress.c \
+    src/core/lib/debug/trace.c \
+    src/core/lib/http/format_request.c \
+    src/core/lib/http/httpcli.c \
+    src/core/lib/http/parser.c \
+    src/core/lib/iomgr/closure.c \
+    src/core/lib/iomgr/endpoint.c \
+    src/core/lib/iomgr/endpoint_pair_posix.c \
+    src/core/lib/iomgr/endpoint_pair_windows.c \
+    src/core/lib/iomgr/ev_poll_and_epoll_posix.c \
+    src/core/lib/iomgr/ev_poll_posix.c \
+    src/core/lib/iomgr/ev_posix.c \
+    src/core/lib/iomgr/exec_ctx.c \
+    src/core/lib/iomgr/executor.c \
+    src/core/lib/iomgr/iocp_windows.c \
+    src/core/lib/iomgr/iomgr.c \
+    src/core/lib/iomgr/iomgr_posix.c \
+    src/core/lib/iomgr/iomgr_windows.c \
+    src/core/lib/iomgr/polling_entity.c \
+    src/core/lib/iomgr/pollset_set_windows.c \
+    src/core/lib/iomgr/pollset_windows.c \
+    src/core/lib/iomgr/resolve_address_posix.c \
+    src/core/lib/iomgr/resolve_address_windows.c \
+    src/core/lib/iomgr/sockaddr_utils.c \
+    src/core/lib/iomgr/socket_utils_common_posix.c \
+    src/core/lib/iomgr/socket_utils_linux.c \
+    src/core/lib/iomgr/socket_utils_posix.c \
+    src/core/lib/iomgr/socket_windows.c \
+    src/core/lib/iomgr/tcp_client_posix.c \
+    src/core/lib/iomgr/tcp_client_windows.c \
+    src/core/lib/iomgr/tcp_posix.c \
+    src/core/lib/iomgr/tcp_server_posix.c \
+    src/core/lib/iomgr/tcp_server_windows.c \
+    src/core/lib/iomgr/tcp_windows.c \
+    src/core/lib/iomgr/time_averaged_stats.c \
+    src/core/lib/iomgr/timer.c \
+    src/core/lib/iomgr/timer_heap.c \
+    src/core/lib/iomgr/udp_server.c \
+    src/core/lib/iomgr/unix_sockets_posix.c \
+    src/core/lib/iomgr/unix_sockets_posix_noop.c \
+    src/core/lib/iomgr/wakeup_fd_eventfd.c \
+    src/core/lib/iomgr/wakeup_fd_nospecial.c \
+    src/core/lib/iomgr/wakeup_fd_pipe.c \
+    src/core/lib/iomgr/wakeup_fd_posix.c \
+    src/core/lib/iomgr/workqueue_posix.c \
+    src/core/lib/iomgr/workqueue_windows.c \
+    src/core/lib/json/json.c \
+    src/core/lib/json/json_reader.c \
+    src/core/lib/json/json_string.c \
+    src/core/lib/json/json_writer.c \
+    src/core/lib/surface/alarm.c \
+    src/core/lib/surface/api_trace.c \
+    src/core/lib/surface/byte_buffer.c \
+    src/core/lib/surface/byte_buffer_reader.c \
+    src/core/lib/surface/call.c \
+    src/core/lib/surface/call_details.c \
+    src/core/lib/surface/call_log_batch.c \
+    src/core/lib/surface/channel.c \
+    src/core/lib/surface/channel_init.c \
+    src/core/lib/surface/channel_ping.c \
+    src/core/lib/surface/channel_stack_type.c \
+    src/core/lib/surface/completion_queue.c \
+    src/core/lib/surface/event_string.c \
+    src/core/lib/surface/lame_client.c \
+    src/core/lib/surface/metadata_array.c \
+    src/core/lib/surface/server.c \
+    src/core/lib/surface/validate_metadata.c \
+    src/core/lib/surface/version.c \
+    src/core/lib/transport/byte_stream.c \
+    src/core/lib/transport/connectivity_state.c \
+    src/core/lib/transport/metadata.c \
+    src/core/lib/transport/metadata_batch.c \
+    src/core/lib/transport/static_metadata.c \
+    src/core/lib/transport/transport.c \
+    src/core/lib/transport/transport_op_string.c \
+    src/core/ext/transport/cronet/client/secure/cronet_channel_create.c \
+    src/core/ext/transport/cronet/transport/cronet_api_dummy.c \
+    src/core/ext/transport/cronet/transport/cronet_transport.c \
+    src/core/ext/transport/chttp2/client/secure/secure_channel_create.c \
+    src/core/ext/transport/chttp2/transport/bin_encoder.c \
+    src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
+    src/core/ext/transport/chttp2/transport/chttp2_transport.c \
+    src/core/ext/transport/chttp2/transport/frame_data.c \
+    src/core/ext/transport/chttp2/transport/frame_goaway.c \
+    src/core/ext/transport/chttp2/transport/frame_ping.c \
+    src/core/ext/transport/chttp2/transport/frame_rst_stream.c \
+    src/core/ext/transport/chttp2/transport/frame_settings.c \
+    src/core/ext/transport/chttp2/transport/frame_window_update.c \
+    src/core/ext/transport/chttp2/transport/hpack_encoder.c \
+    src/core/ext/transport/chttp2/transport/hpack_parser.c \
+    src/core/ext/transport/chttp2/transport/hpack_table.c \
+    src/core/ext/transport/chttp2/transport/huffsyms.c \
+    src/core/ext/transport/chttp2/transport/incoming_metadata.c \
+    src/core/ext/transport/chttp2/transport/parsing.c \
+    src/core/ext/transport/chttp2/transport/status_conversion.c \
+    src/core/ext/transport/chttp2/transport/stream_lists.c \
+    src/core/ext/transport/chttp2/transport/stream_map.c \
+    src/core/ext/transport/chttp2/transport/timeout_encoding.c \
+    src/core/ext/transport/chttp2/transport/varint.c \
+    src/core/ext/transport/chttp2/transport/writing.c \
+    src/core/ext/transport/chttp2/alpn/alpn.c \
+    src/core/ext/client_config/channel_connectivity.c \
+    src/core/ext/client_config/client_channel.c \
+    src/core/ext/client_config/client_channel_factory.c \
+    src/core/ext/client_config/client_config.c \
+    src/core/ext/client_config/client_config_plugin.c \
+    src/core/ext/client_config/connector.c \
+    src/core/ext/client_config/default_initial_connect_string.c \
+    src/core/ext/client_config/initial_connect_string.c \
+    src/core/ext/client_config/lb_policy.c \
+    src/core/ext/client_config/lb_policy_factory.c \
+    src/core/ext/client_config/lb_policy_registry.c \
+    src/core/ext/client_config/parse_address.c \
+    src/core/ext/client_config/resolver.c \
+    src/core/ext/client_config/resolver_factory.c \
+    src/core/ext/client_config/resolver_registry.c \
+    src/core/ext/client_config/subchannel.c \
+    src/core/ext/client_config/subchannel_call_holder.c \
+    src/core/ext/client_config/subchannel_index.c \
+    src/core/ext/client_config/uri_parser.c \
+    src/core/lib/http/httpcli_security_connector.c \
+    src/core/lib/security/context/security_context.c \
+    src/core/lib/security/credentials/composite/composite_credentials.c \
+    src/core/lib/security/credentials/credentials.c \
+    src/core/lib/security/credentials/credentials_metadata.c \
+    src/core/lib/security/credentials/fake/fake_credentials.c \
+    src/core/lib/security/credentials/google_default/credentials_posix.c \
+    src/core/lib/security/credentials/google_default/credentials_windows.c \
+    src/core/lib/security/credentials/google_default/google_default_credentials.c \
+    src/core/lib/security/credentials/iam/iam_credentials.c \
+    src/core/lib/security/credentials/jwt/json_token.c \
+    src/core/lib/security/credentials/jwt/jwt_credentials.c \
+    src/core/lib/security/credentials/jwt/jwt_verifier.c \
+    src/core/lib/security/credentials/oauth2/oauth2_credentials.c \
+    src/core/lib/security/credentials/plugin/plugin_credentials.c \
+    src/core/lib/security/credentials/ssl/ssl_credentials.c \
+    src/core/lib/security/transport/client_auth_filter.c \
+    src/core/lib/security/transport/handshake.c \
+    src/core/lib/security/transport/secure_endpoint.c \
+    src/core/lib/security/transport/security_connector.c \
+    src/core/lib/security/transport/server_auth_filter.c \
+    src/core/lib/security/util/b64.c \
+    src/core/lib/security/util/json_util.c \
+    src/core/lib/surface/init_secure.c \
+    src/core/lib/tsi/fake_transport_security.c \
+    src/core/lib/tsi/ssl_transport_security.c \
+    src/core/lib/tsi/transport_security.c \
+    src/core/plugin_registry/grpc_cronet_plugin_registry.c \
+
+PUBLIC_HEADERS_C += \
+    include/grpc/byte_buffer.h \
+    include/grpc/byte_buffer_reader.h \
+    include/grpc/compression.h \
+    include/grpc/grpc.h \
+    include/grpc/status.h \
+    include/grpc/impl/codegen/byte_buffer.h \
+    include/grpc/impl/codegen/byte_buffer_reader.h \
+    include/grpc/impl/codegen/compression_types.h \
+    include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/grpc_types.h \
+    include/grpc/impl/codegen/propagation_bits.h \
+    include/grpc/impl/codegen/status.h \
+    include/grpc/impl/codegen/alloc.h \
+    include/grpc/impl/codegen/atm.h \
+    include/grpc/impl/codegen/atm_gcc_atomic.h \
+    include/grpc/impl/codegen/atm_gcc_sync.h \
+    include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/port_platform.h \
+    include/grpc/impl/codegen/slice.h \
+    include/grpc/impl/codegen/slice_buffer.h \
+    include/grpc/impl/codegen/sync.h \
+    include/grpc/impl/codegen/sync_generic.h \
+    include/grpc/impl/codegen/sync_posix.h \
+    include/grpc/impl/codegen/sync_windows.h \
+    include/grpc/impl/codegen/time.h \
+    include/grpc/grpc_cronet.h \
+    include/grpc/grpc_security.h \
+    include/grpc/grpc_security_constants.h \
+
+LIBGRPC_CRONET_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_CRONET_SRC))))
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL.
+
+$(LIBDIR)/$(CONFIG)/libgrpc_cronet.a: openssl_dep_error
+
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT): openssl_dep_error
+
+else
+
+
+$(LIBDIR)/$(CONFIG)/libgrpc_cronet.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_CRONET_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a
+	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBGRPC_CRONET_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a
+endif
+
+
+
+ifeq ($(SYSTEM),MINGW32)
+$(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC_CRONET_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc_cronet.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
+else
+$(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC_CRONET_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+ifeq ($(SYSTEM),Darwin)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
+else
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_cronet.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION).so.0
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION).so
+endif
+endif
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC_CRONET_OBJS:.o=.dep)
+endif
+endif
+
+
 LIBGRPC_TEST_UTIL_SRC = \
 LIBGRPC_TEST_UTIL_SRC = \
     test/core/end2end/data/client_certs.c \
     test/core/end2end/data/client_certs.c \
     test/core/end2end/data/server1_cert.c \
     test/core/end2end/data/server1_cert.c \
@@ -2844,6 +3099,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr_posix.c \
     src/core/lib/iomgr/iomgr_posix.c \
     src/core/lib/iomgr/iomgr_windows.c \
     src/core/lib/iomgr/iomgr_windows.c \
+    src/core/lib/iomgr/polling_entity.c \
     src/core/lib/iomgr/pollset_set_windows.c \
     src/core/lib/iomgr/pollset_set_windows.c \
     src/core/lib/iomgr/pollset_windows.c \
     src/core/lib/iomgr/pollset_windows.c \
     src/core/lib/iomgr/resolve_address_posix.c \
     src/core/lib/iomgr/resolve_address_posix.c \
@@ -3199,7 +3455,6 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/impl/client_unary_call.h \
     include/grpc++/impl/client_unary_call.h \
     include/grpc++/impl/grpc_library.h \
     include/grpc++/impl/grpc_library.h \
     include/grpc++/impl/method_handler_impl.h \
     include/grpc++/impl/method_handler_impl.h \
-    include/grpc++/impl/proto_utils.h \
     include/grpc++/impl/rpc_method.h \
     include/grpc++/impl/rpc_method.h \
     include/grpc++/impl/rpc_service_method.h \
     include/grpc++/impl/rpc_service_method.h \
     include/grpc++/impl/serialization_traits.h \
     include/grpc++/impl/serialization_traits.h \
@@ -3224,6 +3479,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/support/async_unary_call.h \
     include/grpc++/support/async_unary_call.h \
     include/grpc++/support/byte_buffer.h \
     include/grpc++/support/byte_buffer.h \
     include/grpc++/support/channel_arguments.h \
     include/grpc++/support/channel_arguments.h \
+    include/grpc++/support/config.h \
     include/grpc++/support/slice.h \
     include/grpc++/support/slice.h \
     include/grpc++/support/status.h \
     include/grpc++/support/status.h \
     include/grpc++/support/status_code_enum.h \
     include/grpc++/support/status_code_enum.h \
@@ -3240,11 +3496,11 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/impl/codegen/client_unary_call.h \
     include/grpc++/impl/codegen/client_unary_call.h \
     include/grpc++/impl/codegen/completion_queue.h \
     include/grpc++/impl/codegen/completion_queue.h \
     include/grpc++/impl/codegen/completion_queue_tag.h \
     include/grpc++/impl/codegen/completion_queue_tag.h \
+    include/grpc++/impl/codegen/config.h \
     include/grpc++/impl/codegen/core_codegen_interface.h \
     include/grpc++/impl/codegen/core_codegen_interface.h \
     include/grpc++/impl/codegen/create_auth_context.h \
     include/grpc++/impl/codegen/create_auth_context.h \
     include/grpc++/impl/codegen/grpc_library.h \
     include/grpc++/impl/codegen/grpc_library.h \
     include/grpc++/impl/codegen/method_handler_impl.h \
     include/grpc++/impl/codegen/method_handler_impl.h \
-    include/grpc++/impl/codegen/proto_utils.h \
     include/grpc++/impl/codegen/rpc_method.h \
     include/grpc++/impl/codegen/rpc_method.h \
     include/grpc++/impl/codegen/rpc_service_method.h \
     include/grpc++/impl/codegen/rpc_service_method.h \
     include/grpc++/impl/codegen/security/auth_context.h \
     include/grpc++/impl/codegen/security/auth_context.h \
@@ -3282,10 +3538,6 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/sync_posix.h \
     include/grpc/impl/codegen/sync_posix.h \
     include/grpc/impl/codegen/sync_windows.h \
     include/grpc/impl/codegen/sync_windows.h \
     include/grpc/impl/codegen/time.h \
     include/grpc/impl/codegen/time.h \
-    include/grpc++/impl/codegen/config.h \
-    include/grpc++/impl/codegen/config_protobuf.h \
-    include/grpc++/support/config.h \
-    include/grpc++/support/config_protobuf.h \
 
 
 LIBGRPC++_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_SRC))))
 LIBGRPC++_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_SRC))))
 
 
@@ -3409,8 +3661,62 @@ LIBGRPC++_TEST_UTIL_SRC = \
     test/cpp/util/string_ref_helper.cc \
     test/cpp/util/string_ref_helper.cc \
     test/cpp/util/subprocess.cc \
     test/cpp/util/subprocess.cc \
     test/cpp/util/test_credentials_provider.cc \
     test/cpp/util/test_credentials_provider.cc \
+    src/cpp/codegen/codegen_init.cc \
 
 
 PUBLIC_HEADERS_CXX += \
 PUBLIC_HEADERS_CXX += \
+    include/grpc++/impl/codegen/async_stream.h \
+    include/grpc++/impl/codegen/async_unary_call.h \
+    include/grpc++/impl/codegen/call.h \
+    include/grpc++/impl/codegen/call_hook.h \
+    include/grpc++/impl/codegen/channel_interface.h \
+    include/grpc++/impl/codegen/client_context.h \
+    include/grpc++/impl/codegen/client_unary_call.h \
+    include/grpc++/impl/codegen/completion_queue.h \
+    include/grpc++/impl/codegen/completion_queue_tag.h \
+    include/grpc++/impl/codegen/config.h \
+    include/grpc++/impl/codegen/core_codegen_interface.h \
+    include/grpc++/impl/codegen/create_auth_context.h \
+    include/grpc++/impl/codegen/grpc_library.h \
+    include/grpc++/impl/codegen/method_handler_impl.h \
+    include/grpc++/impl/codegen/rpc_method.h \
+    include/grpc++/impl/codegen/rpc_service_method.h \
+    include/grpc++/impl/codegen/security/auth_context.h \
+    include/grpc++/impl/codegen/serialization_traits.h \
+    include/grpc++/impl/codegen/server_context.h \
+    include/grpc++/impl/codegen/server_interface.h \
+    include/grpc++/impl/codegen/service_type.h \
+    include/grpc++/impl/codegen/status.h \
+    include/grpc++/impl/codegen/status_code_enum.h \
+    include/grpc++/impl/codegen/string_ref.h \
+    include/grpc++/impl/codegen/stub_options.h \
+    include/grpc++/impl/codegen/sync.h \
+    include/grpc++/impl/codegen/sync_cxx11.h \
+    include/grpc++/impl/codegen/sync_no_cxx11.h \
+    include/grpc++/impl/codegen/sync_stream.h \
+    include/grpc++/impl/codegen/time.h \
+    include/grpc/impl/codegen/byte_buffer.h \
+    include/grpc/impl/codegen/byte_buffer_reader.h \
+    include/grpc/impl/codegen/compression_types.h \
+    include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/grpc_types.h \
+    include/grpc/impl/codegen/propagation_bits.h \
+    include/grpc/impl/codegen/status.h \
+    include/grpc/impl/codegen/alloc.h \
+    include/grpc/impl/codegen/atm.h \
+    include/grpc/impl/codegen/atm_gcc_atomic.h \
+    include/grpc/impl/codegen/atm_gcc_sync.h \
+    include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/port_platform.h \
+    include/grpc/impl/codegen/slice.h \
+    include/grpc/impl/codegen/slice_buffer.h \
+    include/grpc/impl/codegen/sync.h \
+    include/grpc/impl/codegen/sync_generic.h \
+    include/grpc/impl/codegen/sync_posix.h \
+    include/grpc/impl/codegen/sync_windows.h \
+    include/grpc/impl/codegen/time.h \
+    include/grpc++/impl/codegen/proto_utils.h \
+    include/grpc++/impl/codegen/config_protobuf.h \
 
 
 LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC))))
 LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC))))
 
 
@@ -3460,6 +3766,7 @@ $(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/src/proto/grp
 $(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/test_credentials_provider.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/test_credentials_provider.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 
 
 
 
 LIBGRPC++_UNSECURE_SRC = \
 LIBGRPC++_UNSECURE_SRC = \
@@ -3503,7 +3810,6 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/impl/client_unary_call.h \
     include/grpc++/impl/client_unary_call.h \
     include/grpc++/impl/grpc_library.h \
     include/grpc++/impl/grpc_library.h \
     include/grpc++/impl/method_handler_impl.h \
     include/grpc++/impl/method_handler_impl.h \
-    include/grpc++/impl/proto_utils.h \
     include/grpc++/impl/rpc_method.h \
     include/grpc++/impl/rpc_method.h \
     include/grpc++/impl/rpc_service_method.h \
     include/grpc++/impl/rpc_service_method.h \
     include/grpc++/impl/serialization_traits.h \
     include/grpc++/impl/serialization_traits.h \
@@ -3528,6 +3834,7 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/support/async_unary_call.h \
     include/grpc++/support/async_unary_call.h \
     include/grpc++/support/byte_buffer.h \
     include/grpc++/support/byte_buffer.h \
     include/grpc++/support/channel_arguments.h \
     include/grpc++/support/channel_arguments.h \
+    include/grpc++/support/config.h \
     include/grpc++/support/slice.h \
     include/grpc++/support/slice.h \
     include/grpc++/support/status.h \
     include/grpc++/support/status.h \
     include/grpc++/support/status_code_enum.h \
     include/grpc++/support/status_code_enum.h \
@@ -3544,11 +3851,11 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/impl/codegen/client_unary_call.h \
     include/grpc++/impl/codegen/client_unary_call.h \
     include/grpc++/impl/codegen/completion_queue.h \
     include/grpc++/impl/codegen/completion_queue.h \
     include/grpc++/impl/codegen/completion_queue_tag.h \
     include/grpc++/impl/codegen/completion_queue_tag.h \
+    include/grpc++/impl/codegen/config.h \
     include/grpc++/impl/codegen/core_codegen_interface.h \
     include/grpc++/impl/codegen/core_codegen_interface.h \
     include/grpc++/impl/codegen/create_auth_context.h \
     include/grpc++/impl/codegen/create_auth_context.h \
     include/grpc++/impl/codegen/grpc_library.h \
     include/grpc++/impl/codegen/grpc_library.h \
     include/grpc++/impl/codegen/method_handler_impl.h \
     include/grpc++/impl/codegen/method_handler_impl.h \
-    include/grpc++/impl/codegen/proto_utils.h \
     include/grpc++/impl/codegen/rpc_method.h \
     include/grpc++/impl/codegen/rpc_method.h \
     include/grpc++/impl/codegen/rpc_service_method.h \
     include/grpc++/impl/codegen/rpc_service_method.h \
     include/grpc++/impl/codegen/security/auth_context.h \
     include/grpc++/impl/codegen/security/auth_context.h \
@@ -3586,10 +3893,6 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/sync_posix.h \
     include/grpc/impl/codegen/sync_posix.h \
     include/grpc/impl/codegen/sync_windows.h \
     include/grpc/impl/codegen/sync_windows.h \
     include/grpc/impl/codegen/time.h \
     include/grpc/impl/codegen/time.h \
-    include/grpc++/impl/codegen/config.h \
-    include/grpc++/impl/codegen/config_protobuf.h \
-    include/grpc++/support/config.h \
-    include/grpc++/support/config_protobuf.h \
 
 
 LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC))))
 LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC))))
 
 
@@ -3699,9 +4002,6 @@ LIBGRPC_PLUGIN_SUPPORT_SRC = \
     src/compiler/ruby_generator.cc \
     src/compiler/ruby_generator.cc \
 
 
 PUBLIC_HEADERS_CXX += \
 PUBLIC_HEADERS_CXX += \
-    include/grpc++/support/config.h \
-    include/grpc++/support/config_protobuf.h \
-    include/grpc++/impl/codegen/config.h \
     include/grpc++/impl/codegen/config_protobuf.h \
     include/grpc++/impl/codegen/config_protobuf.h \
 
 
 LIBGRPC_PLUGIN_SUPPORT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_PLUGIN_SUPPORT_SRC))))
 LIBGRPC_PLUGIN_SUPPORT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_PLUGIN_SUPPORT_SRC))))
@@ -9965,7 +10265,6 @@ CODEGEN_TEST_FULL_SRC = \
     $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc \
     test/cpp/codegen/codegen_test_full.cc \
     test/cpp/codegen/codegen_test_full.cc \
-    src/cpp/codegen/codegen_init.cc \
 
 
 CODEGEN_TEST_FULL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CODEGEN_TEST_FULL_SRC))))
 CODEGEN_TEST_FULL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CODEGEN_TEST_FULL_SRC))))
 ifeq ($(NO_SECURE),true)
 ifeq ($(NO_SECURE),true)
@@ -10008,8 +10307,6 @@ $(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/stats.o:  $(LIBDIR)/$(CONFIG)/libgrpc
 
 
 $(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_full.o:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 $(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_full.o:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 
-$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
 deps_codegen_test_full: $(CODEGEN_TEST_FULL_OBJS:.o=.dep)
 deps_codegen_test_full: $(CODEGEN_TEST_FULL_OBJS:.o=.dep)
 
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_SECURE),true)
@@ -10018,7 +10315,6 @@ ifneq ($(NO_DEPS),true)
 endif
 endif
 endif
 endif
 $(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_full.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_full.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
 
 
 
 
 CODEGEN_TEST_MINIMAL_SRC = \
 CODEGEN_TEST_MINIMAL_SRC = \
@@ -14249,6 +14545,7 @@ src/core/lib/surface/init_secure.c: $(OPENSSL_DEP)
 src/core/lib/tsi/fake_transport_security.c: $(OPENSSL_DEP)
 src/core/lib/tsi/fake_transport_security.c: $(OPENSSL_DEP)
 src/core/lib/tsi/ssl_transport_security.c: $(OPENSSL_DEP)
 src/core/lib/tsi/ssl_transport_security.c: $(OPENSSL_DEP)
 src/core/lib/tsi/transport_security.c: $(OPENSSL_DEP)
 src/core/lib/tsi/transport_security.c: $(OPENSSL_DEP)
+src/core/plugin_registry/grpc_cronet_plugin_registry.c: $(OPENSSL_DEP)
 src/core/plugin_registry/grpc_plugin_registry.c: $(OPENSSL_DEP)
 src/core/plugin_registry/grpc_plugin_registry.c: $(OPENSSL_DEP)
 src/cpp/client/secure_credentials.cc: $(OPENSSL_DEP)
 src/cpp/client/secure_credentials.cc: $(OPENSSL_DEP)
 src/cpp/common/auth_property_iterator.cc: $(OPENSSL_DEP)
 src/cpp/common/auth_property_iterator.cc: $(OPENSSL_DEP)

+ 1 - 3
binding.gyp

@@ -590,6 +590,7 @@
         'src/core/lib/iomgr/iomgr.c',
         'src/core/lib/iomgr/iomgr.c',
         'src/core/lib/iomgr/iomgr_posix.c',
         'src/core/lib/iomgr/iomgr_posix.c',
         'src/core/lib/iomgr/iomgr_windows.c',
         'src/core/lib/iomgr/iomgr_windows.c',
+        'src/core/lib/iomgr/polling_entity.c',
         'src/core/lib/iomgr/pollset_set_windows.c',
         'src/core/lib/iomgr/pollset_set_windows.c',
         'src/core/lib/iomgr/pollset_windows.c',
         'src/core/lib/iomgr/pollset_windows.c',
         'src/core/lib/iomgr/resolve_address_posix.c',
         'src/core/lib/iomgr/resolve_address_posix.c',
@@ -718,9 +719,6 @@
         'src/core/ext/client_config/uri_parser.c',
         'src/core/ext/client_config/uri_parser.c',
         'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
         'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
         'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
         'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
-        'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c',
-        'src/core/ext/transport/cronet/transport/cronet_api_dummy.c',
-        'src/core/ext/transport/cronet/transport/cronet_transport.c',
         'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
         'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
         'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
         'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
         'third_party/nanopb/pb_common.c',
         'third_party/nanopb/pb_common.c',

+ 49 - 21
build.yaml

@@ -143,6 +143,11 @@ filegroups:
   - include/grpc/impl/codegen/sync_posix.h
   - include/grpc/impl/codegen/sync_posix.h
   - include/grpc/impl/codegen/sync_windows.h
   - include/grpc/impl/codegen/sync_windows.h
   - include/grpc/impl/codegen/time.h
   - include/grpc/impl/codegen/time.h
+- name: grpc++_codegen_base_src
+  src:
+  - src/cpp/codegen/codegen_init.cc
+  uses:
+  - grpc++_codegen_base
 - name: grpc_base
 - name: grpc_base
   public_headers:
   public_headers:
   - include/grpc/byte_buffer.h
   - include/grpc/byte_buffer.h
@@ -177,6 +182,7 @@ filegroups:
   - src/core/lib/iomgr/iomgr.h
   - src/core/lib/iomgr/iomgr.h
   - src/core/lib/iomgr/iomgr_internal.h
   - src/core/lib/iomgr/iomgr_internal.h
   - src/core/lib/iomgr/iomgr_posix.h
   - src/core/lib/iomgr/iomgr_posix.h
+  - src/core/lib/iomgr/polling_entity.h
   - src/core/lib/iomgr/pollset.h
   - src/core/lib/iomgr/pollset.h
   - src/core/lib/iomgr/pollset_set.h
   - src/core/lib/iomgr/pollset_set.h
   - src/core/lib/iomgr/pollset_set_windows.h
   - src/core/lib/iomgr/pollset_set_windows.h
@@ -252,6 +258,7 @@ filegroups:
   - src/core/lib/iomgr/iomgr.c
   - src/core/lib/iomgr/iomgr.c
   - src/core/lib/iomgr/iomgr_posix.c
   - src/core/lib/iomgr/iomgr_posix.c
   - src/core/lib/iomgr/iomgr_windows.c
   - src/core/lib/iomgr/iomgr_windows.c
+  - src/core/lib/iomgr/polling_entity.c
   - src/core/lib/iomgr/pollset_set_windows.c
   - src/core/lib/iomgr/pollset_set_windows.c
   - src/core/lib/iomgr/pollset_windows.c
   - src/core/lib/iomgr/pollset_windows.c
   - src/core/lib/iomgr/resolve_address_posix.c
   - src/core/lib/iomgr/resolve_address_posix.c
@@ -415,7 +422,6 @@ filegroups:
   - grpc_client_config
   - grpc_client_config
 - name: grpc_secure
 - name: grpc_secure
   public_headers:
   public_headers:
-  - include/grpc/grpc_cronet.h
   - include/grpc/grpc_security.h
   - include/grpc/grpc_security.h
   - include/grpc/grpc_security_constants.h
   - include/grpc/grpc_security_constants.h
   headers:
   headers:
@@ -581,6 +587,10 @@ filegroups:
   - grpc_base
   - grpc_base
   - grpc_secure
   - grpc_secure
 - name: grpc_transport_cronet_client_secure
 - name: grpc_transport_cronet_client_secure
+  public_headers:
+  - include/grpc/grpc_cronet.h
+  - include/grpc/grpc_security.h
+  - include/grpc/grpc_security_constants.h
   headers:
   headers:
   - third_party/objective_c/Cronet/cronet_c_for_grpc.h
   - third_party/objective_c/Cronet/cronet_c_for_grpc.h
   src:
   src:
@@ -629,7 +639,6 @@ filegroups:
   - include/grpc++/impl/client_unary_call.h
   - include/grpc++/impl/client_unary_call.h
   - include/grpc++/impl/grpc_library.h
   - include/grpc++/impl/grpc_library.h
   - include/grpc++/impl/method_handler_impl.h
   - include/grpc++/impl/method_handler_impl.h
-  - include/grpc++/impl/proto_utils.h
   - include/grpc++/impl/rpc_method.h
   - include/grpc++/impl/rpc_method.h
   - include/grpc++/impl/rpc_service_method.h
   - include/grpc++/impl/rpc_service_method.h
   - include/grpc++/impl/serialization_traits.h
   - include/grpc++/impl/serialization_traits.h
@@ -654,6 +663,7 @@ filegroups:
   - include/grpc++/support/async_unary_call.h
   - include/grpc++/support/async_unary_call.h
   - include/grpc++/support/byte_buffer.h
   - include/grpc++/support/byte_buffer.h
   - include/grpc++/support/channel_arguments.h
   - include/grpc++/support/channel_arguments.h
+  - include/grpc++/support/config.h
   - include/grpc++/support/slice.h
   - include/grpc++/support/slice.h
   - include/grpc++/support/status.h
   - include/grpc++/support/status.h
   - include/grpc++/support/status_code_enum.h
   - include/grpc++/support/status_code_enum.h
@@ -694,9 +704,8 @@ filegroups:
   deps:
   deps:
   - grpc
   - grpc
   uses:
   uses:
-  - grpc++_codegen
-  - grpc++_config
-- name: grpc++_codegen
+  - grpc++_codegen_base
+- name: grpc++_codegen_base
   language: c++
   language: c++
   public_headers:
   public_headers:
   - include/grpc++/impl/codegen/async_stream.h
   - include/grpc++/impl/codegen/async_stream.h
@@ -708,11 +717,11 @@ filegroups:
   - include/grpc++/impl/codegen/client_unary_call.h
   - include/grpc++/impl/codegen/client_unary_call.h
   - include/grpc++/impl/codegen/completion_queue.h
   - include/grpc++/impl/codegen/completion_queue.h
   - include/grpc++/impl/codegen/completion_queue_tag.h
   - include/grpc++/impl/codegen/completion_queue_tag.h
+  - include/grpc++/impl/codegen/config.h
   - include/grpc++/impl/codegen/core_codegen_interface.h
   - include/grpc++/impl/codegen/core_codegen_interface.h
   - include/grpc++/impl/codegen/create_auth_context.h
   - include/grpc++/impl/codegen/create_auth_context.h
   - include/grpc++/impl/codegen/grpc_library.h
   - include/grpc++/impl/codegen/grpc_library.h
   - include/grpc++/impl/codegen/method_handler_impl.h
   - include/grpc++/impl/codegen/method_handler_impl.h
-  - include/grpc++/impl/codegen/proto_utils.h
   - include/grpc++/impl/codegen/rpc_method.h
   - include/grpc++/impl/codegen/rpc_method.h
   - include/grpc++/impl/codegen/rpc_service_method.h
   - include/grpc++/impl/codegen/rpc_service_method.h
   - include/grpc++/impl/codegen/security/auth_context.h
   - include/grpc++/impl/codegen/security/auth_context.h
@@ -729,22 +738,18 @@ filegroups:
   - include/grpc++/impl/codegen/sync_no_cxx11.h
   - include/grpc++/impl/codegen/sync_no_cxx11.h
   - include/grpc++/impl/codegen/sync_stream.h
   - include/grpc++/impl/codegen/sync_stream.h
   - include/grpc++/impl/codegen/time.h
   - include/grpc++/impl/codegen/time.h
-  src:
-  - src/cpp/codegen/codegen_init.cc
   uses:
   uses:
   - grpc_codegen
   - grpc_codegen
-  - grpc++_config_codegen
-- name: grpc++_config
+- name: grpc++_codegen_proto
   language: c++
   language: c++
   public_headers:
   public_headers:
-  - include/grpc++/support/config.h
-  - include/grpc++/support/config_protobuf.h
+  - include/grpc++/impl/codegen/proto_utils.h
   uses:
   uses:
-  - grpc++_config_codegen
-- name: grpc++_config_codegen
+  - grpc++_codegen_base
+  - grpc++_config_proto
+- name: grpc++_config_proto
   language: c++
   language: c++
   public_headers:
   public_headers:
-  - include/grpc++/impl/codegen/config.h
   - include/grpc++/impl/codegen/config_protobuf.h
   - include/grpc++/impl/codegen/config_protobuf.h
 libs:
 libs:
 - name: gpr
 - name: gpr
@@ -779,7 +784,6 @@ libs:
   - grpc_transport_chttp2_client_secure
   - grpc_transport_chttp2_client_secure
   - grpc_transport_chttp2_server_insecure
   - grpc_transport_chttp2_server_insecure
   - grpc_transport_chttp2_client_insecure
   - grpc_transport_chttp2_client_insecure
-  - grpc_transport_cronet_client_secure
   - grpc_lb_policy_grpclb
   - grpc_lb_policy_grpclb
   - grpc_lb_policy_pick_first
   - grpc_lb_policy_pick_first
   - grpc_lb_policy_round_robin
   - grpc_lb_policy_round_robin
@@ -794,6 +798,22 @@ libs:
   - grpc.dependencies.openssl
   - grpc.dependencies.openssl
   - grpc.dependencies.zlib
   - grpc.dependencies.zlib
   vs_project_guid: '{29D16885-7228-4C31-81ED-5F9187C7F2A9}'
   vs_project_guid: '{29D16885-7228-4C31-81ED-5F9187C7F2A9}'
+- name: grpc_cronet
+  build: all
+  language: c
+  src:
+  - src/core/lib/surface/init.c
+  baselib: true
+  deps_linkage: static
+  dll: true
+  filegroups:
+  - grpc_base
+  - grpc_transport_cronet_client_secure
+  - grpc_transport_chttp2_client_secure
+  generate_plugin_registry: true
+  platforms:
+  - linux
+  secure: true
 - name: grpc_dll
 - name: grpc_dll
   build: private
   build: private
   language: c
   language: c
@@ -929,7 +949,8 @@ libs:
   dll: true
   dll: true
   filegroups:
   filegroups:
   - grpc++_base
   - grpc++_base
-  - grpc++_codegen
+  - grpc++_codegen_base
+  - grpc++_codegen_base_src
   secure: check
   secure: check
   vs_project_guid: '{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}'
   vs_project_guid: '{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}'
 - name: grpc++_test_config
 - name: grpc++_test_config
@@ -962,6 +983,11 @@ libs:
   deps:
   deps:
   - grpc++
   - grpc++
   - grpc_test_util
   - grpc_test_util
+  filegroups:
+  - grpc++_codegen_base
+  - grpc++_codegen_base_src
+  - grpc++_codegen_proto
+  - grpc++_config_proto
 - name: grpc++_unsecure
 - name: grpc++_unsecure
   build: all
   build: all
   language: c++
   language: c++
@@ -974,7 +1000,8 @@ libs:
   dll: true
   dll: true
   filegroups:
   filegroups:
   - grpc++_base
   - grpc++_base
-  - grpc++_codegen
+  - grpc++_codegen_base
+  - grpc++_codegen_base_src
   secure: false
   secure: false
   vs_project_guid: '{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}'
   vs_project_guid: '{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}'
 - name: grpc_cli_libs
 - name: grpc_cli_libs
@@ -1016,7 +1043,7 @@ libs:
   - src/compiler/python_generator.cc
   - src/compiler/python_generator.cc
   - src/compiler/ruby_generator.cc
   - src/compiler/ruby_generator.cc
   filegroups:
   filegroups:
-  - grpc++_config
+  - grpc++_config_proto
   secure: false
   secure: false
   vs_project_guid: '{B6E81D84-2ACB-41B8-8781-493A944C7817}'
   vs_project_guid: '{B6E81D84-2ACB-41B8-8781-493A944C7817}'
   vs_props:
   vs_props:
@@ -2462,7 +2489,7 @@ targets:
   - grpc
   - grpc
   - gpr
   - gpr
   filegroups:
   filegroups:
-  - grpc++_codegen
+  - grpc++_codegen_base
 - name: codegen_test_minimal
 - name: codegen_test_minimal
   gtest: true
   gtest: true
   build: test
   build: test
@@ -2475,7 +2502,8 @@ targets:
   - src/proto/grpc/testing/stats.proto
   - src/proto/grpc/testing/stats.proto
   - test/cpp/codegen/codegen_test_minimal.cc
   - test/cpp/codegen/codegen_test_minimal.cc
   filegroups:
   filegroups:
-  - grpc++_codegen
+  - grpc++_codegen_base
+  - grpc++_codegen_base_src
 - name: credentials_test
 - name: credentials_test
   gtest: true
   gtest: true
   build: test
   build: test

+ 1 - 5
config.m4

@@ -109,6 +109,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr_posix.c \
     src/core/lib/iomgr/iomgr_posix.c \
     src/core/lib/iomgr/iomgr_windows.c \
     src/core/lib/iomgr/iomgr_windows.c \
+    src/core/lib/iomgr/polling_entity.c \
     src/core/lib/iomgr/pollset_set_windows.c \
     src/core/lib/iomgr/pollset_set_windows.c \
     src/core/lib/iomgr/pollset_windows.c \
     src/core/lib/iomgr/pollset_windows.c \
     src/core/lib/iomgr/resolve_address_posix.c \
     src/core/lib/iomgr/resolve_address_posix.c \
@@ -237,9 +238,6 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/client_config/uri_parser.c \
     src/core/ext/client_config/uri_parser.c \
     src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
     src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
     src/core/ext/transport/chttp2/client/insecure/channel_create.c \
     src/core/ext/transport/chttp2/client/insecure/channel_create.c \
-    src/core/ext/transport/cronet/client/secure/cronet_channel_create.c \
-    src/core/ext/transport/cronet/transport/cronet_api_dummy.c \
-    src/core/ext/transport/cronet/transport/cronet_transport.c \
     src/core/ext/lb_policy/grpclb/load_balancer_api.c \
     src/core/ext/lb_policy/grpclb/load_balancer_api.c \
     src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     third_party/nanopb/pb_common.c \
     third_party/nanopb/pb_common.c \
@@ -583,8 +581,6 @@ if test "$PHP_GRPC" != "no"; then
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/server/insecure)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/server/insecure)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/server/secure)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/server/secure)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/transport)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/transport)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/cronet/client/secure)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/cronet/transport)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/channel)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/channel)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/compression)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/compression)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/debug)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/debug)

+ 3 - 6
gRPC.podspec

@@ -190,6 +190,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/iomgr.h',
                       'src/core/lib/iomgr/iomgr.h',
                       'src/core/lib/iomgr/iomgr_internal.h',
                       'src/core/lib/iomgr/iomgr_internal.h',
                       'src/core/lib/iomgr/iomgr_posix.h',
                       'src/core/lib/iomgr/iomgr_posix.h',
+                      'src/core/lib/iomgr/polling_entity.h',
                       'src/core/lib/iomgr/pollset.h',
                       'src/core/lib/iomgr/pollset.h',
                       'src/core/lib/iomgr/pollset_set.h',
                       'src/core/lib/iomgr/pollset_set.h',
                       'src/core/lib/iomgr/pollset_set_windows.h',
                       'src/core/lib/iomgr/pollset_set_windows.h',
@@ -298,7 +299,6 @@ Pod::Spec.new do |s|
                       'src/core/ext/client_config/subchannel_call_holder.h',
                       'src/core/ext/client_config/subchannel_call_holder.h',
                       'src/core/ext/client_config/subchannel_index.h',
                       'src/core/ext/client_config/subchannel_index.h',
                       'src/core/ext/client_config/uri_parser.h',
                       'src/core/ext/client_config/uri_parser.h',
-                      'third_party/objective_c/Cronet/cronet_c_for_grpc.h',
                       'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
                       'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
                       'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
                       'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
                       'third_party/nanopb/pb.h',
                       'third_party/nanopb/pb.h',
@@ -340,7 +340,6 @@ Pod::Spec.new do |s|
                       'include/grpc/impl/codegen/sync_posix.h',
                       'include/grpc/impl/codegen/sync_posix.h',
                       'include/grpc/impl/codegen/sync_windows.h',
                       'include/grpc/impl/codegen/sync_windows.h',
                       'include/grpc/impl/codegen/time.h',
                       'include/grpc/impl/codegen/time.h',
-                      'include/grpc/grpc_cronet.h',
                       'include/grpc/grpc_security.h',
                       'include/grpc/grpc_security.h',
                       'include/grpc/grpc_security_constants.h',
                       'include/grpc/grpc_security_constants.h',
                       'include/grpc/census.h',
                       'include/grpc/census.h',
@@ -371,6 +370,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/iomgr.c',
                       'src/core/lib/iomgr/iomgr.c',
                       'src/core/lib/iomgr/iomgr_posix.c',
                       'src/core/lib/iomgr/iomgr_posix.c',
                       'src/core/lib/iomgr/iomgr_windows.c',
                       'src/core/lib/iomgr/iomgr_windows.c',
+                      'src/core/lib/iomgr/polling_entity.c',
                       'src/core/lib/iomgr/pollset_set_windows.c',
                       'src/core/lib/iomgr/pollset_set_windows.c',
                       'src/core/lib/iomgr/pollset_windows.c',
                       'src/core/lib/iomgr/pollset_windows.c',
                       'src/core/lib/iomgr/resolve_address_posix.c',
                       'src/core/lib/iomgr/resolve_address_posix.c',
@@ -499,9 +499,6 @@ Pod::Spec.new do |s|
                       'src/core/ext/client_config/uri_parser.c',
                       'src/core/ext/client_config/uri_parser.c',
                       'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
                       'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
                       'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
                       'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
-                      'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c',
-                      'src/core/ext/transport/cronet/transport/cronet_api_dummy.c',
-                      'src/core/ext/transport/cronet/transport/cronet_transport.c',
                       'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
                       'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
                       'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
                       'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
                       'third_party/nanopb/pb_common.c',
                       'third_party/nanopb/pb_common.c',
@@ -563,6 +560,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/iomgr/iomgr.h',
                               'src/core/lib/iomgr/iomgr.h',
                               'src/core/lib/iomgr/iomgr_internal.h',
                               'src/core/lib/iomgr/iomgr_internal.h',
                               'src/core/lib/iomgr/iomgr_posix.h',
                               'src/core/lib/iomgr/iomgr_posix.h',
+                              'src/core/lib/iomgr/polling_entity.h',
                               'src/core/lib/iomgr/pollset.h',
                               'src/core/lib/iomgr/pollset.h',
                               'src/core/lib/iomgr/pollset_set.h',
                               'src/core/lib/iomgr/pollset_set.h',
                               'src/core/lib/iomgr/pollset_set_windows.h',
                               'src/core/lib/iomgr/pollset_set_windows.h',
@@ -671,7 +669,6 @@ Pod::Spec.new do |s|
                               'src/core/ext/client_config/subchannel_call_holder.h',
                               'src/core/ext/client_config/subchannel_call_holder.h',
                               'src/core/ext/client_config/subchannel_index.h',
                               'src/core/ext/client_config/subchannel_index.h',
                               'src/core/ext/client_config/uri_parser.h',
                               'src/core/ext/client_config/uri_parser.h',
-                              'third_party/objective_c/Cronet/cronet_c_for_grpc.h',
                               'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
                               'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
                               'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
                               'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
                               'third_party/nanopb/pb.h',
                               'third_party/nanopb/pb.h',

+ 0 - 1
grpc.def

@@ -88,7 +88,6 @@ EXPORTS
     grpc_header_nonbin_value_is_legal
     grpc_header_nonbin_value_is_legal
     grpc_is_binary_header
     grpc_is_binary_header
     grpc_call_error_to_string
     grpc_call_error_to_string
-    grpc_cronet_secure_channel_create
     grpc_auth_property_iterator_next
     grpc_auth_property_iterator_next
     grpc_auth_context_property_iterator
     grpc_auth_context_property_iterator
     grpc_auth_context_peer_identity
     grpc_auth_context_peer_identity

+ 2 - 5
grpc.gemspec

@@ -169,7 +169,6 @@ Gem::Specification.new do |s|
   s.files += %w( include/grpc/impl/codegen/sync_posix.h )
   s.files += %w( include/grpc/impl/codegen/sync_posix.h )
   s.files += %w( include/grpc/impl/codegen/sync_windows.h )
   s.files += %w( include/grpc/impl/codegen/sync_windows.h )
   s.files += %w( include/grpc/impl/codegen/time.h )
   s.files += %w( include/grpc/impl/codegen/time.h )
-  s.files += %w( include/grpc/grpc_cronet.h )
   s.files += %w( include/grpc/grpc_security.h )
   s.files += %w( include/grpc/grpc_security.h )
   s.files += %w( include/grpc/grpc_security_constants.h )
   s.files += %w( include/grpc/grpc_security_constants.h )
   s.files += %w( include/grpc/census.h )
   s.files += %w( include/grpc/census.h )
@@ -199,6 +198,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/iomgr/iomgr.h )
   s.files += %w( src/core/lib/iomgr/iomgr.h )
   s.files += %w( src/core/lib/iomgr/iomgr_internal.h )
   s.files += %w( src/core/lib/iomgr/iomgr_internal.h )
   s.files += %w( src/core/lib/iomgr/iomgr_posix.h )
   s.files += %w( src/core/lib/iomgr/iomgr_posix.h )
+  s.files += %w( src/core/lib/iomgr/polling_entity.h )
   s.files += %w( src/core/lib/iomgr/pollset.h )
   s.files += %w( src/core/lib/iomgr/pollset.h )
   s.files += %w( src/core/lib/iomgr/pollset_set.h )
   s.files += %w( src/core/lib/iomgr/pollset_set.h )
   s.files += %w( src/core/lib/iomgr/pollset_set_windows.h )
   s.files += %w( src/core/lib/iomgr/pollset_set_windows.h )
@@ -307,7 +307,6 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/client_config/subchannel_call_holder.h )
   s.files += %w( src/core/ext/client_config/subchannel_call_holder.h )
   s.files += %w( src/core/ext/client_config/subchannel_index.h )
   s.files += %w( src/core/ext/client_config/subchannel_index.h )
   s.files += %w( src/core/ext/client_config/uri_parser.h )
   s.files += %w( src/core/ext/client_config/uri_parser.h )
-  s.files += %w( third_party/objective_c/Cronet/cronet_c_for_grpc.h )
   s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.h )
   s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.h )
   s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h )
   s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h )
   s.files += %w( third_party/nanopb/pb.h )
   s.files += %w( third_party/nanopb/pb.h )
@@ -350,6 +349,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/iomgr/iomgr.c )
   s.files += %w( src/core/lib/iomgr/iomgr.c )
   s.files += %w( src/core/lib/iomgr/iomgr_posix.c )
   s.files += %w( src/core/lib/iomgr/iomgr_posix.c )
   s.files += %w( src/core/lib/iomgr/iomgr_windows.c )
   s.files += %w( src/core/lib/iomgr/iomgr_windows.c )
+  s.files += %w( src/core/lib/iomgr/polling_entity.c )
   s.files += %w( src/core/lib/iomgr/pollset_set_windows.c )
   s.files += %w( src/core/lib/iomgr/pollset_set_windows.c )
   s.files += %w( src/core/lib/iomgr/pollset_windows.c )
   s.files += %w( src/core/lib/iomgr/pollset_windows.c )
   s.files += %w( src/core/lib/iomgr/resolve_address_posix.c )
   s.files += %w( src/core/lib/iomgr/resolve_address_posix.c )
@@ -478,9 +478,6 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/client_config/uri_parser.c )
   s.files += %w( src/core/ext/client_config/uri_parser.c )
   s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2.c )
   s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2.c )
   s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create.c )
   s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create.c )
-  s.files += %w( src/core/ext/transport/cronet/client/secure/cronet_channel_create.c )
-  s.files += %w( src/core/ext/transport/cronet/transport/cronet_api_dummy.c )
-  s.files += %w( src/core/ext/transport/cronet/transport/cronet_transport.c )
   s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.c )
   s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.c )
   s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c )
   s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c )
   s.files += %w( third_party/nanopb/pb_common.c )
   s.files += %w( third_party/nanopb/pb_common.c )

+ 1 - 0
include/grpc++/impl/codegen/async_stream.h

@@ -172,6 +172,7 @@ class ClientAsyncWriter GRPC_FINAL : public ClientAsyncWriterInterface<W> {
                     R* response, void* tag)
                     R* response, void* tag)
       : context_(context), call_(channel->CreateCall(method, context, cq)) {
       : context_(context), call_(channel->CreateCall(method, context, cq)) {
     finish_ops_.RecvMessage(response);
     finish_ops_.RecvMessage(response);
+    finish_ops_.AllowNoMessage();
 
 
     init_ops_.set_output_tag(tag);
     init_ops_.set_output_tag(tag);
     init_ops_.SendInitialMetadata(context->send_initial_metadata_,
     init_ops_.SendInitialMetadata(context->send_initial_metadata_,

+ 1 - 0
include/grpc++/impl/codegen/async_unary_call.h

@@ -91,6 +91,7 @@ class ClientAsyncResponseReader GRPC_FINAL
       collection_->finish_buf_.RecvInitialMetadata(context_);
       collection_->finish_buf_.RecvInitialMetadata(context_);
     }
     }
     collection_->finish_buf_.RecvMessage(msg);
     collection_->finish_buf_.RecvMessage(msg);
+    collection_->finish_buf_.AllowNoMessage();
     collection_->finish_buf_.ClientRecvStatus(context_, status);
     collection_->finish_buf_.ClientRecvStatus(context_, status);
     call_.PerformOps(&collection_->finish_buf_);
     call_.PerformOps(&collection_->finish_buf_);
   }
   }

+ 20 - 4
include/grpc++/impl/codegen/call.h

@@ -273,10 +273,16 @@ Status CallOpSendMessage::SendMessage(const M& message) {
 template <class R>
 template <class R>
 class CallOpRecvMessage {
 class CallOpRecvMessage {
  public:
  public:
-  CallOpRecvMessage() : got_message(false), message_(nullptr) {}
+  CallOpRecvMessage()
+      : got_message(false),
+        message_(nullptr),
+        allow_not_getting_message_(false) {}
 
 
   void RecvMessage(R* message) { message_ = message; }
   void RecvMessage(R* message) { message_ = message; }
 
 
+  // Do not change status if no message is received.
+  void AllowNoMessage() { allow_not_getting_message_ = true; }
+
   bool got_message;
   bool got_message;
 
 
  protected:
  protected:
@@ -302,7 +308,9 @@ class CallOpRecvMessage {
       }
       }
     } else {
     } else {
       got_message = false;
       got_message = false;
-      *status = false;
+      if (!allow_not_getting_message_) {
+        *status = false;
+      }
     }
     }
     message_ = nullptr;
     message_ = nullptr;
   }
   }
@@ -310,6 +318,7 @@ class CallOpRecvMessage {
  private:
  private:
   R* message_;
   R* message_;
   grpc_byte_buffer* recv_buf_;
   grpc_byte_buffer* recv_buf_;
+  bool allow_not_getting_message_;
 };
 };
 
 
 namespace CallOpGenericRecvMessageHelper {
 namespace CallOpGenericRecvMessageHelper {
@@ -337,7 +346,8 @@ class DeserializeFuncType GRPC_FINAL : public DeserializeFunc {
 
 
 class CallOpGenericRecvMessage {
 class CallOpGenericRecvMessage {
  public:
  public:
-  CallOpGenericRecvMessage() : got_message(false) {}
+  CallOpGenericRecvMessage()
+      : got_message(false), allow_not_getting_message_(false) {}
 
 
   template <class R>
   template <class R>
   void RecvMessage(R* message) {
   void RecvMessage(R* message) {
@@ -348,6 +358,9 @@ class CallOpGenericRecvMessage {
     deserialize_.reset(func);
     deserialize_.reset(func);
   }
   }
 
 
+  // Do not change status if no message is received.
+  void AllowNoMessage() { allow_not_getting_message_ = true; }
+
   bool got_message;
   bool got_message;
 
 
  protected:
  protected:
@@ -372,7 +385,9 @@ class CallOpGenericRecvMessage {
       }
       }
     } else {
     } else {
       got_message = false;
       got_message = false;
-      *status = false;
+      if (!allow_not_getting_message_) {
+        *status = false;
+      }
     }
     }
     deserialize_.reset();
     deserialize_.reset();
   }
   }
@@ -380,6 +395,7 @@ class CallOpGenericRecvMessage {
  private:
  private:
   std::unique_ptr<CallOpGenericRecvMessageHelper::DeserializeFunc> deserialize_;
   std::unique_ptr<CallOpGenericRecvMessageHelper::DeserializeFunc> deserialize_;
   grpc_byte_buffer* recv_buf_;
   grpc_byte_buffer* recv_buf_;
+  bool allow_not_getting_message_;
 };
 };
 
 
 class CallOpClientSendClose {
 class CallOpClientSendClose {

+ 1 - 1
include/grpc++/impl/codegen/core_codegen_interface.h

@@ -34,7 +34,7 @@
 #ifndef GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H
 #ifndef GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H
 #define GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H
 #define GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H
 
 
-#include <grpc++/impl/codegen/config_protobuf.h>
+#include <grpc++/impl/codegen/config.h>
 #include <grpc++/impl/codegen/status.h>
 #include <grpc++/impl/codegen/status.h>
 #include <grpc/impl/codegen/grpc_types.h>
 #include <grpc/impl/codegen/grpc_types.h>
 
 

+ 1 - 0
include/grpc++/impl/codegen/sync_stream.h

@@ -189,6 +189,7 @@ class ClientWriter : public ClientWriterInterface<W> {
                ClientContext* context, R* response)
                ClientContext* context, R* response)
       : context_(context), call_(channel->CreateCall(method, context, &cq_)) {
       : context_(context), call_(channel->CreateCall(method, context, &cq_)) {
     finish_ops_.RecvMessage(response);
     finish_ops_.RecvMessage(response);
+    finish_ops_.AllowNoMessage();
 
 
     CallOpSet<CallOpSendInitialMetadata> ops;
     CallOpSet<CallOpSendInitialMetadata> ops;
     ops.SendInitialMetadata(context->send_initial_metadata_,
     ops.SendInitialMetadata(context->send_initial_metadata_,

+ 0 - 39
include/grpc++/support/config_protobuf.h

@@ -1,39 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPCXX_SUPPORT_CONFIG_PROTOBUF_H
-#define GRPCXX_SUPPORT_CONFIG_PROTOBUF_H
-
-#include <grpc++/impl/codegen/config_protobuf.h>
-
-#endif  // GRPCXX_SUPPORT_CONFIG_PROTOBUF_H

+ 2 - 5
package.xml

@@ -176,7 +176,6 @@
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_windows.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_windows.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/time.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/time.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/grpc_cronet.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc_security.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc_security.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc_security_constants.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc_security_constants.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/census.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/census.h" role="src" />
@@ -206,6 +205,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_internal.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_internal.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_posix.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_posix.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/polling_entity.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset_set.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset_set.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset_set_windows.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset_set_windows.h" role="src" />
@@ -314,7 +314,6 @@
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel_call_holder.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel_call_holder.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel_index.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel_index.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/uri_parser.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/uri_parser.h" role="src" />
-    <file baseinstalldir="/" name="third_party/objective_c/Cronet/cronet_c_for_grpc.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" role="src" />
     <file baseinstalldir="/" name="third_party/nanopb/pb.h" role="src" />
     <file baseinstalldir="/" name="third_party/nanopb/pb.h" role="src" />
@@ -357,6 +356,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/polling_entity.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset_set_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset_set_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/resolve_address_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/resolve_address_posix.c" role="src" />
@@ -485,9 +485,6 @@
     <file baseinstalldir="/" name="src/core/ext/client_config/uri_parser.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/uri_parser.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/insecure/server_chttp2.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/insecure/server_chttp2.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/transport/cronet/client/secure/cronet_channel_create.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/transport/cronet/transport/cronet_api_dummy.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/transport/cronet/transport/cronet_transport.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c" role="src" />
     <file baseinstalldir="/" name="third_party/nanopb/pb_common.c" role="src" />
     <file baseinstalldir="/" name="third_party/nanopb/pb_common.c" role="src" />

+ 9 - 2
src/compiler/config.h

@@ -34,8 +34,7 @@
 #ifndef SRC_COMPILER_CONFIG_H
 #ifndef SRC_COMPILER_CONFIG_H
 #define SRC_COMPILER_CONFIG_H
 #define SRC_COMPILER_CONFIG_H
 
 
-#include <grpc++/support/config.h>
-#include <grpc++/support/config_protobuf.h>
+#include <grpc++/impl/codegen/config_protobuf.h>
 
 
 #ifndef GRPC_CUSTOM_DESCRIPTOR
 #ifndef GRPC_CUSTOM_DESCRIPTOR
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/descriptor.h>
@@ -75,7 +74,15 @@
 #define GRPC_CUSTOM_PARSEGENERATORPARAMETER ::google::protobuf::compiler::ParseGeneratorParameter
 #define GRPC_CUSTOM_PARSEGENERATORPARAMETER ::google::protobuf::compiler::ParseGeneratorParameter
 #endif
 #endif
 
 
+#ifndef GRPC_CUSTOM_STRING
+#include <string>
+#define GRPC_CUSTOM_STRING std::string
+#endif
+
 namespace grpc {
 namespace grpc {
+
+typedef GRPC_CUSTOM_STRING string;
+
 namespace protobuf {
 namespace protobuf {
 typedef GRPC_CUSTOM_DESCRIPTOR Descriptor;
 typedef GRPC_CUSTOM_DESCRIPTOR Descriptor;
 typedef GRPC_CUSTOM_FILEDESCRIPTOR FileDescriptor;
 typedef GRPC_CUSTOM_FILEDESCRIPTOR FileDescriptor;

+ 7 - 109
src/compiler/csharp_generator.cc

@@ -119,18 +119,10 @@ std::string GetServiceClassName(const ServiceDescriptor* service) {
   return service->name();
   return service->name();
 }
 }
 
 
-std::string GetClientInterfaceName(const ServiceDescriptor* service) {
-  return "I" + service->name() + "Client";
-}
-
 std::string GetClientClassName(const ServiceDescriptor* service) {
 std::string GetClientClassName(const ServiceDescriptor* service) {
   return service->name() + "Client";
   return service->name() + "Client";
 }
 }
 
 
-std::string GetServerInterfaceName(const ServiceDescriptor* service) {
-  return "I" + service->name();
-}
-
 std::string GetServerClassName(const ServiceDescriptor* service) {
 std::string GetServerClassName(const ServiceDescriptor* service) {
   return service->name() + "Base";
   return service->name() + "Base";
 }
 }
@@ -302,86 +294,6 @@ void GenerateServiceDescriptorProperty(Printer* out, const ServiceDescriptor *se
   out->Print("\n");
   out->Print("\n");
 }
 }
 
 
-void GenerateClientInterface(Printer* out, const ServiceDescriptor *service) {
-  out->Print("/// <summary>Client for $servicename$</summary>\n",
-             "servicename", GetServiceClassName(service));
-  out->Print("[System.Obsolete(\"Client side interfaced will be removed "
-             "in the next release. Use client class directly.\")]\n");
-  out->Print("public interface $name$\n", "name",
-             GetClientInterfaceName(service));
-  out->Print("{\n");
-  out->Indent();
-  for (int i = 0; i < service->method_count(); i++) {
-    const MethodDescriptor *method = service->method(i);
-    MethodType method_type = GetMethodType(method);
-
-    if (method_type == METHODTYPE_NO_STREAMING) {
-      // unary calls have an extra synchronous stub method
-      GenerateDocCommentBody(out, method);
-      out->Print(
-          "$response$ $methodname$($request$ request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));\n",
-          "methodname", method->name(), "request",
-          GetClassName(method->input_type()), "response",
-          GetClassName(method->output_type()));
-
-      // overload taking CallOptions as a param
-      GenerateDocCommentBody(out, method);
-      out->Print(
-          "$response$ $methodname$($request$ request, CallOptions options);\n",
-          "methodname", method->name(), "request",
-          GetClassName(method->input_type()), "response",
-          GetClassName(method->output_type()));
-    }
-
-    std::string method_name = method->name();
-    if (method_type == METHODTYPE_NO_STREAMING) {
-      method_name += "Async";  // prevent name clash with synchronous method.
-    }
-    GenerateDocCommentBody(out, method);
-    out->Print(
-        "$returntype$ $methodname$($request_maybe$Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));\n",
-        "methodname", method_name, "request_maybe",
-        GetMethodRequestParamMaybe(method), "returntype",
-        GetMethodReturnTypeClient(method));
-
-    // overload taking CallOptions as a param
-    GenerateDocCommentBody(out, method);
-    out->Print(
-        "$returntype$ $methodname$($request_maybe$CallOptions options);\n",
-        "methodname", method_name, "request_maybe",
-        GetMethodRequestParamMaybe(method), "returntype",
-        GetMethodReturnTypeClient(method));
-  }
-  out->Outdent();
-  out->Print("}\n");
-  out->Print("\n");
-}
-
-void GenerateServerInterface(Printer* out, const ServiceDescriptor *service) {
-  out->Print("/// <summary>Interface of server-side implementations of $servicename$</summary>\n",
-             "servicename", GetServiceClassName(service));
-  out->Print("[System.Obsolete(\"Service implementations should inherit"
-      " from the generated abstract base class instead.\")]\n");
-  out->Print("public interface $name$\n", "name",
-             GetServerInterfaceName(service));
-  out->Print("{\n");
-  out->Indent();
-  for (int i = 0; i < service->method_count(); i++) {
-    const MethodDescriptor *method = service->method(i);
-    GenerateDocCommentBody(out, method);
-    out->Print(
-        "$returntype$ $methodname$($request$$response_stream_maybe$, "
-        "ServerCallContext context);\n",
-        "methodname", method->name(), "returntype",
-        GetMethodReturnTypeServer(method), "request",
-        GetMethodRequestParamServer(method), "response_stream_maybe",
-        GetMethodResponseStreamMaybe(method));
-  }
-  out->Outdent();
-  out->Print("}\n");
-  out->Print("\n");
-}
-
 void GenerateServerClass(Printer* out, const ServiceDescriptor *service) {
 void GenerateServerClass(Printer* out, const ServiceDescriptor *service) {
   out->Print("/// <summary>Base class for server-side implementations of $servicename$</summary>\n",
   out->Print("/// <summary>Base class for server-side implementations of $servicename$</summary>\n",
              "servicename", GetServiceClassName(service));
              "servicename", GetServiceClassName(service));
@@ -414,12 +326,9 @@ void GenerateServerClass(Printer* out, const ServiceDescriptor *service) {
 void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
 void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
   out->Print("/// <summary>Client for $servicename$</summary>\n",
   out->Print("/// <summary>Client for $servicename$</summary>\n",
              "servicename", GetServiceClassName(service));
              "servicename", GetServiceClassName(service));
-  out->Print("#pragma warning disable 0618\n");
   out->Print(
   out->Print(
-      "public class $name$ : ClientBase<$name$>, $interface$\n",
-      "name", GetClientClassName(service),
-      "interface", GetClientInterfaceName(service));
-  out->Print("#pragma warning restore 0618\n");
+      "public class $name$ : ClientBase<$name$>\n",
+      "name", GetClientClassName(service));
   out->Print("{\n");
   out->Print("{\n");
   out->Indent();
   out->Indent();
 
 
@@ -546,22 +455,16 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
   out->Print("\n");
   out->Print("\n");
 }
 }
 
 
-void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor *service,
-                               bool use_server_class) {
+void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor *service) {
   out->Print(
   out->Print(
       "/// <summary>Creates service definition that can be registered with a server</summary>\n");
       "/// <summary>Creates service definition that can be registered with a server</summary>\n");
-  out->Print("#pragma warning disable 0618\n");
   out->Print(
   out->Print(
-      "public static ServerServiceDefinition BindService($interface$ serviceImpl)\n",
-      "interface", use_server_class ? GetServerClassName(service) :
-          GetServerInterfaceName(service));
-  out->Print("#pragma warning restore 0618\n");
+      "public static ServerServiceDefinition BindService($implclass$ serviceImpl)\n",
+      "implclass", GetServerClassName(service));
   out->Print("{\n");
   out->Print("{\n");
   out->Indent();
   out->Indent();
 
 
-  out->Print(
-      "return ServerServiceDefinition.CreateBuilder($servicenamefield$)\n",
-      "servicenamefield", GetServiceNameFieldName());
+  out->Print("return ServerServiceDefinition.CreateBuilder()\n");
   out->Indent();
   out->Indent();
   out->Indent();
   out->Indent();
   for (int i = 0; i < service->method_count(); i++) {
   for (int i = 0; i < service->method_count(); i++) {
@@ -616,11 +519,7 @@ void GenerateService(Printer* out, const ServiceDescriptor *service,
   }
   }
   GenerateServiceDescriptorProperty(out, service);
   GenerateServiceDescriptorProperty(out, service);
 
 
-  if (generate_client) {
-    GenerateClientInterface(out, service);
-  }
   if (generate_server) {
   if (generate_server) {
-    GenerateServerInterface(out, service);
     GenerateServerClass(out, service);
     GenerateServerClass(out, service);
   }
   }
   if (generate_client) {
   if (generate_client) {
@@ -628,8 +527,7 @@ void GenerateService(Printer* out, const ServiceDescriptor *service,
     GenerateNewStubMethods(out, service);
     GenerateNewStubMethods(out, service);
   }
   }
   if (generate_server) {
   if (generate_server) {
-    GenerateBindServiceMethod(out, service, false);
-    GenerateBindServiceMethod(out, service, true);
+    GenerateBindServiceMethod(out, service);
   }
   }
 
 
   out->Outdent();
   out->Outdent();

+ 2 - 2
src/core/ext/census/grpc_filter.c

@@ -180,7 +180,7 @@ const grpc_channel_filter grpc_client_census_filter = {
     grpc_channel_next_op,
     grpc_channel_next_op,
     sizeof(call_data),
     sizeof(call_data),
     client_init_call_elem,
     client_init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     client_destroy_call_elem,
     client_destroy_call_elem,
     sizeof(channel_data),
     sizeof(channel_data),
     init_channel_elem,
     init_channel_elem,
@@ -193,7 +193,7 @@ const grpc_channel_filter grpc_server_census_filter = {
     grpc_channel_next_op,
     grpc_channel_next_op,
     sizeof(call_data),
     sizeof(call_data),
     server_init_call_elem,
     server_init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     server_destroy_call_elem,
     server_destroy_call_elem,
     sizeof(channel_data),
     sizeof(channel_data),
     init_channel_elem,
     init_channel_elem,

+ 6 - 5
src/core/ext/client_config/client_channel.c

@@ -376,7 +376,7 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp,
     int r;
     int r;
     GRPC_LB_POLICY_REF(lb_policy, "cc_pick_subchannel");
     GRPC_LB_POLICY_REF(lb_policy, "cc_pick_subchannel");
     gpr_mu_unlock(&chand->mu_config);
     gpr_mu_unlock(&chand->mu_config);
-    r = grpc_lb_policy_pick(exec_ctx, lb_policy, calld->pollset,
+    r = grpc_lb_policy_pick(exec_ctx, lb_policy, calld->pollent,
                             initial_metadata, initial_metadata_flags,
                             initial_metadata, initial_metadata_flags,
                             connected_subchannel, on_ready);
                             connected_subchannel, on_ready);
     GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "cc_pick_subchannel");
     GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "cc_pick_subchannel");
@@ -461,10 +461,11 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
   gpr_mu_destroy(&chand->mu_config);
   gpr_mu_destroy(&chand->mu_config);
 }
 }
 
 
-static void cc_set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                           grpc_pollset *pollset) {
+static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
+                                          grpc_call_element *elem,
+                                          grpc_polling_entity *pollent) {
   call_data *calld = elem->call_data;
   call_data *calld = elem->call_data;
-  calld->pollset = pollset;
+  calld->pollent = pollent;
 }
 }
 
 
 const grpc_channel_filter grpc_client_channel_filter = {
 const grpc_channel_filter grpc_client_channel_filter = {
@@ -472,7 +473,7 @@ const grpc_channel_filter grpc_client_channel_filter = {
     cc_start_transport_op,
     cc_start_transport_op,
     sizeof(call_data),
     sizeof(call_data),
     init_call_elem,
     init_call_elem,
-    cc_set_pollset,
+    cc_set_pollset_or_pollset_set,
     destroy_call_elem,
     destroy_call_elem,
     sizeof(channel_data),
     sizeof(channel_data),
     init_channel_elem,
     init_channel_elem,

+ 2 - 2
src/core/ext/client_config/lb_policy.c

@@ -99,12 +99,12 @@ void grpc_lb_policy_weak_unref(grpc_exec_ctx *exec_ctx,
 }
 }
 
 
 int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
 int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
-                        grpc_pollset *pollset,
+                        grpc_polling_entity *pollent,
                         grpc_metadata_batch *initial_metadata,
                         grpc_metadata_batch *initial_metadata,
                         uint32_t initial_metadata_flags,
                         uint32_t initial_metadata_flags,
                         grpc_connected_subchannel **target,
                         grpc_connected_subchannel **target,
                         grpc_closure *on_complete) {
                         grpc_closure *on_complete) {
-  return policy->vtable->pick(exec_ctx, policy, pollset, initial_metadata,
+  return policy->vtable->pick(exec_ctx, policy, pollent, initial_metadata,
                               initial_metadata_flags, target, on_complete);
                               initial_metadata_flags, target, on_complete);
 }
 }
 
 

+ 4 - 2
src/core/ext/client_config/lb_policy.h

@@ -35,6 +35,7 @@
 #define GRPC_CORE_EXT_CLIENT_CONFIG_LB_POLICY_H
 #define GRPC_CORE_EXT_CLIENT_CONFIG_LB_POLICY_H
 
 
 #include "src/core/ext/client_config/subchannel.h"
 #include "src/core/ext/client_config/subchannel.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/transport/connectivity_state.h"
 #include "src/core/lib/transport/connectivity_state.h"
 
 
 /** A load balancing policy: specified by a vtable and a struct (which
 /** A load balancing policy: specified by a vtable and a struct (which
@@ -59,7 +60,8 @@ struct grpc_lb_policy_vtable {
 
 
   /** implement grpc_lb_policy_pick */
   /** implement grpc_lb_policy_pick */
   int (*pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
   int (*pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
-              grpc_pollset *pollset, grpc_metadata_batch *initial_metadata,
+              grpc_polling_entity *pollent,
+              grpc_metadata_batch *initial_metadata,
               uint32_t initial_metadata_flags,
               uint32_t initial_metadata_flags,
               grpc_connected_subchannel **target, grpc_closure *on_complete);
               grpc_connected_subchannel **target, grpc_closure *on_complete);
   void (*cancel_pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
   void (*cancel_pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
@@ -124,7 +126,7 @@ void grpc_lb_policy_init(grpc_lb_policy *policy,
     \a target.
     \a target.
     Picking can be asynchronous. Any IO should be done under \a pollset. */
     Picking can be asynchronous. Any IO should be done under \a pollset. */
 int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
 int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
-                        grpc_pollset *pollset,
+                        grpc_polling_entity *pollent,
                         grpc_metadata_batch *initial_metadata,
                         grpc_metadata_batch *initial_metadata,
                         uint32_t initial_metadata_flags,
                         uint32_t initial_metadata_flags,
                         grpc_connected_subchannel **target,
                         grpc_connected_subchannel **target,

+ 2 - 2
src/core/ext/client_config/subchannel.c

@@ -683,7 +683,7 @@ grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel(
 
 
 grpc_subchannel_call *grpc_connected_subchannel_create_call(
 grpc_subchannel_call *grpc_connected_subchannel_create_call(
     grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con,
     grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con,
-    grpc_pollset *pollset) {
+    grpc_polling_entity *pollent) {
   grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con);
   grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con);
   grpc_subchannel_call *call =
   grpc_subchannel_call *call =
       gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size);
       gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size);
@@ -692,7 +692,7 @@ grpc_subchannel_call *grpc_connected_subchannel_create_call(
   GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call");
   GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call");
   grpc_call_stack_init(exec_ctx, chanstk, 1, subchannel_call_destroy, call,
   grpc_call_stack_init(exec_ctx, chanstk, 1, subchannel_call_destroy, call,
                        NULL, NULL, callstk);
                        NULL, NULL, callstk);
-  grpc_call_stack_set_pollset(exec_ctx, callstk, pollset);
+  grpc_call_stack_set_pollset_or_pollset_set(exec_ctx, callstk, pollent);
   return call;
   return call;
 }
 }
 
 

+ 2 - 1
src/core/ext/client_config/subchannel.h

@@ -36,6 +36,7 @@
 
 
 #include "src/core/ext/client_config/connector.h"
 #include "src/core/ext/client_config/connector.h"
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/channel/channel_stack.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/transport/connectivity_state.h"
 #include "src/core/lib/transport/connectivity_state.h"
 
 
 /** A (sub-)channel that knows how to connect to exactly one target
 /** A (sub-)channel that knows how to connect to exactly one target
@@ -109,7 +110,7 @@ void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx,
 /** construct a subchannel call */
 /** construct a subchannel call */
 grpc_subchannel_call *grpc_connected_subchannel_create_call(
 grpc_subchannel_call *grpc_connected_subchannel_create_call(
     grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel,
     grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel,
-    grpc_pollset *pollset);
+    grpc_polling_entity *pollent);
 
 
 /** process a transport level op */
 /** process a transport level op */
 void grpc_connected_subchannel_process_transport_op(
 void grpc_connected_subchannel_process_transport_op(

+ 3 - 2
src/core/ext/client_config/subchannel_call_holder.c

@@ -68,6 +68,7 @@ void grpc_subchannel_call_holder_init(
   holder->waiting_ops_capacity = 0;
   holder->waiting_ops_capacity = 0;
   holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
   holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
   holder->owning_call = owning_call;
   holder->owning_call = owning_call;
+  holder->pollent = NULL;
 }
 }
 
 
 void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx,
 void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx,
@@ -157,7 +158,7 @@ retry:
     gpr_atm_rel_store(
     gpr_atm_rel_store(
         &holder->subchannel_call,
         &holder->subchannel_call,
         (gpr_atm)(uintptr_t)grpc_connected_subchannel_create_call(
         (gpr_atm)(uintptr_t)grpc_connected_subchannel_create_call(
-            exec_ctx, holder->connected_subchannel, holder->pollset));
+            exec_ctx, holder->connected_subchannel, holder->pollent));
     retry_waiting_locked(exec_ctx, holder);
     retry_waiting_locked(exec_ctx, holder);
     goto retry;
     goto retry;
   }
   }
@@ -183,7 +184,7 @@ static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
     gpr_atm_rel_store(
     gpr_atm_rel_store(
         &holder->subchannel_call,
         &holder->subchannel_call,
         (gpr_atm)(uintptr_t)grpc_connected_subchannel_create_call(
         (gpr_atm)(uintptr_t)grpc_connected_subchannel_create_call(
-            exec_ctx, holder->connected_subchannel, holder->pollset));
+            exec_ctx, holder->connected_subchannel, holder->pollent));
     retry_waiting_locked(exec_ctx, holder);
     retry_waiting_locked(exec_ctx, holder);
   }
   }
   gpr_mu_unlock(&holder->mu);
   gpr_mu_unlock(&holder->mu);

+ 2 - 1
src/core/ext/client_config/subchannel_call_holder.h

@@ -35,6 +35,7 @@
 #define GRPC_CORE_EXT_CLIENT_CONFIG_SUBCHANNEL_CALL_HOLDER_H
 #define GRPC_CORE_EXT_CLIENT_CONFIG_SUBCHANNEL_CALL_HOLDER_H
 
 
 #include "src/core/ext/client_config/subchannel.h"
 #include "src/core/ext/client_config/subchannel.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 
 
 /** Pick a subchannel for grpc_subchannel_call_holder;
 /** Pick a subchannel for grpc_subchannel_call_holder;
     Return 1 if subchannel is available immediately (in which case on_ready
     Return 1 if subchannel is available immediately (in which case on_ready
@@ -71,7 +72,7 @@ typedef struct grpc_subchannel_call_holder {
 
 
   grpc_subchannel_call_holder_creation_phase creation_phase;
   grpc_subchannel_call_holder_creation_phase creation_phase;
   grpc_connected_subchannel *connected_subchannel;
   grpc_connected_subchannel *connected_subchannel;
-  grpc_pollset *pollset;
+  grpc_polling_entity *pollent;
 
 
   grpc_transport_stream_op *waiting_ops;
   grpc_transport_stream_op *waiting_ops;
   size_t waiting_ops_count;
   size_t waiting_ops_count;

+ 14 - 12
src/core/ext/lb_policy/pick_first/pick_first.c

@@ -39,7 +39,7 @@
 
 
 typedef struct pending_pick {
 typedef struct pending_pick {
   struct pending_pick *next;
   struct pending_pick *next;
-  grpc_pollset *pollset;
+  grpc_polling_entity *pollent;
   uint32_t initial_metadata_flags;
   uint32_t initial_metadata_flags;
   grpc_connected_subchannel **target;
   grpc_connected_subchannel **target;
   grpc_closure *on_complete;
   grpc_closure *on_complete;
@@ -118,8 +118,8 @@ static void pf_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
   while (pp != NULL) {
   while (pp != NULL) {
     pending_pick *next = pp->next;
     pending_pick *next = pp->next;
     *pp->target = NULL;
     *pp->target = NULL;
-    grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
-                                 pp->pollset);
+    grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
+                                             p->base.interested_parties);
     grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
     grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
     gpr_free(pp);
     gpr_free(pp);
     pp = next;
     pp = next;
@@ -136,8 +136,8 @@ static void pf_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
   while (pp != NULL) {
   while (pp != NULL) {
     pending_pick *next = pp->next;
     pending_pick *next = pp->next;
     if (pp->target == target) {
     if (pp->target == target) {
-      grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
-                                   pp->pollset);
+      grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
+                                               p->base.interested_parties);
       *target = NULL;
       *target = NULL;
       grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
       grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
       gpr_free(pp);
       gpr_free(pp);
@@ -162,8 +162,8 @@ static void pf_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     pending_pick *next = pp->next;
     pending_pick *next = pp->next;
     if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
     if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
         initial_metadata_flags_eq) {
         initial_metadata_flags_eq) {
-      grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
-                                   pp->pollset);
+      grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
+                                               p->base.interested_parties);
       grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
       grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
       gpr_free(pp);
       gpr_free(pp);
     } else {
     } else {
@@ -196,7 +196,8 @@ static void pf_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
 }
 }
 
 
 static int pf_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
 static int pf_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
-                   grpc_pollset *pollset, grpc_metadata_batch *initial_metadata,
+                   grpc_polling_entity *pollent,
+                   grpc_metadata_batch *initial_metadata,
                    uint32_t initial_metadata_flags,
                    uint32_t initial_metadata_flags,
                    grpc_connected_subchannel **target,
                    grpc_connected_subchannel **target,
                    grpc_closure *on_complete) {
                    grpc_closure *on_complete) {
@@ -221,10 +222,11 @@ static int pf_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     if (!p->started_picking) {
     if (!p->started_picking) {
       start_picking(exec_ctx, p);
       start_picking(exec_ctx, p);
     }
     }
-    grpc_pollset_set_add_pollset(exec_ctx, p->base.interested_parties, pollset);
+    grpc_polling_entity_add_to_pollset_set(exec_ctx, pollent,
+                                           p->base.interested_parties);
     pp = gpr_malloc(sizeof(*pp));
     pp = gpr_malloc(sizeof(*pp));
     pp->next = p->pending_picks;
     pp->next = p->pending_picks;
-    pp->pollset = pollset;
+    pp->pollent = pollent;
     pp->target = target;
     pp->target = target;
     pp->initial_metadata_flags = initial_metadata_flags;
     pp->initial_metadata_flags = initial_metadata_flags;
     pp->on_complete = on_complete;
     pp->on_complete = on_complete;
@@ -304,8 +306,8 @@ static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
         while ((pp = p->pending_picks)) {
         while ((pp = p->pending_picks)) {
           p->pending_picks = pp->next;
           p->pending_picks = pp->next;
           *pp->target = selected;
           *pp->target = selected;
-          grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
-                                       pp->pollset);
+          grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
+                                                   p->base.interested_parties);
           grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
           grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
           gpr_free(pp);
           gpr_free(pp);
         }
         }

+ 12 - 10
src/core/ext/lb_policy/round_robin/round_robin.c

@@ -48,7 +48,7 @@ int grpc_lb_round_robin_trace = 0;
  * Once a pick is available, \a target is updated and \a on_complete called. */
  * Once a pick is available, \a target is updated and \a on_complete called. */
 typedef struct pending_pick {
 typedef struct pending_pick {
   struct pending_pick *next;
   struct pending_pick *next;
-  grpc_pollset *pollset;
+  grpc_polling_entity *pollent;
   uint32_t initial_metadata_flags;
   uint32_t initial_metadata_flags;
   grpc_connected_subchannel **target;
   grpc_connected_subchannel **target;
   grpc_closure *on_complete;
   grpc_closure *on_complete;
@@ -262,8 +262,8 @@ static void rr_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
   while (pp != NULL) {
   while (pp != NULL) {
     pending_pick *next = pp->next;
     pending_pick *next = pp->next;
     if (pp->target == target) {
     if (pp->target == target) {
-      grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
-                                   pp->pollset);
+      grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
+                                               p->base.interested_parties);
       *target = NULL;
       *target = NULL;
       grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
       grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
       gpr_free(pp);
       gpr_free(pp);
@@ -288,8 +288,8 @@ static void rr_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     pending_pick *next = pp->next;
     pending_pick *next = pp->next;
     if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
     if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
         initial_metadata_flags_eq) {
         initial_metadata_flags_eq) {
-      grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
-                                   pp->pollset);
+      grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
+                                               p->base.interested_parties);
       *pp->target = NULL;
       *pp->target = NULL;
       grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
       grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
       gpr_free(pp);
       gpr_free(pp);
@@ -331,7 +331,8 @@ static void rr_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
 }
 }
 
 
 static int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
 static int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
-                   grpc_pollset *pollset, grpc_metadata_batch *initial_metadata,
+                   grpc_polling_entity *pollent,
+                   grpc_metadata_batch *initial_metadata,
                    uint32_t initial_metadata_flags,
                    uint32_t initial_metadata_flags,
                    grpc_connected_subchannel **target,
                    grpc_connected_subchannel **target,
                    grpc_closure *on_complete) {
                    grpc_closure *on_complete) {
@@ -354,10 +355,11 @@ static int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
     if (!p->started_picking) {
     if (!p->started_picking) {
       start_picking(exec_ctx, p);
       start_picking(exec_ctx, p);
     }
     }
-    grpc_pollset_set_add_pollset(exec_ctx, p->base.interested_parties, pollset);
+    grpc_polling_entity_add_to_pollset_set(exec_ctx, pollent,
+                                           p->base.interested_parties);
     pp = gpr_malloc(sizeof(*pp));
     pp = gpr_malloc(sizeof(*pp));
     pp->next = p->pending_picks;
     pp->next = p->pending_picks;
-    pp->pollset = pollset;
+    pp->pollent = pollent;
     pp->target = target;
     pp->target = target;
     pp->on_complete = on_complete;
     pp->on_complete = on_complete;
     pp->initial_metadata_flags = initial_metadata_flags;
     pp->initial_metadata_flags = initial_metadata_flags;
@@ -406,8 +408,8 @@ static void rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
                     "[RR CONN CHANGED] TARGET <-- SUBCHANNEL %p (NODE %p)",
                     "[RR CONN CHANGED] TARGET <-- SUBCHANNEL %p (NODE %p)",
                     selected->subchannel, selected);
                     selected->subchannel, selected);
           }
           }
-          grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
-                                       pp->pollset);
+          grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
+                                                   p->base.interested_parties);
           grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
           grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
           gpr_free(pp);
           gpr_free(pp);
         }
         }

+ 1 - 1
src/core/ext/load_reporting/load_reporting_filter.c

@@ -142,7 +142,7 @@ const grpc_channel_filter grpc_load_reporting_filter = {
     grpc_channel_next_op,
     grpc_channel_next_op,
     sizeof(call_data),
     sizeof(call_data),
     init_call_elem,
     init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     destroy_call_elem,
     destroy_call_elem,
     sizeof(channel_data),
     sizeof(channel_data),
     init_channel_elem,
     init_channel_elem,

+ 8 - 0
src/core/ext/transport/chttp2/transport/chttp2_transport.c

@@ -1734,6 +1734,13 @@ static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
                                    add_to_pollset_locked, pollset, 0);
                                    add_to_pollset_locked, pollset, 0);
 }
 }
 
 
+static void set_pollset_set(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
+                            grpc_stream *gs, grpc_pollset_set *pollset_set) {
+  grpc_chttp2_run_with_global_lock(exec_ctx, (grpc_chttp2_transport *)gt,
+                                   (grpc_chttp2_stream *)gs,
+                                   add_to_pollset_set_locked, pollset_set, 0);
+}
+
 /*******************************************************************************
 /*******************************************************************************
  * BYTE STREAM
  * BYTE STREAM
  */
  */
@@ -2055,6 +2062,7 @@ static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream),
                                              "chttp2",
                                              "chttp2",
                                              init_stream,
                                              init_stream,
                                              set_pollset,
                                              set_pollset,
+                                             set_pollset_set,
                                              perform_stream_op,
                                              perform_stream_op,
                                              perform_transport_op,
                                              perform_transport_op,
                                              destroy_stream,
                                              destroy_stream,

+ 14 - 4
src/core/ext/transport/cronet/transport/cronet_transport.c

@@ -152,6 +152,10 @@ static void next_recv_step(stream_obj *s, enum e_caller caller);
 static void set_pollset_do_nothing(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
 static void set_pollset_do_nothing(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
                                    grpc_stream *gs, grpc_pollset *pollset) {}
                                    grpc_stream *gs, grpc_pollset *pollset) {}
 
 
+static void set_pollset_set_do_nothing(grpc_exec_ctx *exec_ctx,
+                                       grpc_transport *gt, grpc_stream *gs,
+                                       grpc_pollset_set *pollset_set) {}
+
 static void enqueue_callbacks(grpc_closure *callback_list[]) {
 static void enqueue_callbacks(grpc_closure *callback_list[]) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   if (callback_list[0]) {
   if (callback_list[0]) {
@@ -646,7 +650,13 @@ static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {
   }
   }
 }
 }
 
 
-const grpc_transport_vtable grpc_cronet_vtable = {
-    sizeof(stream_obj),     "cronet_http",     init_stream,
-    set_pollset_do_nothing, perform_stream_op, NULL,
-    destroy_stream,         destroy_transport, NULL};
+const grpc_transport_vtable grpc_cronet_vtable = {sizeof(stream_obj),
+                                                  "cronet_http",
+                                                  init_stream,
+                                                  set_pollset_do_nothing,
+                                                  set_pollset_set_do_nothing,
+                                                  perform_stream_op,
+                                                  NULL,
+                                                  destroy_stream,
+                                                  destroy_transport,
+                                                  NULL};

+ 8 - 7
src/core/lib/channel/channel_stack.c

@@ -189,9 +189,9 @@ void grpc_call_stack_init(grpc_exec_ctx *exec_ctx,
   }
   }
 }
 }
 
 
-void grpc_call_stack_set_pollset(grpc_exec_ctx *exec_ctx,
-                                 grpc_call_stack *call_stack,
-                                 grpc_pollset *pollset) {
+void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
+                                                grpc_call_stack *call_stack,
+                                                grpc_polling_entity *pollent) {
   size_t count = call_stack->count;
   size_t count = call_stack->count;
   grpc_call_element *call_elems;
   grpc_call_element *call_elems;
   char *user_data;
   char *user_data;
@@ -203,15 +203,16 @@ void grpc_call_stack_set_pollset(grpc_exec_ctx *exec_ctx,
 
 
   /* init per-filter data */
   /* init per-filter data */
   for (i = 0; i < count; i++) {
   for (i = 0; i < count; i++) {
-    call_elems[i].filter->set_pollset(exec_ctx, &call_elems[i], pollset);
+    call_elems[i].filter->set_pollset_or_pollset_set(exec_ctx, &call_elems[i],
+                                                     pollent);
     user_data +=
     user_data +=
         ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data);
         ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data);
   }
   }
 }
 }
 
 
-void grpc_call_stack_ignore_set_pollset(grpc_exec_ctx *exec_ctx,
-                                        grpc_call_element *elem,
-                                        grpc_pollset *pollset) {}
+void grpc_call_stack_ignore_set_pollset_or_pollset_set(
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    grpc_polling_entity *pollent) {}
 
 
 void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack,
 void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack,
                              const grpc_call_stats *call_stats,
                              const grpc_call_stats *call_stats,

+ 14 - 11
src/core/lib/channel/channel_stack.h

@@ -48,6 +48,7 @@
 #include <grpc/support/time.h>
 #include <grpc/support/time.h>
 
 
 #include "src/core/lib/debug/trace.h"
 #include "src/core/lib/debug/trace.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/transport/transport.h"
 #include "src/core/lib/transport/transport.h"
 
 
 typedef struct grpc_channel_element grpc_channel_element;
 typedef struct grpc_channel_element grpc_channel_element;
@@ -109,8 +110,9 @@ typedef struct {
      argument. */
      argument. */
   void (*init_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
   void (*init_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                          grpc_call_element_args *args);
                          grpc_call_element_args *args);
-  void (*set_pollset)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                      grpc_pollset *pollset);
+  void (*set_pollset_or_pollset_set)(grpc_exec_ctx *exec_ctx,
+                                     grpc_call_element *elem,
+                                     grpc_polling_entity *pollent);
   /* Destroy per call data.
   /* Destroy per call data.
      The filter does not need to do any chaining.
      The filter does not need to do any chaining.
      The bottom filter of a stack will be passed a non-NULL pointer to
      The bottom filter of a stack will be passed a non-NULL pointer to
@@ -210,10 +212,11 @@ void grpc_call_stack_init(grpc_exec_ctx *exec_ctx,
                           grpc_call_context_element *context,
                           grpc_call_context_element *context,
                           const void *transport_server_data,
                           const void *transport_server_data,
                           grpc_call_stack *call_stack);
                           grpc_call_stack *call_stack);
-/* Set a pollset for a call stack: must occur before the first op is started */
-void grpc_call_stack_set_pollset(grpc_exec_ctx *exec_ctx,
-                                 grpc_call_stack *call_stack,
-                                 grpc_pollset *pollset);
+/* Set a pollset or a pollset_set for a call stack: must occur before the first
+ * op is started */
+void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
+                                                grpc_call_stack *call_stack,
+                                                grpc_polling_entity *pollent);
 
 
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
 #define GRPC_CALL_STACK_REF(call_stack, reason) \
 #define GRPC_CALL_STACK_REF(call_stack, reason) \
@@ -240,11 +243,11 @@ void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack,
                              const grpc_call_stats *call_stats,
                              const grpc_call_stats *call_stats,
                              void *and_free_memory);
                              void *and_free_memory);
 
 
-/* Ignore set pollset - used by filters to implement the set_pollset method
-   if they don't care about pollsets at all. Does nothing. */
-void grpc_call_stack_ignore_set_pollset(grpc_exec_ctx *exec_ctx,
-                                        grpc_call_element *elem,
-                                        grpc_pollset *pollset);
+/* Ignore set pollset{_set} - used by filters if they don't care about pollsets
+ * at all. Does nothing. */
+void grpc_call_stack_ignore_set_pollset_or_pollset_set(
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    grpc_polling_entity *pollent);
 /* Call the next operation in a call stack */
 /* Call the next operation in a call stack */
 void grpc_call_next_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 void grpc_call_next_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                        grpc_transport_stream_op *op);
                        grpc_transport_stream_op *op);

+ 1 - 1
src/core/lib/channel/compress_filter.c

@@ -318,7 +318,7 @@ const grpc_channel_filter grpc_compress_filter = {
     grpc_channel_next_op,
     grpc_channel_next_op,
     sizeof(call_data),
     sizeof(call_data),
     init_call_elem,
     init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     destroy_call_elem,
     destroy_call_elem,
     sizeof(channel_data),
     sizeof(channel_data),
     init_channel_elem,
     init_channel_elem,

+ 6 - 5
src/core/lib/channel/connected_channel.c

@@ -93,12 +93,13 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
   GPR_ASSERT(r == 0);
   GPR_ASSERT(r == 0);
 }
 }
 
 
-static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                        grpc_pollset *pollset) {
+static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
+                                       grpc_call_element *elem,
+                                       grpc_polling_entity *pollent) {
   call_data *calld = elem->call_data;
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
   channel_data *chand = elem->channel_data;
-  grpc_transport_set_pollset(exec_ctx, chand->transport,
-                             TRANSPORT_STREAM_FROM_CALL_DATA(calld), pollset);
+  grpc_transport_set_pops(exec_ctx, chand->transport,
+                          TRANSPORT_STREAM_FROM_CALL_DATA(calld), pollent);
 }
 }
 
 
 /* Destructor for call_data */
 /* Destructor for call_data */
@@ -138,7 +139,7 @@ static const grpc_channel_filter connected_channel_filter = {
     con_start_transport_op,
     con_start_transport_op,
     sizeof(call_data),
     sizeof(call_data),
     init_call_elem,
     init_call_elem,
-    set_pollset,
+    set_pollset_or_pollset_set,
     destroy_call_elem,
     destroy_call_elem,
     sizeof(channel_data),
     sizeof(channel_data),
     init_channel_elem,
     init_channel_elem,

+ 1 - 1
src/core/lib/channel/http_client_filter.c

@@ -250,7 +250,7 @@ const grpc_channel_filter grpc_http_client_filter = {
     grpc_channel_next_op,
     grpc_channel_next_op,
     sizeof(call_data),
     sizeof(call_data),
     init_call_elem,
     init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     destroy_call_elem,
     destroy_call_elem,
     sizeof(channel_data),
     sizeof(channel_data),
     init_channel_elem,
     init_channel_elem,

+ 1 - 1
src/core/lib/channel/http_server_filter.c

@@ -244,7 +244,7 @@ const grpc_channel_filter grpc_http_server_filter = {
     grpc_channel_next_op,
     grpc_channel_next_op,
     sizeof(call_data),
     sizeof(call_data),
     init_call_elem,
     init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     destroy_call_elem,
     destroy_call_elem,
     sizeof(channel_data),
     sizeof(channel_data),
     init_channel_elem,
     init_channel_elem,

+ 12 - 11
src/core/lib/http/httpcli.c

@@ -62,7 +62,7 @@ typedef struct {
   grpc_httpcli_response_cb on_response;
   grpc_httpcli_response_cb on_response;
   void *user_data;
   void *user_data;
   grpc_httpcli_context *context;
   grpc_httpcli_context *context;
-  grpc_pollset *pollset;
+  grpc_polling_entity *pollent;
   grpc_iomgr_object iomgr_obj;
   grpc_iomgr_object iomgr_obj;
   gpr_slice_buffer incoming;
   gpr_slice_buffer incoming;
   gpr_slice_buffer outgoing;
   gpr_slice_buffer outgoing;
@@ -97,8 +97,8 @@ static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req);
 
 
 static void finish(grpc_exec_ctx *exec_ctx, internal_request *req,
 static void finish(grpc_exec_ctx *exec_ctx, internal_request *req,
                    int success) {
                    int success) {
-  grpc_pollset_set_del_pollset(exec_ctx, req->context->pollset_set,
-                               req->pollset);
+  grpc_polling_entity_del_from_pollset_set(exec_ctx, req->pollent,
+                                           req->context->pollset_set);
   req->on_response(exec_ctx, req->user_data,
   req->on_response(exec_ctx, req->user_data,
                    success ? &req->parser.http.response : NULL);
                    success ? &req->parser.http.response : NULL);
   grpc_http_parser_destroy(&req->parser);
   grpc_http_parser_destroy(&req->parser);
@@ -222,7 +222,7 @@ static void on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
 
 
 static void internal_request_begin(
 static void internal_request_begin(
     grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
     grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
-    grpc_pollset *pollset, const grpc_httpcli_request *request,
+    grpc_polling_entity *pollent, const grpc_httpcli_request *request,
     gpr_timespec deadline, grpc_httpcli_response_cb on_response,
     gpr_timespec deadline, grpc_httpcli_response_cb on_response,
     void *user_data, const char *name, gpr_slice request_text) {
     void *user_data, const char *name, gpr_slice request_text) {
   internal_request *req = gpr_malloc(sizeof(internal_request));
   internal_request *req = gpr_malloc(sizeof(internal_request));
@@ -235,7 +235,7 @@ static void internal_request_begin(
   req->handshaker =
   req->handshaker =
       request->handshaker ? request->handshaker : &grpc_httpcli_plaintext;
       request->handshaker ? request->handshaker : &grpc_httpcli_plaintext;
   req->context = context;
   req->context = context;
-  req->pollset = pollset;
+  req->pollent = pollent;
   grpc_closure_init(&req->on_read, on_read, req);
   grpc_closure_init(&req->on_read, on_read, req);
   grpc_closure_init(&req->done_write, done_write, req);
   grpc_closure_init(&req->done_write, done_write, req);
   gpr_slice_buffer_init(&req->incoming);
   gpr_slice_buffer_init(&req->incoming);
@@ -244,14 +244,15 @@ static void internal_request_begin(
   req->host = gpr_strdup(request->host);
   req->host = gpr_strdup(request->host);
   req->ssl_host_override = gpr_strdup(request->ssl_host_override);
   req->ssl_host_override = gpr_strdup(request->ssl_host_override);
 
 
-  grpc_pollset_set_add_pollset(exec_ctx, req->context->pollset_set,
-                               req->pollset);
+  GPR_ASSERT(pollent);
+  grpc_polling_entity_add_to_pollset_set(exec_ctx, req->pollent,
+                                         req->context->pollset_set);
   grpc_resolve_address(exec_ctx, request->host, req->handshaker->default_port,
   grpc_resolve_address(exec_ctx, request->host, req->handshaker->default_port,
                        on_resolved, req);
                        on_resolved, req);
 }
 }
 
 
 void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
 void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
-                      grpc_pollset *pollset,
+                      grpc_polling_entity *pollent,
                       const grpc_httpcli_request *request,
                       const grpc_httpcli_request *request,
                       gpr_timespec deadline,
                       gpr_timespec deadline,
                       grpc_httpcli_response_cb on_response, void *user_data) {
                       grpc_httpcli_response_cb on_response, void *user_data) {
@@ -261,14 +262,14 @@ void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
     return;
     return;
   }
   }
   gpr_asprintf(&name, "HTTP:GET:%s:%s", request->host, request->http.path);
   gpr_asprintf(&name, "HTTP:GET:%s:%s", request->host, request->http.path);
-  internal_request_begin(exec_ctx, context, pollset, request, deadline,
+  internal_request_begin(exec_ctx, context, pollent, request, deadline,
                          on_response, user_data, name,
                          on_response, user_data, name,
                          grpc_httpcli_format_get_request(request));
                          grpc_httpcli_format_get_request(request));
   gpr_free(name);
   gpr_free(name);
 }
 }
 
 
 void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
 void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
-                       grpc_pollset *pollset,
+                       grpc_polling_entity *pollent,
                        const grpc_httpcli_request *request,
                        const grpc_httpcli_request *request,
                        const char *body_bytes, size_t body_size,
                        const char *body_bytes, size_t body_size,
                        gpr_timespec deadline,
                        gpr_timespec deadline,
@@ -281,7 +282,7 @@ void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
   }
   }
   gpr_asprintf(&name, "HTTP:POST:%s:%s", request->host, request->http.path);
   gpr_asprintf(&name, "HTTP:POST:%s:%s", request->host, request->http.path);
   internal_request_begin(
   internal_request_begin(
-      exec_ctx, context, pollset, request, deadline, on_response, user_data,
+      exec_ctx, context, pollent, request, deadline, on_response, user_data,
       name, grpc_httpcli_format_post_request(request, body_bytes, body_size));
       name, grpc_httpcli_format_post_request(request, body_bytes, body_size));
   gpr_free(name);
   gpr_free(name);
 }
 }

+ 3 - 2
src/core/lib/http/httpcli.h

@@ -41,6 +41,7 @@
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/iomgr_internal.h"
 #include "src/core/lib/iomgr/iomgr_internal.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/iomgr/pollset_set.h"
 #include "src/core/lib/iomgr/pollset_set.h"
 
 
 /* User agent this library reports */
 /* User agent this library reports */
@@ -100,7 +101,7 @@ void grpc_httpcli_context_destroy(grpc_httpcli_context *context);
    'on_response' is a callback to report results to (and 'user_data' is a user
    'on_response' is a callback to report results to (and 'user_data' is a user
      supplied pointer to pass to said call) */
      supplied pointer to pass to said call) */
 void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
 void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
-                      grpc_pollset *pollset,
+                      grpc_polling_entity *pollent,
                       const grpc_httpcli_request *request,
                       const grpc_httpcli_request *request,
                       gpr_timespec deadline,
                       gpr_timespec deadline,
                       grpc_httpcli_response_cb on_response, void *user_data);
                       grpc_httpcli_response_cb on_response, void *user_data);
@@ -121,7 +122,7 @@ void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
      supplied pointer to pass to said call)
      supplied pointer to pass to said call)
    Does not support ?var1=val1&var2=val2 in the path. */
    Does not support ?var1=val1&var2=val2 in the path. */
 void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
 void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
-                       grpc_pollset *pollset,
+                       grpc_polling_entity *pollent,
                        const grpc_httpcli_request *request,
                        const grpc_httpcli_request *request,
                        const char *body_bytes, size_t body_size,
                        const char *body_bytes, size_t body_size,
                        gpr_timespec deadline,
                        gpr_timespec deadline,

+ 104 - 0
src/core/lib/iomgr/polling_entity.c

@@ -0,0 +1,104 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/iomgr/polling_entity.h"
+
+grpc_polling_entity grpc_polling_entity_create_from_pollset_set(
+    grpc_pollset_set *pollset_set) {
+  grpc_polling_entity pollent;
+  pollent.pollent.pollset_set = pollset_set;
+  pollent.tag = POPS_POLLSET_SET;
+  return pollent;
+}
+
+grpc_polling_entity grpc_polling_entity_create_from_pollset(
+    grpc_pollset *pollset) {
+  grpc_polling_entity pollent;
+  pollent.pollent.pollset = pollset;
+  pollent.tag = POPS_POLLSET;
+  return pollent;
+}
+
+grpc_pollset *grpc_polling_entity_pollset(grpc_polling_entity *pollent) {
+  if (pollent->tag == POPS_POLLSET) {
+    return pollent->pollent.pollset;
+  }
+  return NULL;
+}
+
+grpc_pollset_set *grpc_polling_entity_pollset_set(
+    grpc_polling_entity *pollent) {
+  if (pollent->tag == POPS_POLLSET_SET) {
+    return pollent->pollent.pollset_set;
+  }
+  return NULL;
+}
+
+bool grpc_polling_entity_is_empty(const grpc_polling_entity *pollent) {
+  return pollent->tag == POPS_NONE;
+}
+
+void grpc_polling_entity_add_to_pollset_set(grpc_exec_ctx *exec_ctx,
+                                            grpc_polling_entity *pollent,
+                                            grpc_pollset_set *pss_dst) {
+  if (pollent->tag == POPS_POLLSET) {
+    GPR_ASSERT(pollent->pollent.pollset != NULL);
+    grpc_pollset_set_add_pollset(exec_ctx, pss_dst, pollent->pollent.pollset);
+  } else if (pollent->tag == POPS_POLLSET_SET) {
+    GPR_ASSERT(pollent->pollent.pollset_set != NULL);
+    grpc_pollset_set_add_pollset_set(exec_ctx, pss_dst,
+                                     pollent->pollent.pollset_set);
+  } else {
+    gpr_log(GPR_ERROR, "Invalid grpc_polling_entity tag '%d'", pollent->tag);
+    abort();
+  }
+}
+
+void grpc_polling_entity_del_from_pollset_set(grpc_exec_ctx *exec_ctx,
+                                              grpc_polling_entity *pollent,
+                                              grpc_pollset_set *pss_dst) {
+  if (pollent->tag == POPS_POLLSET) {
+    GPR_ASSERT(pollent->pollent.pollset != NULL);
+    grpc_pollset_set_del_pollset(exec_ctx, pss_dst, pollent->pollent.pollset);
+  } else if (pollent->tag == POPS_POLLSET_SET) {
+    GPR_ASSERT(pollent->pollent.pollset_set != NULL);
+    grpc_pollset_set_del_pollset_set(exec_ctx, pss_dst,
+                                     pollent->pollent.pollset_set);
+  } else {
+    gpr_log(GPR_ERROR, "Invalid grpc_polling_entity tag '%d'", pollent->tag);
+    abort();
+  }
+}

+ 81 - 0
src/core/lib/iomgr/polling_entity.h

@@ -0,0 +1,81 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_IOMGR_POLLING_ENTITY_H
+#define GRPC_CORE_LIB_IOMGR_POLLING_ENTITY_H
+
+#include "src/core/lib/iomgr/pollset.h"
+#include "src/core/lib/iomgr/pollset_set.h"
+
+/* A grpc_polling_entity is a pollset-or-pollset_set container. It allows
+ * functions that
+ * accept a pollset XOR a pollset_set to do so through an abstract interface.
+ * No ownership is taken. */
+
+typedef struct grpc_polling_entity {
+  union {
+    grpc_pollset *pollset;
+    grpc_pollset_set *pollset_set;
+  } pollent;
+  enum pops_tag { POPS_NONE, POPS_POLLSET, POPS_POLLSET_SET } tag;
+} grpc_polling_entity;
+
+grpc_polling_entity grpc_polling_entity_create_from_pollset_set(
+    grpc_pollset_set *pollset_set);
+grpc_polling_entity grpc_polling_entity_create_from_pollset(
+    grpc_pollset *pollset);
+
+/** If \a pollent contains a pollset, return it. Otherwise, return NULL */
+grpc_pollset *grpc_polling_entity_pollset(grpc_polling_entity *pollent);
+
+/** If \a pollent contains a pollset_set, return it. Otherwise, return NULL */
+grpc_pollset_set *grpc_polling_entity_pollset_set(grpc_polling_entity *pollent);
+
+bool grpc_polling_entity_is_empty(const grpc_polling_entity *pollent);
+
+/** Add the pollset or pollset_set in \a pollent to the destination pollset_set
+ * \a
+ * pss_dst */
+void grpc_polling_entity_add_to_pollset_set(grpc_exec_ctx *exec_ctx,
+                                            grpc_polling_entity *pollent,
+                                            grpc_pollset_set *pss_dst);
+
+/** Delete the pollset or pollset_set in \a pollent from the destination
+ * pollset_set \a
+ * pss_dst */
+void grpc_polling_entity_del_from_pollset_set(grpc_exec_ctx *exec_ctx,
+                                              grpc_polling_entity *pollent,
+                                              grpc_pollset_set *pss_dst);
+/* pollset_set specific */
+
+#endif /* GRPC_CORE_LIB_IOMGR_POLLING_ENTITY_H */

+ 4 - 1
src/core/lib/iomgr/pollset_set_windows.c

@@ -32,12 +32,15 @@
  */
  */
 
 
 #include <grpc/support/port_platform.h>
 #include <grpc/support/port_platform.h>
+#include <stdint.h>
 
 
 #ifdef GPR_WINSOCK_SOCKET
 #ifdef GPR_WINSOCK_SOCKET
 
 
 #include "src/core/lib/iomgr/pollset_set_windows.h"
 #include "src/core/lib/iomgr/pollset_set_windows.h"
 
 
-grpc_pollset_set* grpc_pollset_set_create(void) { return NULL; }
+grpc_pollset_set* grpc_pollset_set_create(void) {
+  return (grpc_pollset_set*)((intptr_t)0xdeafbeef);
+}
 
 
 void grpc_pollset_set_destroy(grpc_pollset_set* pollset_set) {}
 void grpc_pollset_set_destroy(grpc_pollset_set* pollset_set) {}
 
 

+ 2 - 1
src/core/lib/iomgr/timer.c

@@ -278,7 +278,8 @@ static int refill_queue(shard_type *shard, gpr_timespec now) {
   return !grpc_timer_heap_is_empty(&shard->heap);
   return !grpc_timer_heap_is_empty(&shard->heap);
 }
 }
 
 
-/* This pops the next non-cancelled timer with deadline <= now from the queue,
+/* This pollent the next non-cancelled timer with deadline <= now from the
+   queue,
    or returns NULL if there isn't one.
    or returns NULL if there isn't one.
    REQUIRES: shard->mu locked */
    REQUIRES: shard->mu locked */
 static grpc_timer *pop_one(shard_type *shard, gpr_timespec now) {
 static grpc_timer *pop_one(shard_type *shard, gpr_timespec now) {

+ 7 - 6
src/core/lib/security/credentials/composite/composite_credentials.c

@@ -1,6 +1,6 @@
 /*
 /*
  *
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  * All rights reserved.
  *
  *
  * Redistribution and use in source and binary forms, with or without
  * Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,7 @@
 
 
 #include <string.h>
 #include <string.h>
 
 
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/api_trace.h"
 
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/alloc.h>
@@ -49,7 +50,7 @@ typedef struct {
   grpc_credentials_md_store *md_elems;
   grpc_credentials_md_store *md_elems;
   grpc_auth_metadata_context auth_md_context;
   grpc_auth_metadata_context auth_md_context;
   void *user_data;
   void *user_data;
-  grpc_pollset *pollset;
+  grpc_polling_entity *pollent;
   grpc_credentials_metadata_cb cb;
   grpc_credentials_metadata_cb cb;
 } grpc_composite_call_credentials_metadata_context;
 } grpc_composite_call_credentials_metadata_context;
 
 
@@ -93,7 +94,7 @@ static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data,
     grpc_call_credentials *inner_creds =
     grpc_call_credentials *inner_creds =
         ctx->composite_creds->inner.creds_array[ctx->creds_index++];
         ctx->composite_creds->inner.creds_array[ctx->creds_index++];
     grpc_call_credentials_get_request_metadata(
     grpc_call_credentials_get_request_metadata(
-        exec_ctx, inner_creds, ctx->pollset, ctx->auth_md_context,
+        exec_ctx, inner_creds, ctx->pollent, ctx->auth_md_context,
         composite_call_metadata_cb, ctx);
         composite_call_metadata_cb, ctx);
     return;
     return;
   }
   }
@@ -106,7 +107,7 @@ static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data,
 
 
 static void composite_call_get_request_metadata(
 static void composite_call_get_request_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
-    grpc_pollset *pollset, grpc_auth_metadata_context auth_md_context,
+    grpc_polling_entity *pollent, grpc_auth_metadata_context auth_md_context,
     grpc_credentials_metadata_cb cb, void *user_data) {
     grpc_credentials_metadata_cb cb, void *user_data) {
   grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds;
   grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds;
   grpc_composite_call_credentials_metadata_context *ctx;
   grpc_composite_call_credentials_metadata_context *ctx;
@@ -117,10 +118,10 @@ static void composite_call_get_request_metadata(
   ctx->user_data = user_data;
   ctx->user_data = user_data;
   ctx->cb = cb;
   ctx->cb = cb;
   ctx->composite_creds = c;
   ctx->composite_creds = c;
-  ctx->pollset = pollset;
+  ctx->pollent = pollent;
   ctx->md_elems = grpc_credentials_md_store_create(c->inner.num_creds);
   ctx->md_elems = grpc_credentials_md_store_create(c->inner.num_creds);
   grpc_call_credentials_get_request_metadata(
   grpc_call_credentials_get_request_metadata(
-      exec_ctx, c->inner.creds_array[ctx->creds_index++], pollset,
+      exec_ctx, c->inner.creds_array[ctx->creds_index++], ctx->pollent,
       auth_md_context, composite_call_metadata_cb, ctx);
       auth_md_context, composite_call_metadata_cb, ctx);
 }
 }
 
 

+ 2 - 2
src/core/lib/security/credentials/credentials.c

@@ -111,7 +111,7 @@ void grpc_call_credentials_release(grpc_call_credentials *creds) {
 
 
 void grpc_call_credentials_get_request_metadata(
 void grpc_call_credentials_get_request_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
-    grpc_pollset *pollset, grpc_auth_metadata_context context,
+    grpc_polling_entity *pollent, grpc_auth_metadata_context context,
     grpc_credentials_metadata_cb cb, void *user_data) {
     grpc_credentials_metadata_cb cb, void *user_data) {
   if (creds == NULL || creds->vtable->get_request_metadata == NULL) {
   if (creds == NULL || creds->vtable->get_request_metadata == NULL) {
     if (cb != NULL) {
     if (cb != NULL) {
@@ -119,7 +119,7 @@ void grpc_call_credentials_get_request_metadata(
     }
     }
     return;
     return;
   }
   }
-  creds->vtable->get_request_metadata(exec_ctx, creds, pollset, context, cb,
+  creds->vtable->get_request_metadata(exec_ctx, creds, pollent, context, cb,
                                       user_data);
                                       user_data);
 }
 }
 
 

+ 4 - 2
src/core/lib/security/credentials/credentials.h

@@ -41,6 +41,7 @@
 
 
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/http/parser.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/security/transport/security_connector.h"
 #include "src/core/lib/security/transport/security_connector.h"
 
 
 struct grpc_http_response;
 struct grpc_http_response;
@@ -164,7 +165,8 @@ typedef void (*grpc_credentials_metadata_cb)(grpc_exec_ctx *exec_ctx,
 typedef struct {
 typedef struct {
   void (*destruct)(grpc_call_credentials *c);
   void (*destruct)(grpc_call_credentials *c);
   void (*get_request_metadata)(grpc_exec_ctx *exec_ctx,
   void (*get_request_metadata)(grpc_exec_ctx *exec_ctx,
-                               grpc_call_credentials *c, grpc_pollset *pollset,
+                               grpc_call_credentials *c,
+                               grpc_polling_entity *pollent,
                                grpc_auth_metadata_context context,
                                grpc_auth_metadata_context context,
                                grpc_credentials_metadata_cb cb,
                                grpc_credentials_metadata_cb cb,
                                void *user_data);
                                void *user_data);
@@ -180,7 +182,7 @@ grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds);
 void grpc_call_credentials_unref(grpc_call_credentials *creds);
 void grpc_call_credentials_unref(grpc_call_credentials *creds);
 void grpc_call_credentials_get_request_metadata(
 void grpc_call_credentials_get_request_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
-    grpc_pollset *pollset, grpc_auth_metadata_context context,
+    grpc_polling_entity *pollent, grpc_auth_metadata_context context,
     grpc_credentials_metadata_cb cb, void *user_data);
     grpc_credentials_metadata_cb cb, void *user_data);
 
 
 /* Metadata-only credentials with the specified key and value where
 /* Metadata-only credentials with the specified key and value where

+ 1 - 1
src/core/lib/security/credentials/fake/fake_credentials.c

@@ -106,7 +106,7 @@ static void on_simulated_token_fetch_done(grpc_exec_ctx *exec_ctx,
 
 
 static void md_only_test_get_request_metadata(
 static void md_only_test_get_request_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
-    grpc_pollset *pollset, grpc_auth_metadata_context context,
+    grpc_polling_entity *pollent, grpc_auth_metadata_context context,
     grpc_credentials_metadata_cb cb, void *user_data) {
     grpc_credentials_metadata_cb cb, void *user_data) {
   grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;
   grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;
 
 

+ 15 - 10
src/core/lib/security/credentials/google_default/google_default_credentials.c

@@ -41,6 +41,7 @@
 
 
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/http/parser.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
 #include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
 #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
 #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
 #include "src/core/lib/support/env.h"
 #include "src/core/lib/support/env.h"
@@ -62,7 +63,7 @@ static gpr_once g_once = GPR_ONCE_INIT;
 static void init_default_credentials(void) { gpr_mu_init(&g_state_mu); }
 static void init_default_credentials(void) { gpr_mu_init(&g_state_mu); }
 
 
 typedef struct {
 typedef struct {
-  grpc_pollset *pollset;
+  grpc_polling_entity pollent;
   int is_done;
   int is_done;
   int success;
   int success;
 } compute_engine_detector;
 } compute_engine_detector;
@@ -86,7 +87,7 @@ static void on_compute_engine_detection_http_response(
   }
   }
   gpr_mu_lock(g_polling_mu);
   gpr_mu_lock(g_polling_mu);
   detector->is_done = 1;
   detector->is_done = 1;
-  grpc_pollset_kick(detector->pollset, NULL);
+  grpc_pollset_kick(grpc_polling_entity_pollset(&detector->pollent), NULL);
   gpr_mu_unlock(g_polling_mu);
   gpr_mu_unlock(g_polling_mu);
 }
 }
 
 
@@ -105,8 +106,9 @@ static int is_stack_running_on_compute_engine(void) {
      on compute engine. */
      on compute engine. */
   gpr_timespec max_detection_delay = gpr_time_from_seconds(1, GPR_TIMESPAN);
   gpr_timespec max_detection_delay = gpr_time_from_seconds(1, GPR_TIMESPAN);
 
 
-  detector.pollset = gpr_malloc(grpc_pollset_size());
-  grpc_pollset_init(detector.pollset, &g_polling_mu);
+  grpc_pollset *pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(pollset, &g_polling_mu);
+  detector.pollent = grpc_polling_entity_create_from_pollset(pollset);
   detector.is_done = 0;
   detector.is_done = 0;
   detector.success = 0;
   detector.success = 0;
 
 
@@ -117,7 +119,7 @@ static int is_stack_running_on_compute_engine(void) {
   grpc_httpcli_context_init(&context);
   grpc_httpcli_context_init(&context);
 
 
   grpc_httpcli_get(
   grpc_httpcli_get(
-      &exec_ctx, &context, detector.pollset, &request,
+      &exec_ctx, &context, &detector.pollent, &request,
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), max_detection_delay),
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), max_detection_delay),
       on_compute_engine_detection_http_response, &detector);
       on_compute_engine_detection_http_response, &detector);
 
 
@@ -128,19 +130,22 @@ static int is_stack_running_on_compute_engine(void) {
   gpr_mu_lock(g_polling_mu);
   gpr_mu_lock(g_polling_mu);
   while (!detector.is_done) {
   while (!detector.is_done) {
     grpc_pollset_worker *worker = NULL;
     grpc_pollset_worker *worker = NULL;
-    grpc_pollset_work(&exec_ctx, detector.pollset, &worker,
-                      gpr_now(GPR_CLOCK_MONOTONIC),
+    grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&detector.pollent),
+                      &worker, gpr_now(GPR_CLOCK_MONOTONIC),
                       gpr_inf_future(GPR_CLOCK_MONOTONIC));
                       gpr_inf_future(GPR_CLOCK_MONOTONIC));
   }
   }
   gpr_mu_unlock(g_polling_mu);
   gpr_mu_unlock(g_polling_mu);
 
 
   grpc_httpcli_context_destroy(&context);
   grpc_httpcli_context_destroy(&context);
-  grpc_closure_init(&destroy_closure, destroy_pollset, detector.pollset);
-  grpc_pollset_shutdown(&exec_ctx, detector.pollset, &destroy_closure);
+  grpc_closure_init(&destroy_closure, destroy_pollset,
+                    grpc_polling_entity_pollset(&detector.pollent));
+  grpc_pollset_shutdown(&exec_ctx,
+                        grpc_polling_entity_pollset(&detector.pollent),
+                        &destroy_closure);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_exec_ctx_finish(&exec_ctx);
   g_polling_mu = NULL;
   g_polling_mu = NULL;
 
 
-  gpr_free(detector.pollset);
+  gpr_free(grpc_polling_entity_pollset(&detector.pollent));
 
 
   return detector.success;
   return detector.success;
 }
 }

+ 1 - 1
src/core/lib/security/credentials/iam/iam_credentials.c

@@ -49,7 +49,7 @@ static void iam_destruct(grpc_call_credentials *creds) {
 
 
 static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx,
 static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx,
                                      grpc_call_credentials *creds,
                                      grpc_call_credentials *creds,
-                                     grpc_pollset *pollset,
+                                     grpc_polling_entity *pollent,
                                      grpc_auth_metadata_context context,
                                      grpc_auth_metadata_context context,
                                      grpc_credentials_metadata_cb cb,
                                      grpc_credentials_metadata_cb cb,
                                      void *user_data) {
                                      void *user_data) {

+ 1 - 1
src/core/lib/security/credentials/jwt/jwt_credentials.c

@@ -64,7 +64,7 @@ static void jwt_destruct(grpc_call_credentials *creds) {
 
 
 static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
 static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
                                      grpc_call_credentials *creds,
                                      grpc_call_credentials *creds,
-                                     grpc_pollset *pollset,
+                                     grpc_polling_entity *pollent,
                                      grpc_auth_metadata_context context,
                                      grpc_auth_metadata_context context,
                                      grpc_credentials_metadata_cb cb,
                                      grpc_credentials_metadata_cb cb,
                                      void *user_data) {
                                      void *user_data) {

+ 7 - 4
src/core/lib/security/credentials/jwt/jwt_verifier.c

@@ -37,6 +37,7 @@
 #include <string.h>
 #include <string.h>
 
 
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/http/httpcli.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/security/util/b64.h"
 #include "src/core/lib/security/util/b64.h"
 #include "src/core/lib/tsi/ssl_types.h"
 #include "src/core/lib/tsi/ssl_types.h"
 
 
@@ -321,7 +322,7 @@ grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims,
 
 
 typedef struct {
 typedef struct {
   grpc_jwt_verifier *verifier;
   grpc_jwt_verifier *verifier;
-  grpc_pollset *pollset;
+  grpc_polling_entity pollent;
   jose_header *header;
   jose_header *header;
   grpc_jwt_claims *claims;
   grpc_jwt_claims *claims;
   char *audience;
   char *audience;
@@ -337,10 +338,11 @@ static verifier_cb_ctx *verifier_cb_ctx_create(
     grpc_jwt_claims *claims, const char *audience, gpr_slice signature,
     grpc_jwt_claims *claims, const char *audience, gpr_slice signature,
     const char *signed_jwt, size_t signed_jwt_len, void *user_data,
     const char *signed_jwt, size_t signed_jwt_len, void *user_data,
     grpc_jwt_verification_done_cb cb) {
     grpc_jwt_verification_done_cb cb) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   verifier_cb_ctx *ctx = gpr_malloc(sizeof(verifier_cb_ctx));
   verifier_cb_ctx *ctx = gpr_malloc(sizeof(verifier_cb_ctx));
   memset(ctx, 0, sizeof(verifier_cb_ctx));
   memset(ctx, 0, sizeof(verifier_cb_ctx));
   ctx->verifier = verifier;
   ctx->verifier = verifier;
-  ctx->pollset = pollset;
+  ctx->pollent = grpc_polling_entity_create_from_pollset(pollset);
   ctx->header = header;
   ctx->header = header;
   ctx->audience = gpr_strdup(audience);
   ctx->audience = gpr_strdup(audience);
   ctx->claims = claims;
   ctx->claims = claims;
@@ -348,6 +350,7 @@ static verifier_cb_ctx *verifier_cb_ctx_create(
   ctx->signed_data = gpr_slice_from_copied_buffer(signed_jwt, signed_jwt_len);
   ctx->signed_data = gpr_slice_from_copied_buffer(signed_jwt, signed_jwt_len);
   ctx->user_data = user_data;
   ctx->user_data = user_data;
   ctx->user_cb = cb;
   ctx->user_cb = cb;
+  grpc_exec_ctx_finish(&exec_ctx);
   return ctx;
   return ctx;
 }
 }
 
 
@@ -642,7 +645,7 @@ static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
     *(req.host + (req.http.path - jwks_uri)) = '\0';
     *(req.host + (req.http.path - jwks_uri)) = '\0';
   }
   }
   grpc_httpcli_get(
   grpc_httpcli_get(
-      exec_ctx, &ctx->verifier->http_ctx, ctx->pollset, &req,
+      exec_ctx, &ctx->verifier->http_ctx, &ctx->pollent, &req,
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
       on_keys_retrieved, ctx);
       on_keys_retrieved, ctx);
   grpc_json_destroy(json);
   grpc_json_destroy(json);
@@ -745,7 +748,7 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx,
   }
   }
 
 
   grpc_httpcli_get(
   grpc_httpcli_get(
-      exec_ctx, &ctx->verifier->http_ctx, ctx->pollset, &req,
+      exec_ctx, &ctx->verifier->http_ctx, &ctx->pollent, &req,
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
       http_cb, ctx);
       http_cb, ctx);
   gpr_free(req.host);
   gpr_free(req.host);

+ 7 - 7
src/core/lib/security/credentials/oauth2/oauth2_credentials.c

@@ -244,7 +244,7 @@ static void on_oauth2_token_fetcher_http_response(
 
 
 static void oauth2_token_fetcher_get_request_metadata(
 static void oauth2_token_fetcher_get_request_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
-    grpc_pollset *pollset, grpc_auth_metadata_context context,
+    grpc_polling_entity *pollent, grpc_auth_metadata_context context,
     grpc_credentials_metadata_cb cb, void *user_data) {
     grpc_credentials_metadata_cb cb, void *user_data) {
   grpc_oauth2_token_fetcher_credentials *c =
   grpc_oauth2_token_fetcher_credentials *c =
       (grpc_oauth2_token_fetcher_credentials *)creds;
       (grpc_oauth2_token_fetcher_credentials *)creds;
@@ -270,7 +270,7 @@ static void oauth2_token_fetcher_get_request_metadata(
     c->fetch_func(
     c->fetch_func(
         exec_ctx,
         exec_ctx,
         grpc_credentials_metadata_request_create(creds, cb, user_data),
         grpc_credentials_metadata_request_create(creds, cb, user_data),
-        &c->httpcli_context, pollset, on_oauth2_token_fetcher_http_response,
+        &c->httpcli_context, pollent, on_oauth2_token_fetcher_http_response,
         gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), refresh_threshold));
         gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), refresh_threshold));
   }
   }
 }
 }
@@ -295,7 +295,7 @@ static grpc_call_credentials_vtable compute_engine_vtable = {
 
 
 static void compute_engine_fetch_oauth2(
 static void compute_engine_fetch_oauth2(
     grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
     grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
-    grpc_httpcli_context *httpcli_context, grpc_pollset *pollset,
+    grpc_httpcli_context *httpcli_context, grpc_polling_entity *pollent,
     grpc_httpcli_response_cb response_cb, gpr_timespec deadline) {
     grpc_httpcli_response_cb response_cb, gpr_timespec deadline) {
   grpc_http_header header = {"Metadata-Flavor", "Google"};
   grpc_http_header header = {"Metadata-Flavor", "Google"};
   grpc_httpcli_request request;
   grpc_httpcli_request request;
@@ -304,7 +304,7 @@ static void compute_engine_fetch_oauth2(
   request.http.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
   request.http.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
   request.http.hdr_count = 1;
   request.http.hdr_count = 1;
   request.http.hdrs = &header;
   request.http.hdrs = &header;
-  grpc_httpcli_get(exec_ctx, httpcli_context, pollset, &request, deadline,
+  grpc_httpcli_get(exec_ctx, httpcli_context, pollent, &request, deadline,
                    response_cb, metadata_req);
                    response_cb, metadata_req);
 }
 }
 
 
@@ -336,7 +336,7 @@ static grpc_call_credentials_vtable refresh_token_vtable = {
 
 
 static void refresh_token_fetch_oauth2(
 static void refresh_token_fetch_oauth2(
     grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
     grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
-    grpc_httpcli_context *httpcli_context, grpc_pollset *pollset,
+    grpc_httpcli_context *httpcli_context, grpc_polling_entity *pollent,
     grpc_httpcli_response_cb response_cb, gpr_timespec deadline) {
     grpc_httpcli_response_cb response_cb, gpr_timespec deadline) {
   grpc_google_refresh_token_credentials *c =
   grpc_google_refresh_token_credentials *c =
       (grpc_google_refresh_token_credentials *)metadata_req->creds;
       (grpc_google_refresh_token_credentials *)metadata_req->creds;
@@ -353,7 +353,7 @@ static void refresh_token_fetch_oauth2(
   request.http.hdr_count = 1;
   request.http.hdr_count = 1;
   request.http.hdrs = &header;
   request.http.hdrs = &header;
   request.handshaker = &grpc_httpcli_ssl;
   request.handshaker = &grpc_httpcli_ssl;
-  grpc_httpcli_post(exec_ctx, httpcli_context, pollset, &request, body,
+  grpc_httpcli_post(exec_ctx, httpcli_context, pollent, &request, body,
                     strlen(body), deadline, response_cb, metadata_req);
                     strlen(body), deadline, response_cb, metadata_req);
   gpr_free(body);
   gpr_free(body);
 }
 }
@@ -396,7 +396,7 @@ static void access_token_destruct(grpc_call_credentials *creds) {
 
 
 static void access_token_get_request_metadata(
 static void access_token_get_request_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
-    grpc_pollset *pollset, grpc_auth_metadata_context context,
+    grpc_polling_entity *pollent, grpc_auth_metadata_context context,
     grpc_credentials_metadata_cb cb, void *user_data) {
     grpc_credentials_metadata_cb cb, void *user_data) {
   grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
   grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
   cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK);
   cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK);

+ 1 - 1
src/core/lib/security/credentials/oauth2/oauth2_credentials.h

@@ -70,7 +70,7 @@ void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token);
 typedef void (*grpc_fetch_oauth2_func)(grpc_exec_ctx *exec_ctx,
 typedef void (*grpc_fetch_oauth2_func)(grpc_exec_ctx *exec_ctx,
                                        grpc_credentials_metadata_request *req,
                                        grpc_credentials_metadata_request *req,
                                        grpc_httpcli_context *http_context,
                                        grpc_httpcli_context *http_context,
-                                       grpc_pollset *pollset,
+                                       grpc_polling_entity *pollent,
                                        grpc_httpcli_response_cb response_cb,
                                        grpc_httpcli_response_cb response_cb,
                                        gpr_timespec deadline);
                                        gpr_timespec deadline);
 typedef struct {
 typedef struct {

+ 1 - 1
src/core/lib/security/credentials/plugin/plugin_credentials.c

@@ -94,7 +94,7 @@ static void plugin_md_request_metadata_ready(void *request,
 
 
 static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx,
 static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx,
                                         grpc_call_credentials *creds,
                                         grpc_call_credentials *creds,
-                                        grpc_pollset *pollset,
+                                        grpc_polling_entity *pollent,
                                         grpc_auth_metadata_context context,
                                         grpc_auth_metadata_context context,
                                         grpc_credentials_metadata_cb cb,
                                         grpc_credentials_metadata_cb cb,
                                         void *user_data) {
                                         void *user_data) {

+ 22 - 15
src/core/lib/security/transport/client_auth_filter.c

@@ -54,11 +54,11 @@ typedef struct {
   grpc_call_credentials *creds;
   grpc_call_credentials *creds;
   grpc_mdstr *host;
   grpc_mdstr *host;
   grpc_mdstr *method;
   grpc_mdstr *method;
-  /* pollset bound to this call; if we need to make external
-     network requests, they should be done under this pollset
-     so that work can progress when this call wants work to
-     progress */
-  grpc_pollset *pollset;
+  /* pollset{_set} bound to this call; if we need to make external
+     network requests, they should be done under a pollset added to this
+     pollset_set so that work can progress when this call wants work to progress
+  */
+  grpc_polling_entity *pollent;
   grpc_transport_stream_op op;
   grpc_transport_stream_op op;
   uint8_t security_context_set;
   uint8_t security_context_set;
   grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT];
   grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT];
@@ -184,9 +184,9 @@ static void send_security_metadata(grpc_exec_ctx *exec_ctx,
   build_auth_metadata_context(&chand->security_connector->base,
   build_auth_metadata_context(&chand->security_connector->base,
                               chand->auth_context, calld);
                               chand->auth_context, calld);
   calld->op = *op; /* Copy op (originates from the caller's stack). */
   calld->op = *op; /* Copy op (originates from the caller's stack). */
-  GPR_ASSERT(calld->pollset);
+  GPR_ASSERT(calld->pollent != NULL);
   grpc_call_credentials_get_request_metadata(
   grpc_call_credentials_get_request_metadata(
-      exec_ctx, calld->creds, calld->pollset, calld->auth_md_context,
+      exec_ctx, calld->creds, calld->pollent, calld->auth_md_context,
       on_credentials_metadata, elem);
       on_credentials_metadata, elem);
 }
 }
 
 
@@ -270,10 +270,11 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
   memset(calld, 0, sizeof(*calld));
   memset(calld, 0, sizeof(*calld));
 }
 }
 
 
-static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                        grpc_pollset *pollset) {
+static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
+                                       grpc_call_element *elem,
+                                       grpc_polling_entity *pollent) {
   call_data *calld = elem->call_data;
   call_data *calld = elem->call_data;
-  calld->pollset = pollset;
+  calld->pollent = pollent;
 }
 }
 
 
 /* Destructor for call_data */
 /* Destructor for call_data */
@@ -329,8 +330,14 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
   GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "client_auth_filter");
   GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "client_auth_filter");
 }
 }
 
 
-const grpc_channel_filter grpc_client_auth_filter = {
-    auth_start_transport_op, grpc_channel_next_op, sizeof(call_data),
-    init_call_elem,          set_pollset,          destroy_call_elem,
-    sizeof(channel_data),    init_channel_elem,    destroy_channel_elem,
-    grpc_call_next_get_peer, "client-auth"};
+const grpc_channel_filter grpc_client_auth_filter = {auth_start_transport_op,
+                                                     grpc_channel_next_op,
+                                                     sizeof(call_data),
+                                                     init_call_elem,
+                                                     set_pollset_or_pollset_set,
+                                                     destroy_call_elem,
+                                                     sizeof(channel_data),
+                                                     init_channel_elem,
+                                                     destroy_channel_elem,
+                                                     grpc_call_next_get_peer,
+                                                     "client-auth"};

+ 11 - 7
src/core/lib/security/transport/server_auth_filter.c

@@ -220,9 +220,6 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
       grpc_server_security_context_destroy;
       grpc_server_security_context_destroy;
 }
 }
 
 
-static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                        grpc_pollset *pollset) {}
-
 /* Destructor for call_data */
 /* Destructor for call_data */
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_stats *stats, void *ignored) {}
                               const grpc_call_stats *stats, void *ignored) {}
@@ -258,7 +255,14 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
 }
 }
 
 
 const grpc_channel_filter grpc_server_auth_filter = {
 const grpc_channel_filter grpc_server_auth_filter = {
-    auth_start_transport_op, grpc_channel_next_op, sizeof(call_data),
-    init_call_elem,          set_pollset,          destroy_call_elem,
-    sizeof(channel_data),    init_channel_elem,    destroy_channel_elem,
-    grpc_call_next_get_peer, "server-auth"};
+    auth_start_transport_op,
+    grpc_channel_next_op,
+    sizeof(call_data),
+    init_call_elem,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
+    destroy_call_elem,
+    sizeof(channel_data),
+    init_channel_elem,
+    destroy_channel_elem,
+    grpc_call_next_get_peer,
+    "server-auth"};

+ 27 - 11
src/core/lib/surface/call.c

@@ -113,6 +113,7 @@ typedef struct batch_control {
 
 
 struct grpc_call {
 struct grpc_call {
   grpc_completion_queue *cq;
   grpc_completion_queue *cq;
+  grpc_polling_entity pollent;
   grpc_channel *channel;
   grpc_channel *channel;
   grpc_call *parent;
   grpc_call *parent;
   grpc_call *first_child;
   grpc_call *first_child;
@@ -224,13 +225,11 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call_stack,
 static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
 static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
                                   bool success);
                                   bool success);
 
 
-grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call,
-                            uint32_t propagation_mask,
-                            grpc_completion_queue *cq,
-                            const void *server_transport_data,
-                            grpc_mdelem **add_initial_metadata,
-                            size_t add_initial_metadata_count,
-                            gpr_timespec send_deadline) {
+grpc_call *grpc_call_create(
+    grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
+    grpc_completion_queue *cq, grpc_pollset_set *pollset_set_alternative,
+    const void *server_transport_data, grpc_mdelem **add_initial_metadata,
+    size_t add_initial_metadata_count, gpr_timespec send_deadline) {
   size_t i, j;
   size_t i, j;
   grpc_channel_stack *channel_stack = grpc_channel_get_channel_stack(channel);
   grpc_channel_stack *channel_stack = grpc_channel_get_channel_stack(channel);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -267,9 +266,20 @@ grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call,
                        call->context, server_transport_data,
                        call->context, server_transport_data,
                        CALL_STACK_FROM_CALL(call));
                        CALL_STACK_FROM_CALL(call));
   if (cq != NULL) {
   if (cq != NULL) {
+    GPR_ASSERT(
+        pollset_set_alternative == NULL &&
+        "Only one of 'cq' and 'pollset_set_alternative' should be non-NULL.");
     GRPC_CQ_INTERNAL_REF(cq, "bind");
     GRPC_CQ_INTERNAL_REF(cq, "bind");
-    grpc_call_stack_set_pollset(&exec_ctx, CALL_STACK_FROM_CALL(call),
-                                grpc_cq_pollset(cq));
+    call->pollent =
+        grpc_polling_entity_create_from_pollset(grpc_cq_pollset(cq));
+  }
+  if (pollset_set_alternative != NULL) {
+    call->pollent =
+        grpc_polling_entity_create_from_pollset_set(pollset_set_alternative);
+  }
+  if (!grpc_polling_entity_is_empty(&call->pollent)) {
+    grpc_call_stack_set_pollset_or_pollset_set(
+        &exec_ctx, CALL_STACK_FROM_CALL(call), &call->pollent);
   }
   }
   if (parent_call != NULL) {
   if (parent_call != NULL) {
     GRPC_CALL_INTERNAL_REF(parent_call, "child");
     GRPC_CALL_INTERNAL_REF(parent_call, "child");
@@ -324,10 +334,16 @@ grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call,
 void grpc_call_set_completion_queue(grpc_exec_ctx *exec_ctx, grpc_call *call,
 void grpc_call_set_completion_queue(grpc_exec_ctx *exec_ctx, grpc_call *call,
                                     grpc_completion_queue *cq) {
                                     grpc_completion_queue *cq) {
   GPR_ASSERT(cq);
   GPR_ASSERT(cq);
+
+  if (grpc_polling_entity_pollset_set(&call->pollent) != NULL) {
+    gpr_log(GPR_ERROR, "A pollset_set is already registered for this call.");
+    abort();
+  }
   call->cq = cq;
   call->cq = cq;
   GRPC_CQ_INTERNAL_REF(cq, "bind");
   GRPC_CQ_INTERNAL_REF(cq, "bind");
-  grpc_call_stack_set_pollset(exec_ctx, CALL_STACK_FROM_CALL(call),
-                              grpc_cq_pollset(cq));
+  call->pollent = grpc_polling_entity_create_from_pollset(grpc_cq_pollset(cq));
+  grpc_call_stack_set_pollset_or_pollset_set(
+      exec_ctx, CALL_STACK_FROM_CALL(call), &call->pollent);
 }
 }
 
 
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG

+ 2 - 0
src/core/lib/surface/call.h

@@ -53,6 +53,8 @@ typedef void (*grpc_ioreq_completion_func)(grpc_exec_ctx *exec_ctx,
 grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call,
 grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call,
                             uint32_t propagation_mask,
                             uint32_t propagation_mask,
                             grpc_completion_queue *cq,
                             grpc_completion_queue *cq,
+                            /* if not NULL, it'll be used in lieu of \a cq */
+                            grpc_pollset_set *pollset_set_alternative,
                             const void *server_transport_data,
                             const void *server_transport_data,
                             grpc_mdelem **add_initial_metadata,
                             grpc_mdelem **add_initial_metadata,
                             size_t add_initial_metadata_count,
                             size_t add_initial_metadata_count,

+ 24 - 6
src/core/lib/surface/channel.c

@@ -191,12 +191,14 @@ char *grpc_channel_get_target(grpc_channel *channel) {
 
 
 static grpc_call *grpc_channel_create_call_internal(
 static grpc_call *grpc_channel_create_call_internal(
     grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
     grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
-    grpc_completion_queue *cq, grpc_mdelem *path_mdelem,
-    grpc_mdelem *authority_mdelem, gpr_timespec deadline) {
+    grpc_completion_queue *cq, grpc_pollset_set *pollset_set_alternative,
+    grpc_mdelem *path_mdelem, grpc_mdelem *authority_mdelem,
+    gpr_timespec deadline) {
   grpc_mdelem *send_metadata[2];
   grpc_mdelem *send_metadata[2];
   size_t num_metadata = 0;
   size_t num_metadata = 0;
 
 
   GPR_ASSERT(channel->is_client);
   GPR_ASSERT(channel->is_client);
+  GPR_ASSERT(!(cq != NULL && pollset_set_alternative != NULL));
 
 
   send_metadata[num_metadata++] = path_mdelem;
   send_metadata[num_metadata++] = path_mdelem;
   if (authority_mdelem != NULL) {
   if (authority_mdelem != NULL) {
@@ -205,8 +207,9 @@ static grpc_call *grpc_channel_create_call_internal(
     send_metadata[num_metadata++] = GRPC_MDELEM_REF(channel->default_authority);
     send_metadata[num_metadata++] = GRPC_MDELEM_REF(channel->default_authority);
   }
   }
 
 
-  return grpc_call_create(channel, parent_call, propagation_mask, cq, NULL,
-                          send_metadata, num_metadata, deadline);
+  return grpc_call_create(channel, parent_call, propagation_mask, cq,
+                          pollset_set_alternative, NULL, send_metadata,
+                          num_metadata, deadline);
 }
 }
 
 
 grpc_call *grpc_channel_create_call(grpc_channel *channel,
 grpc_call *grpc_channel_create_call(grpc_channel *channel,
@@ -226,7 +229,22 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
            (int)deadline.clock_type, reserved));
            (int)deadline.clock_type, reserved));
   GPR_ASSERT(!reserved);
   GPR_ASSERT(!reserved);
   return grpc_channel_create_call_internal(
   return grpc_channel_create_call_internal(
-      channel, parent_call, propagation_mask, cq,
+      channel, parent_call, propagation_mask, cq, NULL,
+      grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
+                                        grpc_mdstr_from_string(method)),
+      host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY,
+                                               grpc_mdstr_from_string(host))
+           : NULL,
+      deadline);
+}
+
+grpc_call *grpc_channel_create_pollset_set_call(
+    grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
+    grpc_pollset_set *pollset_set, const char *method, const char *host,
+    gpr_timespec deadline, void *reserved) {
+  GPR_ASSERT(!reserved);
+  return grpc_channel_create_call_internal(
+      channel, parent_call, propagation_mask, NULL, pollset_set,
       grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
       grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
                                         grpc_mdstr_from_string(method)),
                                         grpc_mdstr_from_string(method)),
       host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY,
       host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY,
@@ -270,7 +288,7 @@ grpc_call *grpc_channel_create_registered_call(
           (int)deadline.tv_nsec, (int)deadline.clock_type, reserved));
           (int)deadline.tv_nsec, (int)deadline.clock_type, reserved));
   GPR_ASSERT(!reserved);
   GPR_ASSERT(!reserved);
   return grpc_channel_create_call_internal(
   return grpc_channel_create_call_internal(
-      channel, parent_call, propagation_mask, completion_queue,
+      channel, parent_call, propagation_mask, completion_queue, NULL,
       GRPC_MDELEM_REF(rc->path),
       GRPC_MDELEM_REF(rc->path),
       rc->authority ? GRPC_MDELEM_REF(rc->authority) : NULL, deadline);
       rc->authority ? GRPC_MDELEM_REF(rc->authority) : NULL, deadline);
 }
 }

+ 5 - 0
src/core/lib/surface/channel.h

@@ -42,6 +42,11 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
                                   grpc_channel_stack_type channel_stack_type,
                                   grpc_channel_stack_type channel_stack_type,
                                   grpc_transport *optional_transport);
                                   grpc_transport *optional_transport);
 
 
+grpc_call *grpc_channel_create_pollset_set_call(
+    grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
+    grpc_pollset_set *pollset_set, const char *method, const char *host,
+    gpr_timespec deadline, void *reserved);
+
 /** Get a (borrowed) pointer to this channels underlying channel stack */
 /** Get a (borrowed) pointer to this channels underlying channel stack */
 grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel);
 grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel);
 
 

+ 1 - 1
src/core/lib/surface/lame_client.c

@@ -128,7 +128,7 @@ const grpc_channel_filter grpc_lame_filter = {
     lame_start_transport_op,
     lame_start_transport_op,
     sizeof(call_data),
     sizeof(call_data),
     init_call_elem,
     init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     destroy_call_elem,
     destroy_call_elem,
     sizeof(channel_data),
     sizeof(channel_data),
     init_channel_elem,
     init_channel_elem,

+ 4 - 4
src/core/lib/surface/server.c

@@ -793,9 +793,9 @@ static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd,
                           const void *transport_server_data) {
                           const void *transport_server_data) {
   channel_data *chand = cd;
   channel_data *chand = cd;
   /* create a call */
   /* create a call */
-  grpc_call *call =
-      grpc_call_create(chand->channel, NULL, 0, NULL, transport_server_data,
-                       NULL, 0, gpr_inf_future(GPR_CLOCK_MONOTONIC));
+  grpc_call *call = grpc_call_create(chand->channel, NULL, 0, NULL, NULL,
+                                     transport_server_data, NULL, 0,
+                                     gpr_inf_future(GPR_CLOCK_MONOTONIC));
   grpc_call_element *elem =
   grpc_call_element *elem =
       grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
       grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
   call_data *calld = elem->call_data;
   call_data *calld = elem->call_data;
@@ -910,7 +910,7 @@ const grpc_channel_filter grpc_server_top_filter = {
     grpc_channel_next_op,
     grpc_channel_next_op,
     sizeof(call_data),
     sizeof(call_data),
     init_call_elem,
     init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     destroy_call_elem,
     destroy_call_elem,
     sizeof(channel_data),
     sizeof(channel_data),
     init_channel_elem,
     init_channel_elem,

+ 13 - 4
src/core/lib/transport/transport.c

@@ -125,10 +125,19 @@ void grpc_transport_perform_op(grpc_exec_ctx *exec_ctx,
   transport->vtable->perform_op(exec_ctx, transport, op);
   transport->vtable->perform_op(exec_ctx, transport, op);
 }
 }
 
 
-void grpc_transport_set_pollset(grpc_exec_ctx *exec_ctx,
-                                grpc_transport *transport, grpc_stream *stream,
-                                grpc_pollset *pollset) {
-  transport->vtable->set_pollset(exec_ctx, transport, stream, pollset);
+void grpc_transport_set_pops(grpc_exec_ctx *exec_ctx, grpc_transport *transport,
+                             grpc_stream *stream,
+                             grpc_polling_entity *pollent) {
+  grpc_pollset *pollset;
+  grpc_pollset_set *pollset_set;
+  if ((pollset = grpc_polling_entity_pollset(pollent)) != NULL) {
+    transport->vtable->set_pollset(exec_ctx, transport, stream, pollset);
+  } else if ((pollset_set = grpc_polling_entity_pollset_set(pollent)) != NULL) {
+    transport->vtable->set_pollset_set(exec_ctx, transport, stream,
+                                       pollset_set);
+  } else {
+    abort();
+  }
 }
 }
 
 
 void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx,
 void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx,

+ 3 - 3
src/core/lib/transport/transport.h

@@ -37,6 +37,7 @@
 #include <stddef.h>
 #include <stddef.h>
 
 
 #include "src/core/lib/channel/context.h"
 #include "src/core/lib/channel/context.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/iomgr/pollset.h"
 #include "src/core/lib/iomgr/pollset.h"
 #include "src/core/lib/iomgr/pollset_set.h"
 #include "src/core/lib/iomgr/pollset_set.h"
 #include "src/core/lib/transport/byte_stream.h"
 #include "src/core/lib/transport/byte_stream.h"
@@ -197,9 +198,8 @@ int grpc_transport_init_stream(grpc_exec_ctx *exec_ctx,
                                grpc_stream_refcount *refcount,
                                grpc_stream_refcount *refcount,
                                const void *server_data);
                                const void *server_data);
 
 
-void grpc_transport_set_pollset(grpc_exec_ctx *exec_ctx,
-                                grpc_transport *transport, grpc_stream *stream,
-                                grpc_pollset *pollset);
+void grpc_transport_set_pops(grpc_exec_ctx *exec_ctx, grpc_transport *transport,
+                             grpc_stream *stream, grpc_polling_entity *pollent);
 
 
 /* Destroy transport data for a stream.
 /* Destroy transport data for a stream.
 
 

+ 4 - 0
src/core/lib/transport/transport_impl.h

@@ -53,6 +53,10 @@ typedef struct grpc_transport_vtable {
   void (*set_pollset)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
   void (*set_pollset)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
                       grpc_stream *stream, grpc_pollset *pollset);
                       grpc_stream *stream, grpc_pollset *pollset);
 
 
+  /* implementation of grpc_transport_set_pollset */
+  void (*set_pollset_set)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
+                          grpc_stream *stream, grpc_pollset_set *pollset_set);
+
   /* implementation of grpc_transport_perform_stream_op */
   /* implementation of grpc_transport_perform_stream_op */
   void (*perform_stream_op)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
   void (*perform_stream_op)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
                             grpc_stream *stream, grpc_transport_stream_op *op);
                             grpc_stream *stream, grpc_transport_stream_op *op);

+ 12 - 5
include/grpc++/impl/proto_utils.h → src/core/plugin_registry/grpc_cronet_plugin_registry.c

@@ -1,6 +1,6 @@
 /*
 /*
  *
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
  * All rights reserved.
  * All rights reserved.
  *
  *
  * Redistribution and use in source and binary forms, with or without
  * Redistribution and use in source and binary forms, with or without
@@ -31,9 +31,16 @@
  *
  *
  */
  */
 
 
-#ifndef GRPCXX_IMPL_PROTO_UTILS_H
-#define GRPCXX_IMPL_PROTO_UTILS_H
+#include <grpc/grpc.h>
 
 
-#include <grpc++/impl/codegen/proto_utils.h>
+extern void grpc_chttp2_plugin_init(void);
+extern void grpc_chttp2_plugin_shutdown(void);
+extern void grpc_client_config_init(void);
+extern void grpc_client_config_shutdown(void);
 
 
-#endif  // GRPCXX_IMPL_PROTO_UTILS_H
+void grpc_register_built_in_plugins(void) {
+  grpc_register_plugin(grpc_chttp2_plugin_init,
+                       grpc_chttp2_plugin_shutdown);
+  grpc_register_plugin(grpc_client_config_init,
+                       grpc_client_config_shutdown);
+}

+ 90 - 0
src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs

@@ -0,0 +1,90 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.Core.Tests
+{
+    public class AppDomainUnloadTest
+    {
+        [Test]
+        public void AppDomainUnloadHookCanCleanupAbandonedCall()
+        {
+            var setup = new AppDomainSetup
+            {
+                ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
+            };
+            var childDomain = AppDomain.CreateDomain("test", null, setup);
+            var remoteObj = childDomain.CreateInstance(typeof(AppDomainTestClass).Assembly.GetName().Name, typeof(AppDomainTestClass).FullName);
+
+            // Try to unload the appdomain once we've created a server and a channel inside the appdomain.
+            AppDomain.Unload(childDomain);
+        }
+
+        public class AppDomainTestClass
+        {
+            const string Host = "127.0.0.1";
+
+            /// <summary>
+            /// Creates a server and a channel and initiates a call. The code is invoked from inside of an AppDomain
+            /// to test if AppDomain.Unload() work if Grpc is being used.
+            /// </summary>
+            public AppDomainTestClass()
+            {
+                var helper = new MockServiceHelper(Host);
+                var server = helper.GetServer();
+                server.Start();
+                var channel = helper.GetChannel();
+
+                var readyToShutdown = new TaskCompletionSource<object>();
+                helper.DuplexStreamingHandler = new DuplexStreamingServerMethod<string, string>(async (requestStream, responseStream, context) =>
+                {
+                    readyToShutdown.SetResult(null);
+                    await requestStream.ToListAsync();
+                });
+
+                var call = Calls.AsyncDuplexStreamingCall(helper.CreateDuplexStreamingCall());
+                readyToShutdown.Task.Wait();  // make sure handler is running
+            }
+        }
+    }
+}

+ 3 - 3
src/csharp/Grpc.Core.Tests/ChannelTest.cs

@@ -71,7 +71,7 @@ namespace Grpc.Core.Tests
         public void WaitForStateChangedAsync_InvalidArgument()
         public void WaitForStateChangedAsync_InvalidArgument()
         {
         {
             var channel = new Channel("localhost", ChannelCredentials.Insecure);
             var channel = new Channel("localhost", ChannelCredentials.Insecure);
-            Assert.ThrowsAsync(typeof(ArgumentException), async () => await channel.WaitForStateChangedAsync(ChannelState.FatalFailure));
+            Assert.ThrowsAsync(typeof(ArgumentException), async () => await channel.WaitForStateChangedAsync(ChannelState.Shutdown));
             channel.ShutdownAsync().Wait();
             channel.ShutdownAsync().Wait();
         }
         }
 
 
@@ -102,11 +102,11 @@ namespace Grpc.Core.Tests
         }
         }
 
 
         [Test]
         [Test]
-        public async Task StateIsFatalFailureAfterShutdown()
+        public async Task StateIsShutdownAfterShutdown()
         {
         {
             var channel = new Channel("localhost", ChannelCredentials.Insecure);
             var channel = new Channel("localhost", ChannelCredentials.Insecure);
             await channel.ShutdownAsync();
             await channel.ShutdownAsync();
-            Assert.AreEqual(ChannelState.FatalFailure, channel.State);
+            Assert.AreEqual(ChannelState.Shutdown, channel.State);
         }
         }
 
 
         [Test]
         [Test]

+ 4 - 0
src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj

@@ -86,6 +86,10 @@
     <Compile Include="NUnitMain.cs" />
     <Compile Include="NUnitMain.cs" />
     <Compile Include="Internal\FakeNativeCall.cs" />
     <Compile Include="Internal\FakeNativeCall.cs" />
     <Compile Include="Internal\AsyncCallServerTest.cs" />
     <Compile Include="Internal\AsyncCallServerTest.cs" />
+    <Compile Include="ShutdownHookServerTest.cs" />
+    <Compile Include="ShutdownHookPendingCallTest.cs" />
+    <Compile Include="ShutdownHookClientTest.cs" />
+    <Compile Include="AppDomainUnloadTest.cs" />
   </ItemGroup>
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
   <ItemGroup>

+ 6 - 6
src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs

@@ -49,7 +49,7 @@ namespace Grpc.Core.Tests
             {
             {
                 Assert.IsNotNull(env.CompletionQueues.ElementAt(i));
                 Assert.IsNotNull(env.CompletionQueues.ElementAt(i));
             }
             }
-            GrpcEnvironment.Release();
+            GrpcEnvironment.ReleaseAsync().Wait();
         }
         }
 
 
         [Test]
         [Test]
@@ -58,8 +58,8 @@ namespace Grpc.Core.Tests
             var env1 = GrpcEnvironment.AddRef();
             var env1 = GrpcEnvironment.AddRef();
             var env2 = GrpcEnvironment.AddRef();
             var env2 = GrpcEnvironment.AddRef();
             Assert.AreSame(env1, env2);
             Assert.AreSame(env1, env2);
-            GrpcEnvironment.Release();
-            GrpcEnvironment.Release();
+            GrpcEnvironment.ReleaseAsync().Wait();
+            GrpcEnvironment.ReleaseAsync().Wait();
         }
         }
 
 
         [Test]
         [Test]
@@ -68,10 +68,10 @@ namespace Grpc.Core.Tests
             Assert.AreEqual(0, GrpcEnvironment.GetRefCount());
             Assert.AreEqual(0, GrpcEnvironment.GetRefCount());
 
 
             var env1 = GrpcEnvironment.AddRef();
             var env1 = GrpcEnvironment.AddRef();
-            GrpcEnvironment.Release();
+            GrpcEnvironment.ReleaseAsync().Wait();
 
 
             var env2 = GrpcEnvironment.AddRef();
             var env2 = GrpcEnvironment.AddRef();
-            GrpcEnvironment.Release();
+            GrpcEnvironment.ReleaseAsync().Wait();
 
 
             Assert.AreNotSame(env1, env2);
             Assert.AreNotSame(env1, env2);
         }
         }
@@ -80,7 +80,7 @@ namespace Grpc.Core.Tests
         public void ReleaseWithoutAddRef()
         public void ReleaseWithoutAddRef()
         {
         {
             Assert.AreEqual(0, GrpcEnvironment.GetRefCount());
             Assert.AreEqual(0, GrpcEnvironment.GetRefCount());
-            Assert.Throws(typeof(InvalidOperationException), () => GrpcEnvironment.Release());
+            Assert.ThrowsAsync(typeof(InvalidOperationException), async () => await GrpcEnvironment.ReleaseAsync());
         }
         }
 
 
         [Test]
         [Test]

+ 2 - 2
src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs

@@ -48,7 +48,7 @@ namespace Grpc.Core.Internal.Tests
             GrpcEnvironment.AddRef();
             GrpcEnvironment.AddRef();
             var cq = CompletionQueueSafeHandle.Create();
             var cq = CompletionQueueSafeHandle.Create();
             cq.Dispose();
             cq.Dispose();
-            GrpcEnvironment.Release();
+            GrpcEnvironment.ReleaseAsync().Wait();
         }
         }
 
 
         [Test]
         [Test]
@@ -59,7 +59,7 @@ namespace Grpc.Core.Internal.Tests
             cq.Shutdown();
             cq.Shutdown();
             var ev = cq.Next();
             var ev = cq.Next();
             cq.Dispose();
             cq.Dispose();
-            GrpcEnvironment.Release();
+            GrpcEnvironment.ReleaseAsync().Wait();
             Assert.AreEqual(CompletionQueueEvent.CompletionType.Shutdown, ev.type);
             Assert.AreEqual(CompletionQueueEvent.CompletionType.Shutdown, ev.type);
             Assert.AreNotEqual(IntPtr.Zero, ev.success);
             Assert.AreNotEqual(IntPtr.Zero, ev.success);
             Assert.AreEqual(IntPtr.Zero, ev.tag);
             Assert.AreEqual(IntPtr.Zero, ev.tag);

+ 1 - 1
src/csharp/Grpc.Core.Tests/MockServiceHelper.cs

@@ -102,7 +102,7 @@ namespace Grpc.Core.Tests
                 marshaller,
                 marshaller,
                 marshaller);
                 marshaller);
 
 
-            serviceDefinition = ServerServiceDefinition.CreateBuilder(ServiceName)
+            serviceDefinition = ServerServiceDefinition.CreateBuilder()
                 .AddMethod(unaryMethod, (request, context) => unaryHandler(request, context))
                 .AddMethod(unaryMethod, (request, context) => unaryHandler(request, context))
                 .AddMethod(clientStreamingMethod, (requestStream, context) => clientStreamingHandler(requestStream, context))
                 .AddMethod(clientStreamingMethod, (requestStream, context) => clientStreamingHandler(requestStream, context))
                 .AddMethod(serverStreamingMethod, (request, responseStream, context) => serverStreamingHandler(request, responseStream, context))
                 .AddMethod(serverStreamingMethod, (request, responseStream, context) => serverStreamingHandler(request, responseStream, context))

+ 1 - 1
src/csharp/Grpc.Core.Tests/PInvokeTest.cs

@@ -65,7 +65,7 @@ namespace Grpc.Core.Tests
                     cq.Dispose();
                     cq.Dispose();
                 });
                 });
 
 
-            GrpcEnvironment.Release();
+            GrpcEnvironment.ReleaseAsync().Wait();
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 1 - 1
src/csharp/Grpc.Core.Tests/ServerTest.cs

@@ -89,7 +89,7 @@ namespace Grpc.Core.Tests
             };
             };
             server.Start();
             server.Start();
             Assert.Throws(typeof(InvalidOperationException), () => server.Ports.Add("localhost", 9999, ServerCredentials.Insecure));
             Assert.Throws(typeof(InvalidOperationException), () => server.Ports.Add("localhost", 9999, ServerCredentials.Insecure));
-            Assert.Throws(typeof(InvalidOperationException), () => server.Services.Add(ServerServiceDefinition.CreateBuilder("serviceName").Build()));
+            Assert.Throws(typeof(InvalidOperationException), () => server.Services.Add(ServerServiceDefinition.CreateBuilder().Build()));
 
 
             server.ShutdownAsync().Wait();
             server.ShutdownAsync().Wait();
         }
         }

+ 57 - 0
src/csharp/Grpc.Core.Tests/ShutdownHookClientTest.cs

@@ -0,0 +1,57 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.Core.Tests
+{
+    public class ShutdownHookClientTest
+    {
+        const string Host = "127.0.0.1";
+
+        [Test]
+        public void ProcessExitHookCanCleanupAbandonedChannels()
+        {
+            var channel = new Channel(Host, 1000, ChannelCredentials.Insecure);
+            var channel2 = new Channel(Host, 1001, ChannelCredentials.Insecure);
+        }
+    }
+}

+ 69 - 0
src/csharp/Grpc.Core.Tests/ShutdownHookPendingCallTest.cs

@@ -0,0 +1,69 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.Core.Tests
+{
+    public class ShutdownHookPendingCallTest
+    {
+        const string Host = "127.0.0.1";
+
+        [Test]
+        public void ProcessExitHookCanCleanupAbandonedCall()
+        {
+            var helper = new MockServiceHelper(Host);
+            var server = helper.GetServer();
+            server.Start();
+            var channel = helper.GetChannel();
+
+            var readyToShutdown = new TaskCompletionSource<object>();
+            helper.DuplexStreamingHandler = new DuplexStreamingServerMethod<string, string>(async (requestStream, responseStream, context) =>
+            {
+                readyToShutdown.SetResult(null);
+                await requestStream.ToListAsync();
+            });
+
+            var call = Calls.AsyncDuplexStreamingCall(helper.CreateDuplexStreamingCall());
+            readyToShutdown.Task.Wait();  // make sure handler is running
+        }
+    }
+}

+ 58 - 0
src/csharp/Grpc.Core.Tests/ShutdownHookServerTest.cs

@@ -0,0 +1,58 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.Core.Tests
+{
+    public class ShutdownHookServerTest
+    {
+        const string Host = "127.0.0.1";
+
+        [Test]
+        public void ProcessExitHookCanCleanupAbandonedServers()
+        {
+            var helper = new MockServiceHelper(Host);
+            var server = helper.GetServer();
+            server.Start();
+        }
+    }
+}

+ 4 - 0
src/csharp/Grpc.Core/AsyncClientStreamingCall.cs

@@ -127,6 +127,10 @@ namespace Grpc.Core
         /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
         /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
         /// As a result, all resources being used by the call should be released eventually.
         /// As a result, all resources being used by the call should be released eventually.
         /// </summary>
         /// </summary>
+        /// <remarks>
+        /// Normally, there is no need for you to dispose the call unless you want to utilize the
+        /// "Cancel" semantics of invoking <c>Dispose</c>.
+        /// </remarks>
         public void Dispose()
         public void Dispose()
         {
         {
             disposeAction.Invoke();
             disposeAction.Invoke();

+ 4 - 0
src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs

@@ -117,6 +117,10 @@ namespace Grpc.Core
         /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
         /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
         /// As a result, all resources being used by the call should be released eventually.
         /// As a result, all resources being used by the call should be released eventually.
         /// </summary>
         /// </summary>
+        /// <remarks>
+        /// Normally, there is no need for you to dispose the call unless you want to utilize the
+        /// "Cancel" semantics of invoking <c>Dispose</c>.
+        /// </remarks>
         public void Dispose()
         public void Dispose()
         {
         {
             disposeAction.Invoke();
             disposeAction.Invoke();

+ 4 - 0
src/csharp/Grpc.Core/AsyncServerStreamingCall.cs

@@ -103,6 +103,10 @@ namespace Grpc.Core
         /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
         /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
         /// As a result, all resources being used by the call should be released eventually.
         /// As a result, all resources being used by the call should be released eventually.
         /// </summary>
         /// </summary>
+        /// <remarks>
+        /// Normally, there is no need for you to dispose the call unless you want to utilize the
+        /// "Cancel" semantics of invoking <c>Dispose</c>.
+        /// </remarks>
         public void Dispose()
         public void Dispose()
         {
         {
             disposeAction.Invoke();
             disposeAction.Invoke();

+ 4 - 0
src/csharp/Grpc.Core/AsyncUnaryCall.cs

@@ -112,6 +112,10 @@ namespace Grpc.Core
         /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
         /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
         /// As a result, all resources being used by the call should be released eventually.
         /// As a result, all resources being used by the call should be released eventually.
         /// </summary>
         /// </summary>
+        /// <remarks>
+        /// Normally, there is no need for you to dispose the call unless you want to utilize the
+        /// "Cancel" semantics of invoking <c>Dispose</c>.
+        /// </remarks>
         public void Dispose()
         public void Dispose()
         {
         {
             disposeAction.Invoke();
             disposeAction.Invoke();

+ 7 - 1
src/csharp/Grpc.Core/CallOptions.cs

@@ -88,7 +88,13 @@ namespace Grpc.Core
         }
         }
 
 
         /// <summary>
         /// <summary>
-        /// Token that can be used for cancelling the call.
+        /// Token that can be used for cancelling the call on the client side.
+        /// Cancelling the token will request cancellation
+        /// of the remote call. Best effort will be made to deliver the cancellation
+        /// notification to the server and interaction of the call with the server side
+        /// will be terminated. Unless the call finishes before the cancellation could
+        /// happen (there is an inherent race),
+        /// the call will finish with <c>StatusCode.Cancelled</c> status.
         /// </summary>
         /// </summary>
         public CancellationToken CancellationToken
         public CancellationToken CancellationToken
         {
         {

+ 43 - 12
src/csharp/Grpc.Core/Channel.cs

@@ -61,6 +61,17 @@ namespace Grpc.Core
 
 
         bool shutdownRequested;
         bool shutdownRequested;
 
 
+        /// <summary>
+        /// Creates a channel that connects to a specific host.
+        /// Port will default to 80 for an unsecure channel and to 443 for a secure channel.
+        /// </summary>
+        /// <param name="target">Target of the channel.</param>
+        /// <param name="credentials">Credentials to secure the channel.</param>
+        public Channel(string target, ChannelCredentials credentials) :
+            this(target, credentials, null)
+        {
+        }
+
         /// <summary>
         /// <summary>
         /// Creates a channel that connects to a specific host.
         /// Creates a channel that connects to a specific host.
         /// Port will default to 80 for an unsecure channel and to 443 for a secure channel.
         /// Port will default to 80 for an unsecure channel and to 443 for a secure channel.
@@ -68,7 +79,7 @@ namespace Grpc.Core
         /// <param name="target">Target of the channel.</param>
         /// <param name="target">Target of the channel.</param>
         /// <param name="credentials">Credentials to secure the channel.</param>
         /// <param name="credentials">Credentials to secure the channel.</param>
         /// <param name="options">Channel options.</param>
         /// <param name="options">Channel options.</param>
-        public Channel(string target, ChannelCredentials credentials, IEnumerable<ChannelOption> options = null)
+        public Channel(string target, ChannelCredentials credentials, IEnumerable<ChannelOption> options)
         {
         {
             this.target = GrpcPreconditions.CheckNotNull(target, "target");
             this.target = GrpcPreconditions.CheckNotNull(target, "target");
             this.options = CreateOptionsDictionary(options);
             this.options = CreateOptionsDictionary(options);
@@ -88,6 +99,18 @@ namespace Grpc.Core
                     this.handle = ChannelSafeHandle.CreateInsecure(target, nativeChannelArgs);
                     this.handle = ChannelSafeHandle.CreateInsecure(target, nativeChannelArgs);
                 }
                 }
             }
             }
+            GrpcEnvironment.RegisterChannel(this);
+        }
+
+        /// <summary>
+        /// Creates a channel that connects to a specific host and port.
+        /// </summary>
+        /// <param name="host">The name or IP address of the host.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="credentials">Credentials to secure the channel.</param>
+        public Channel(string host, int port, ChannelCredentials credentials) :
+            this(host, port, credentials, null)
+        {
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -97,14 +120,14 @@ namespace Grpc.Core
         /// <param name="port">The port.</param>
         /// <param name="port">The port.</param>
         /// <param name="credentials">Credentials to secure the channel.</param>
         /// <param name="credentials">Credentials to secure the channel.</param>
         /// <param name="options">Channel options.</param>
         /// <param name="options">Channel options.</param>
-        public Channel(string host, int port, ChannelCredentials credentials, IEnumerable<ChannelOption> options = null) :
+        public Channel(string host, int port, ChannelCredentials credentials, IEnumerable<ChannelOption> options) :
             this(string.Format("{0}:{1}", host, port), credentials, options)
             this(string.Format("{0}:{1}", host, port), credentials, options)
         {
         {
         }
         }
 
 
         /// <summary>
         /// <summary>
         /// Gets current connectivity state of this channel.
         /// Gets current connectivity state of this channel.
-        /// After channel is has been shutdown, <c>ChannelState.FatalFailure</c> will be returned.
+        /// After channel is has been shutdown, <c>ChannelState.Shutdown</c> will be returned.
         /// </summary>
         /// </summary>
         public ChannelState State
         public ChannelState State
         {
         {
@@ -121,8 +144,8 @@ namespace Grpc.Core
         /// </summary>
         /// </summary>
         public Task WaitForStateChangedAsync(ChannelState lastObservedState, DateTime? deadline = null)
         public Task WaitForStateChangedAsync(ChannelState lastObservedState, DateTime? deadline = null)
         {
         {
-            GrpcPreconditions.CheckArgument(lastObservedState != ChannelState.FatalFailure,
-                "FatalFailure is a terminal state. No further state changes can occur.");
+            GrpcPreconditions.CheckArgument(lastObservedState != ChannelState.Shutdown,
+                "Shutdown is a terminal state. No further state changes can occur.");
             var tcs = new TaskCompletionSource<object>();
             var tcs = new TaskCompletionSource<object>();
             var deadlineTimespec = deadline.HasValue ? Timespec.FromDateTime(deadline.Value) : Timespec.InfFuture;
             var deadlineTimespec = deadline.HasValue ? Timespec.FromDateTime(deadline.Value) : Timespec.InfFuture;
             var handler = new BatchCompletionDelegate((success, ctx) =>
             var handler = new BatchCompletionDelegate((success, ctx) =>
@@ -172,7 +195,7 @@ namespace Grpc.Core
         /// <summary>
         /// <summary>
         /// Allows explicitly requesting channel to connect without starting an RPC.
         /// Allows explicitly requesting channel to connect without starting an RPC.
         /// Returned task completes once state Ready was seen. If the deadline is reached,
         /// Returned task completes once state Ready was seen. If the deadline is reached,
-        /// or channel enters the FatalFailure state, the task is cancelled.
+        /// or channel enters the Shutdown state, the task is cancelled.
         /// There is no need to call this explicitly unless your use case requires that.
         /// There is no need to call this explicitly unless your use case requires that.
         /// Starting an RPC on a new channel will request connection implicitly.
         /// Starting an RPC on a new channel will request connection implicitly.
         /// </summary>
         /// </summary>
@@ -182,9 +205,9 @@ namespace Grpc.Core
             var currentState = GetConnectivityState(true);
             var currentState = GetConnectivityState(true);
             while (currentState != ChannelState.Ready)
             while (currentState != ChannelState.Ready)
             {
             {
-                if (currentState == ChannelState.FatalFailure)
+                if (currentState == ChannelState.Shutdown)
                 {
                 {
-                    throw new OperationCanceledException("Channel has reached FatalFailure state.");
+                    throw new OperationCanceledException("Channel has reached Shutdown state.");
                 }
                 }
                 await WaitForStateChangedAsync(currentState, deadline).ConfigureAwait(false);
                 await WaitForStateChangedAsync(currentState, deadline).ConfigureAwait(false);
                 currentState = GetConnectivityState(false);
                 currentState = GetConnectivityState(false);
@@ -192,9 +215,16 @@ namespace Grpc.Core
         }
         }
 
 
         /// <summary>
         /// <summary>
-        /// Waits until there are no more active calls for this channel and then cleans up
-        /// resources used by this channel.
+        /// Shuts down the channel cleanly. It is strongly recommended to shutdown
+        /// all previously created channels before exiting from the process.
         /// </summary>
         /// </summary>
+        /// <remarks>
+        /// This method doesn't wait for all calls on this channel to finish (nor does
+        /// it explicitly cancel all outstanding calls). It is user's responsibility to make sure
+        /// all the calls on this channel have finished (successfully or with an error)
+        /// before shutting down the channel to ensure channel shutdown won't impact
+        /// the outcome of those remote calls.
+        /// </remarks>
         public async Task ShutdownAsync()
         public async Task ShutdownAsync()
         {
         {
             lock (myLock)
             lock (myLock)
@@ -202,6 +232,7 @@ namespace Grpc.Core
                 GrpcPreconditions.CheckState(!shutdownRequested);
                 GrpcPreconditions.CheckState(!shutdownRequested);
                 shutdownRequested = true;
                 shutdownRequested = true;
             }
             }
+            GrpcEnvironment.UnregisterChannel(this);
 
 
             shutdownTokenSource.Cancel();
             shutdownTokenSource.Cancel();
 
 
@@ -213,7 +244,7 @@ namespace Grpc.Core
 
 
             handle.Dispose();
             handle.Dispose();
 
 
-            await Task.Run(() => GrpcEnvironment.Release()).ConfigureAwait(false);
+            await GrpcEnvironment.ReleaseAsync().ConfigureAwait(false);
         }
         }
 
 
         internal ChannelSafeHandle Handle
         internal ChannelSafeHandle Handle
@@ -264,7 +295,7 @@ namespace Grpc.Core
             }
             }
             catch (ObjectDisposedException)
             catch (ObjectDisposedException)
             {
             {
-                return ChannelState.FatalFailure;
+                return ChannelState.Shutdown;
             }
             }
         }
         }
 
 

+ 1 - 1
src/csharp/Grpc.Core/ChannelState.cs

@@ -64,6 +64,6 @@ namespace Grpc.Core
         /// <summary>
         /// <summary>
         /// Channel has seen a failure that it cannot recover from
         /// Channel has seen a failure that it cannot recover from
         /// </summary>
         /// </summary>
-        FatalFailure
+        Shutdown
     }
     }
 }
 }

+ 115 - 6
src/csharp/Grpc.Core/GrpcEnvironment.cs

@@ -35,6 +35,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Runtime.InteropServices;
 using System.Runtime.InteropServices;
+using System.Threading.Tasks;
 using Grpc.Core.Internal;
 using Grpc.Core.Internal;
 using Grpc.Core.Logging;
 using Grpc.Core.Logging;
 using Grpc.Core.Utils;
 using Grpc.Core.Utils;
@@ -53,12 +54,16 @@ namespace Grpc.Core
         static int refCount;
         static int refCount;
         static int? customThreadPoolSize;
         static int? customThreadPoolSize;
         static int? customCompletionQueueCount;
         static int? customCompletionQueueCount;
+        static readonly HashSet<Channel> registeredChannels = new HashSet<Channel>();
+        static readonly HashSet<Server> registeredServers = new HashSet<Server>();
 
 
         static ILogger logger = new ConsoleLogger();
         static ILogger logger = new ConsoleLogger();
 
 
+        readonly object myLock = new object();
         readonly GrpcThreadPool threadPool;
         readonly GrpcThreadPool threadPool;
         readonly DebugStats debugStats = new DebugStats();
         readonly DebugStats debugStats = new DebugStats();
         readonly AtomicCounter cqPickerCounter = new AtomicCounter();
         readonly AtomicCounter cqPickerCounter = new AtomicCounter();
+
         bool isClosed;
         bool isClosed;
 
 
         /// <summary>
         /// <summary>
@@ -67,6 +72,8 @@ namespace Grpc.Core
         /// </summary>
         /// </summary>
         internal static GrpcEnvironment AddRef()
         internal static GrpcEnvironment AddRef()
         {
         {
+            ShutdownHooks.Register();
+
             lock (staticLock)
             lock (staticLock)
             {
             {
                 refCount++;
                 refCount++;
@@ -79,21 +86,26 @@ namespace Grpc.Core
         }
         }
 
 
         /// <summary>
         /// <summary>
-        /// Decrements the reference count for currently active environment and shuts down the gRPC environment if reference count drops to zero.
-        /// (and blocks until the environment has been fully shutdown).
+        /// Decrements the reference count for currently active environment and asynchronously shuts down the gRPC environment if reference count drops to zero.
         /// </summary>
         /// </summary>
-        internal static void Release()
+        internal static async Task ReleaseAsync()
         {
         {
+            GrpcEnvironment instanceToShutdown = null;
             lock (staticLock)
             lock (staticLock)
             {
             {
                 GrpcPreconditions.CheckState(refCount > 0);
                 GrpcPreconditions.CheckState(refCount > 0);
                 refCount--;
                 refCount--;
                 if (refCount == 0)
                 if (refCount == 0)
                 {
                 {
-                    instance.Close();
+                    instanceToShutdown = instance;
                     instance = null;
                     instance = null;
                 }
                 }
             }
             }
+
+            if (instanceToShutdown != null)
+            {
+                await instanceToShutdown.ShutdownAsync();
+            }
         }
         }
 
 
         internal static int GetRefCount()
         internal static int GetRefCount()
@@ -104,6 +116,68 @@ namespace Grpc.Core
             }
             }
         }
         }
 
 
+        internal static void RegisterChannel(Channel channel)
+        {
+            lock (staticLock)
+            {
+                GrpcPreconditions.CheckNotNull(channel);
+                registeredChannels.Add(channel);
+            }
+        }
+
+        internal static void UnregisterChannel(Channel channel)
+        {
+            lock (staticLock)
+            {
+                GrpcPreconditions.CheckNotNull(channel);
+                GrpcPreconditions.CheckArgument(registeredChannels.Remove(channel), "Channel not found in the registered channels set.");
+            }
+        }
+
+        internal static void RegisterServer(Server server)
+        {
+            lock (staticLock)
+            {
+                GrpcPreconditions.CheckNotNull(server);
+                registeredServers.Add(server);
+            }
+        }
+
+        internal static void UnregisterServer(Server server)
+        {
+            lock (staticLock)
+            {
+                GrpcPreconditions.CheckNotNull(server);
+                GrpcPreconditions.CheckArgument(registeredServers.Remove(server), "Server not found in the registered servers set.");
+            }
+        }
+
+        /// <summary>
+        /// Requests shutdown of all channels created by the current process.
+        /// </summary>
+        public static Task ShutdownChannelsAsync()
+        {
+            HashSet<Channel> snapshot = null;
+            lock (staticLock)
+            {
+                snapshot = new HashSet<Channel>(registeredChannels);
+            }
+            return Task.WhenAll(snapshot.Select((channel) => channel.ShutdownAsync()));
+        }
+
+        /// <summary>
+        /// Requests immediate shutdown of all servers created by the current process.
+        /// </summary>
+        public static Task KillServersAsync()
+        {
+            HashSet<Server> snapshot = null;
+            lock (staticLock)
+            {
+                snapshot = new HashSet<Server>(registeredServers);
+            }
+            return Task.WhenAll(snapshot.Select((server) => server.KillAsync()));
+        }
+
         /// <summary>
         /// <summary>
         /// Gets application-wide logger used by gRPC.
         /// Gets application-wide logger used by gRPC.
         /// </summary>
         /// </summary>
@@ -180,6 +254,14 @@ namespace Grpc.Core
             }
             }
         }
         }
 
 
+        internal bool IsAlive
+        {
+            get
+            {
+                return this.threadPool.IsAlive;
+            }
+        }
+
         /// <summary>
         /// <summary>
         /// Picks a completion queue in a round-robin fashion.
         /// Picks a completion queue in a round-robin fashion.
         /// Shouldn't be invoked on a per-call basis (used at per-channel basis).
         /// Shouldn't be invoked on a per-call basis (used at per-channel basis).
@@ -223,13 +305,13 @@ namespace Grpc.Core
         /// <summary>
         /// <summary>
         /// Shuts down this environment.
         /// Shuts down this environment.
         /// </summary>
         /// </summary>
-        private void Close()
+        private async Task ShutdownAsync()
         {
         {
             if (isClosed)
             if (isClosed)
             {
             {
                 throw new InvalidOperationException("Close has already been called");
                 throw new InvalidOperationException("Close has already been called");
             }
             }
-            threadPool.Stop();
+            await threadPool.StopAsync().ConfigureAwait(false);
             GrpcNativeShutdown();
             GrpcNativeShutdown();
             isClosed = true;
             isClosed = true;
 
 
@@ -257,5 +339,32 @@ namespace Grpc.Core
             // by default, create a completion queue for each thread
             // by default, create a completion queue for each thread
             return GetThreadPoolSizeOrDefault();
             return GetThreadPoolSizeOrDefault();
         }
         }
+
+        private static class ShutdownHooks
+        {
+            static object staticLock = new object();
+            static bool hooksRegistered;
+
+            public static void Register()
+            {
+                lock (staticLock)
+                {
+                    if (!hooksRegistered)
+                    {
+                        AppDomain.CurrentDomain.ProcessExit += ShutdownHookHandler;
+                        AppDomain.CurrentDomain.DomainUnload += ShutdownHookHandler;
+                    }
+                    hooksRegistered = true;
+                }
+            }
+
+            /// <summary>
+            /// Handler for AppDomain.DomainUnload and AppDomain.ProcessExit hooks.
+            /// </summary>
+            private static void ShutdownHookHandler(object sender, EventArgs e)
+            {
+                Task.WaitAll(GrpcEnvironment.ShutdownChannelsAsync(), GrpcEnvironment.KillServersAsync());
+            }
+        }
     }
     }
 }
 }

+ 26 - 2
src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs

@@ -35,6 +35,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Threading;
 using System.Threading;
+using System.Threading.Tasks;
 using Grpc.Core.Logging;
 using Grpc.Core.Logging;
 using Grpc.Core.Utils;
 using Grpc.Core.Utils;
 
 
@@ -53,6 +54,8 @@ namespace Grpc.Core.Internal
         readonly int poolSize;
         readonly int poolSize;
         readonly int completionQueueCount;
         readonly int completionQueueCount;
 
 
+        bool stopRequested;
+
         IReadOnlyCollection<CompletionQueueSafeHandle> completionQueues;
         IReadOnlyCollection<CompletionQueueSafeHandle> completionQueues;
 
 
         /// <summary>
         /// <summary>
@@ -84,15 +87,21 @@ namespace Grpc.Core.Internal
             }
             }
         }
         }
 
 
-        public void Stop()
+        public Task StopAsync()
         {
         {
             lock (myLock)
             lock (myLock)
             {
             {
+                GrpcPreconditions.CheckState(!stopRequested, "Stop already requested.");
+                stopRequested = true;
+
                 foreach (var cq in completionQueues)
                 foreach (var cq in completionQueues)
                 {
                 {
                     cq.Shutdown();
                     cq.Shutdown();
                 }
                 }
+            }
 
 
+            return Task.Run(() =>
+            {
                 foreach (var thread in threads)
                 foreach (var thread in threads)
                 {
                 {
                     thread.Join();
                     thread.Join();
@@ -102,6 +111,21 @@ namespace Grpc.Core.Internal
                 {
                 {
                     cq.Dispose();
                     cq.Dispose();
                 }
                 }
+            });
+        }
+
+        /// <summary>
+        /// Returns true if there is at least one thread pool thread that hasn't
+        /// already stopped.
+        /// Threads can either stop because all completion queues shut down or
+        /// because all foreground threads have already shutdown and process is
+        /// going to exit.
+        /// </summary>
+        internal bool IsAlive
+        {
+            get
+            {
+                return threads.Any(t => t.ThreadState != ThreadState.Stopped);
             }
             }
         }
         }
 
 
@@ -119,7 +143,7 @@ namespace Grpc.Core.Internal
             var cq = completionQueues.ElementAt(cqIndex);
             var cq = completionQueues.ElementAt(cqIndex);
 
 
             var thread = new Thread(new ThreadStart(() => RunHandlerLoop(cq)));
             var thread = new Thread(new ThreadStart(() => RunHandlerLoop(cq)));
-            thread.IsBackground = false;
+            thread.IsBackground = true;
             thread.Name = string.Format("grpc {0} (cq {1})", threadIndex, cqIndex);
             thread.Name = string.Format("grpc {0} (cq {1})", threadIndex, cqIndex);
             thread.Start();
             thread.Start();
 
 

+ 68 - 31
src/csharp/Grpc.Core/Server.cs

@@ -67,11 +67,19 @@ namespace Grpc.Core
         bool startRequested;
         bool startRequested;
         volatile bool shutdownRequested;
         volatile bool shutdownRequested;
 
 
+
+        /// <summary>
+        /// Creates a new server.
+        /// </summary>
+        public Server() : this(null)
+        {
+        }
+
         /// <summary>
         /// <summary>
-        /// Create a new server.
+        /// Creates a new server.
         /// </summary>
         /// </summary>
         /// <param name="options">Channel options.</param>
         /// <param name="options">Channel options.</param>
-        public Server(IEnumerable<ChannelOption> options = null)
+        public Server(IEnumerable<ChannelOption> options)
         {
         {
             this.serviceDefinitions = new ServiceDefinitionCollection(this);
             this.serviceDefinitions = new ServiceDefinitionCollection(this);
             this.ports = new ServerPortCollection(this);
             this.ports = new ServerPortCollection(this);
@@ -86,6 +94,7 @@ namespace Grpc.Core
             {
             {
                 this.handle.RegisterCompletionQueue(cq);
                 this.handle.RegisterCompletionQueue(cq);
             }
             }
+            GrpcEnvironment.RegisterServer(this);
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -152,43 +161,24 @@ namespace Grpc.Core
         /// cleans up used resources. The returned task finishes when shutdown procedure
         /// cleans up used resources. The returned task finishes when shutdown procedure
         /// is complete.
         /// is complete.
         /// </summary>
         /// </summary>
-        public async Task ShutdownAsync()
+        /// <remarks>
+        /// It is strongly recommended to shutdown all previously created servers before exiting from the process.
+        /// </remarks>
+        public Task ShutdownAsync()
         {
         {
-            lock (myLock)
-            {
-                GrpcPreconditions.CheckState(startRequested);
-                GrpcPreconditions.CheckState(!shutdownRequested);
-                shutdownRequested = true;
-            }
-
-            var cq = environment.CompletionQueues.First();  // any cq will do
-            handle.ShutdownAndNotify(HandleServerShutdown, cq);
-            await shutdownTcs.Task.ConfigureAwait(false);
-            DisposeHandle();
-
-            await Task.Run(() => GrpcEnvironment.Release()).ConfigureAwait(false);
+            return ShutdownInternalAsync(false);
         }
         }
 
 
         /// <summary>
         /// <summary>
         /// Requests server shutdown while cancelling all the in-progress calls.
         /// Requests server shutdown while cancelling all the in-progress calls.
         /// The returned task finishes when shutdown procedure is complete.
         /// The returned task finishes when shutdown procedure is complete.
         /// </summary>
         /// </summary>
-        public async Task KillAsync()
+        /// <remarks>
+        /// It is strongly recommended to shutdown all previously created servers before exiting from the process.
+        /// </remarks>
+        public Task KillAsync()
         {
         {
-            lock (myLock)
-            {
-                GrpcPreconditions.CheckState(startRequested);
-                GrpcPreconditions.CheckState(!shutdownRequested);
-                shutdownRequested = true;
-            }
-
-            var cq = environment.CompletionQueues.First();  // any cq will do
-            handle.ShutdownAndNotify(HandleServerShutdown, cq);
-            handle.CancelAllCalls();
-            await shutdownTcs.Task.ConfigureAwait(false);
-            DisposeHandle();
-
-            await Task.Run(() => GrpcEnvironment.Release()).ConfigureAwait(false);
+            return ShutdownInternalAsync(true);
         }
         }
 
 
         internal void AddCallReference(object call)
         internal void AddCallReference(object call)
@@ -206,6 +196,53 @@ namespace Grpc.Core
             activeCallCounter.Decrement();
             activeCallCounter.Decrement();
         }
         }
 
 
+        /// <summary>
+        /// Shuts down the server.
+        /// </summary>
+        private async Task ShutdownInternalAsync(bool kill)
+        {
+            lock (myLock)
+            {
+                GrpcPreconditions.CheckState(startRequested);
+                GrpcPreconditions.CheckState(!shutdownRequested);
+                shutdownRequested = true;
+            }
+            GrpcEnvironment.UnregisterServer(this);
+
+            var cq = environment.CompletionQueues.First();  // any cq will do
+            handle.ShutdownAndNotify(HandleServerShutdown, cq);
+            if (kill)
+            {
+                handle.CancelAllCalls();
+            }
+
+            await ShutdownCompleteOrEnvironmentDeadAsync().ConfigureAwait(false);
+
+            DisposeHandle();
+
+            await GrpcEnvironment.ReleaseAsync().ConfigureAwait(false);
+        }
+
+        /// <summary>
+        /// In case the environment's threadpool becomes dead, the shutdown completion will
+        /// never be delivered, but we need to release the environment's handle anyway.
+        /// </summary>
+        private async Task ShutdownCompleteOrEnvironmentDeadAsync()
+        {
+            while (true)
+            {
+                var task = await Task.WhenAny(shutdownTcs.Task, Task.Delay(20)).ConfigureAwait(false);
+                if (shutdownTcs.Task == task)
+                {
+                    return;
+                }
+                if (!environment.IsAlive)
+                {
+                    return;
+                }
+            }
+        }
+
         /// <summary>
         /// <summary>
         /// Adds a service definition.
         /// Adds a service definition.
         /// </summary>
         /// </summary>

+ 3 - 7
src/csharp/Grpc.Core/ServerServiceDefinition.cs

@@ -63,11 +63,10 @@ namespace Grpc.Core
         /// <summary>
         /// <summary>
         /// Creates a new builder object for <c>ServerServiceDefinition</c>.
         /// Creates a new builder object for <c>ServerServiceDefinition</c>.
         /// </summary>
         /// </summary>
-        /// <param name="serviceName">The service name.</param>
         /// <returns>The builder object.</returns>
         /// <returns>The builder object.</returns>
-        public static Builder CreateBuilder(string serviceName)
+        public static Builder CreateBuilder()
         {
         {
-            return new Builder(serviceName);
+            return new Builder();
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -75,16 +74,13 @@ namespace Grpc.Core
         /// </summary>
         /// </summary>
         public class Builder
         public class Builder
         {
         {
-            readonly string serviceName;
             readonly Dictionary<string, IServerCallHandler> callHandlers = new Dictionary<string, IServerCallHandler>();
             readonly Dictionary<string, IServerCallHandler> callHandlers = new Dictionary<string, IServerCallHandler>();
 
 
             /// <summary>
             /// <summary>
             /// Creates a new instance of builder.
             /// Creates a new instance of builder.
             /// </summary>
             /// </summary>
-            /// <param name="serviceName">The service name.</param>
-            public Builder(string serviceName)
+            public Builder()
             {
             {
-                this.serviceName = serviceName;
             }
             }
 
 
             /// <summary>
             /// <summary>

+ 15 - 122
src/csharp/Grpc.Examples/MathGrpc.cs

@@ -81,103 +81,12 @@ namespace Math {
       get { return global::Math.MathReflection.Descriptor.Services[0]; }
       get { return global::Math.MathReflection.Descriptor.Services[0]; }
     }
     }
 
 
-    /// <summary>Client for Math</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface IMathClient
-    {
-      /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
-      /// </summary>
-      global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
-      /// </summary>
-      global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options);
-      /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
-      /// </summary>
-      AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
-      /// </summary>
-      AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options);
-      /// <summary>
-      ///  DivMany accepts an arbitrary number of division args from the client stream
-      ///  and sends back the results in the reply stream.  The stream continues until
-      ///  the client closes its end; the server does the same after sending all the
-      ///  replies.  The stream ends immediately if either end aborts.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  DivMany accepts an arbitrary number of division args from the client stream
-      ///  and sends back the results in the reply stream.  The stream continues until
-      ///  the client closes its end; the server does the same after sending all the
-      ///  replies.  The stream ends immediately if either end aborts.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(CallOptions options);
-      /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
-      ///  generates up to limit numbers; otherwise it continues until the call is
-      ///  canceled.  Unlike Fib above, Fib has no final FibReply.
-      /// </summary>
-      AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
-      ///  generates up to limit numbers; otherwise it continues until the call is
-      ///  canceled.  Unlike Fib above, Fib has no final FibReply.
-      /// </summary>
-      AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, CallOptions options);
-      /// <summary>
-      ///  Sum sums a stream of numbers, returning the final result once the stream
-      ///  is closed.
-      /// </summary>
-      AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Sum sums a stream of numbers, returning the final result once the stream
-      ///  is closed.
-      /// </summary>
-      AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of Math</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface IMath
-    {
-      /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context);
-      /// <summary>
-      ///  DivMany accepts an arbitrary number of division args from the client stream
-      ///  and sends back the results in the reply stream.  The stream continues until
-      ///  the client closes its end; the server does the same after sending all the
-      ///  replies.  The stream ends immediately if either end aborts.
-      /// </summary>
-      global::System.Threading.Tasks.Task DivMany(IAsyncStreamReader<global::Math.DivArgs> requestStream, IServerStreamWriter<global::Math.DivReply> responseStream, ServerCallContext context);
-      /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
-      ///  generates up to limit numbers; otherwise it continues until the call is
-      ///  canceled.  Unlike Fib above, Fib has no final FibReply.
-      /// </summary>
-      global::System.Threading.Tasks.Task Fib(global::Math.FibArgs request, IServerStreamWriter<global::Math.Num> responseStream, ServerCallContext context);
-      /// <summary>
-      ///  Sum sums a stream of numbers, returning the final result once the stream
-      ///  is closed.
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Math.Num> Sum(IAsyncStreamReader<global::Math.Num> requestStream, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of Math</summary>
     /// <summary>Base class for server-side implementations of Math</summary>
     public abstract class MathBase
     public abstract class MathBase
     {
     {
       /// <summary>
       /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
+      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      ///  and remainder.
       /// </summary>
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context)
       public virtual global::System.Threading.Tasks.Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context)
       {
       {
@@ -196,7 +105,7 @@ namespace Math {
       }
       }
 
 
       /// <summary>
       /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
+      ///  Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
       ///  generates up to limit numbers; otherwise it continues until the call is
       ///  generates up to limit numbers; otherwise it continues until the call is
       ///  canceled.  Unlike Fib above, Fib has no final FibReply.
       ///  canceled.  Unlike Fib above, Fib has no final FibReply.
       /// </summary>
       /// </summary>
@@ -217,9 +126,7 @@ namespace Math {
     }
     }
 
 
     /// <summary>Client for Math</summary>
     /// <summary>Client for Math</summary>
-    #pragma warning disable 0618
-    public class MathClient : ClientBase<MathClient>, IMathClient
-    #pragma warning restore 0618
+    public class MathClient : ClientBase<MathClient>
     {
     {
       public MathClient(Channel channel) : base(channel)
       public MathClient(Channel channel) : base(channel)
       {
       {
@@ -237,32 +144,32 @@ namespace Math {
       }
       }
 
 
       /// <summary>
       /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
+      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      ///  and remainder.
       /// </summary>
       /// </summary>
       public virtual global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       public virtual global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
       {
         return Div(request, new CallOptions(headers, deadline, cancellationToken));
         return Div(request, new CallOptions(headers, deadline, cancellationToken));
       }
       }
       /// <summary>
       /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
+      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      ///  and remainder.
       /// </summary>
       /// </summary>
       public virtual global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options)
       public virtual global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options)
       {
       {
         return CallInvoker.BlockingUnaryCall(__Method_Div, null, options, request);
         return CallInvoker.BlockingUnaryCall(__Method_Div, null, options, request);
       }
       }
       /// <summary>
       /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
+      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      ///  and remainder.
       /// </summary>
       /// </summary>
       public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
       {
         return DivAsync(request, new CallOptions(headers, deadline, cancellationToken));
         return DivAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       }
       /// <summary>
       /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
+      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      ///  and remainder.
       /// </summary>
       /// </summary>
       public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options)
       public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options)
       {
       {
@@ -289,7 +196,7 @@ namespace Math {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_DivMany, null, options);
         return CallInvoker.AsyncDuplexStreamingCall(__Method_DivMany, null, options);
       }
       }
       /// <summary>
       /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
+      ///  Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
       ///  generates up to limit numbers; otherwise it continues until the call is
       ///  generates up to limit numbers; otherwise it continues until the call is
       ///  canceled.  Unlike Fib above, Fib has no final FibReply.
       ///  canceled.  Unlike Fib above, Fib has no final FibReply.
       /// </summary>
       /// </summary>
@@ -298,7 +205,7 @@ namespace Math {
         return Fib(request, new CallOptions(headers, deadline, cancellationToken));
         return Fib(request, new CallOptions(headers, deadline, cancellationToken));
       }
       }
       /// <summary>
       /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
+      ///  Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
       ///  generates up to limit numbers; otherwise it continues until the call is
       ///  generates up to limit numbers; otherwise it continues until the call is
       ///  canceled.  Unlike Fib above, Fib has no final FibReply.
       ///  canceled.  Unlike Fib above, Fib has no final FibReply.
       /// </summary>
       /// </summary>
@@ -335,23 +242,9 @@ namespace Math {
     }
     }
 
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(IMath serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_Div, serviceImpl.Div)
-          .AddMethod(__Method_DivMany, serviceImpl.DivMany)
-          .AddMethod(__Method_Fib, serviceImpl.Fib)
-          .AddMethod(__Method_Sum, serviceImpl.Sum).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(MathBase serviceImpl)
     public static ServerServiceDefinition BindService(MathBase serviceImpl)
-    #pragma warning restore 0618
     {
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_Div, serviceImpl.Div)
           .AddMethod(__Method_Div, serviceImpl.Div)
           .AddMethod(__Method_DivMany, serviceImpl.DivMany)
           .AddMethod(__Method_DivMany, serviceImpl.DivMany)
           .AddMethod(__Method_Fib, serviceImpl.Fib)
           .AddMethod(__Method_Fib, serviceImpl.Fib)

+ 2 - 32
src/csharp/Grpc.HealthCheck/HealthGrpc.cs

@@ -58,23 +58,6 @@ namespace Grpc.Health.V1 {
       get { return global::Grpc.Health.V1.HealthReflection.Descriptor.Services[0]; }
       get { return global::Grpc.Health.V1.HealthReflection.Descriptor.Services[0]; }
     }
     }
 
 
-    /// <summary>Client for Health</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface IHealthClient
-    {
-      global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options);
-      AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of Health</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface IHealth
-    {
-      global::System.Threading.Tasks.Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of Health</summary>
     /// <summary>Base class for server-side implementations of Health</summary>
     public abstract class HealthBase
     public abstract class HealthBase
     {
     {
@@ -86,9 +69,7 @@ namespace Grpc.Health.V1 {
     }
     }
 
 
     /// <summary>Client for Health</summary>
     /// <summary>Client for Health</summary>
-    #pragma warning disable 0618
-    public class HealthClient : ClientBase<HealthClient>, IHealthClient
-    #pragma warning restore 0618
+    public class HealthClient : ClientBase<HealthClient>
     {
     {
       public HealthClient(Channel channel) : base(channel)
       public HealthClient(Channel channel) : base(channel)
       {
       {
@@ -134,20 +115,9 @@ namespace Grpc.Health.V1 {
     }
     }
 
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(IHealth serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_Check, serviceImpl.Check).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(HealthBase serviceImpl)
     public static ServerServiceDefinition BindService(HealthBase serviceImpl)
-    #pragma warning restore 0618
     {
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_Check, serviceImpl.Check).Build();
           .AddMethod(__Method_Check, serviceImpl.Check).Build();
     }
     }
 
 

+ 1 - 1
src/csharp/Grpc.IntegrationTesting/GenericService.cs

@@ -64,7 +64,7 @@ namespace Grpc.IntegrationTesting
 
 
         public static ServerServiceDefinition BindHandler(DuplexStreamingServerMethod<byte[], byte[]> handler)
         public static ServerServiceDefinition BindHandler(DuplexStreamingServerMethod<byte[], byte[]> handler)
         {
         {
-            return ServerServiceDefinition.CreateBuilder(StreamingCallMethod.ServiceName)
+            return ServerServiceDefinition.CreateBuilder()
                 .AddMethod(StreamingCallMethod, handler).Build();
                 .AddMethod(StreamingCallMethod, handler).Build();
         }
         }
     }
     }

+ 2 - 63
src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs

@@ -72,53 +72,6 @@ namespace Grpc.Testing {
       get { return global::Grpc.Testing.MetricsReflection.Descriptor.Services[0]; }
       get { return global::Grpc.Testing.MetricsReflection.Descriptor.Services[0]; }
     }
     }
 
 
-    /// <summary>Client for MetricsService</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface IMetricsServiceClient
-    {
-      /// <summary>
-      ///  Returns the values of all the gauges that are currently being maintained by
-      ///  the service
-      /// </summary>
-      AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Returns the values of all the gauges that are currently being maintained by
-      ///  the service
-      /// </summary>
-      AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, CallOptions options);
-      /// <summary>
-      ///  Returns the value of one gauge
-      /// </summary>
-      global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Returns the value of one gauge
-      /// </summary>
-      global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, CallOptions options);
-      /// <summary>
-      ///  Returns the value of one gauge
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Returns the value of one gauge
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of MetricsService</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface IMetricsService
-    {
-      /// <summary>
-      ///  Returns the values of all the gauges that are currently being maintained by
-      ///  the service
-      /// </summary>
-      global::System.Threading.Tasks.Task GetAllGauges(global::Grpc.Testing.EmptyMessage request, IServerStreamWriter<global::Grpc.Testing.GaugeResponse> responseStream, ServerCallContext context);
-      /// <summary>
-      ///  Returns the value of one gauge
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.GaugeResponse> GetGauge(global::Grpc.Testing.GaugeRequest request, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of MetricsService</summary>
     /// <summary>Base class for server-side implementations of MetricsService</summary>
     public abstract class MetricsServiceBase
     public abstract class MetricsServiceBase
     {
     {
@@ -142,9 +95,7 @@ namespace Grpc.Testing {
     }
     }
 
 
     /// <summary>Client for MetricsService</summary>
     /// <summary>Client for MetricsService</summary>
-    #pragma warning disable 0618
-    public class MetricsServiceClient : ClientBase<MetricsServiceClient>, IMetricsServiceClient
-    #pragma warning restore 0618
+    public class MetricsServiceClient : ClientBase<MetricsServiceClient>
     {
     {
       public MetricsServiceClient(Channel channel) : base(channel)
       public MetricsServiceClient(Channel channel) : base(channel)
       {
       {
@@ -218,21 +169,9 @@ namespace Grpc.Testing {
     }
     }
 
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(IMetricsService serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_GetAllGauges, serviceImpl.GetAllGauges)
-          .AddMethod(__Method_GetGauge, serviceImpl.GetGauge).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(MetricsServiceBase serviceImpl)
     public static ServerServiceDefinition BindService(MetricsServiceBase serviceImpl)
-    #pragma warning restore 0618
     {
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_GetAllGauges, serviceImpl.GetAllGauges)
           .AddMethod(__Method_GetAllGauges, serviceImpl.GetAllGauges)
           .AddMethod(__Method_GetGauge, serviceImpl.GetGauge).Build();
           .AddMethod(__Method_GetGauge, serviceImpl.GetGauge).Build();
     }
     }

+ 4 - 192
src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs

@@ -67,58 +67,6 @@ namespace Grpc.Testing {
       get { return global::Grpc.Testing.ServicesReflection.Descriptor.Services[0]; }
       get { return global::Grpc.Testing.ServicesReflection.Descriptor.Services[0]; }
     }
     }
 
 
-    /// <summary>Client for BenchmarkService</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface IBenchmarkServiceClient
-    {
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options);
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options);
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of BenchmarkService</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface IBenchmarkService
-    {
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context);
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      global::System.Threading.Tasks.Task StreamingCall(IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of BenchmarkService</summary>
     /// <summary>Base class for server-side implementations of BenchmarkService</summary>
     public abstract class BenchmarkServiceBase
     public abstract class BenchmarkServiceBase
     {
     {
@@ -143,9 +91,7 @@ namespace Grpc.Testing {
     }
     }
 
 
     /// <summary>Client for BenchmarkService</summary>
     /// <summary>Client for BenchmarkService</summary>
-    #pragma warning disable 0618
-    public class BenchmarkServiceClient : ClientBase<BenchmarkServiceClient>, IBenchmarkServiceClient
-    #pragma warning restore 0618
+    public class BenchmarkServiceClient : ClientBase<BenchmarkServiceClient>
     {
     {
       public BenchmarkServiceClient(Channel channel) : base(channel)
       public BenchmarkServiceClient(Channel channel) : base(channel)
       {
       {
@@ -223,21 +169,9 @@ namespace Grpc.Testing {
     }
     }
 
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(IBenchmarkService serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
-          .AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(BenchmarkServiceBase serviceImpl)
     public static ServerServiceDefinition BindService(BenchmarkServiceBase serviceImpl)
-    #pragma warning restore 0618
     {
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
           .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
           .AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall).Build();
           .AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall).Build();
     }
     }
@@ -289,112 +223,6 @@ namespace Grpc.Testing {
       get { return global::Grpc.Testing.ServicesReflection.Descriptor.Services[1]; }
       get { return global::Grpc.Testing.ServicesReflection.Descriptor.Services[1]; }
     }
     }
 
 
-    /// <summary>Client for WorkerService</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface IWorkerServiceClient
-    {
-      /// <summary>
-      ///  Start server with specified workload.
-      ///  First request sent specifies the ServerConfig followed by ServerStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test server
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Start server with specified workload.
-      ///  First request sent specifies the ServerConfig followed by ServerStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test server
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options);
-      /// <summary>
-      ///  Start client with specified workload.
-      ///  First request sent specifies the ClientConfig followed by ClientStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test client
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Start client with specified workload.
-      ///  First request sent specifies the ClientConfig followed by ClientStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test client
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options);
-      /// <summary>
-      ///  Just return the core count - unary call
-      /// </summary>
-      global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Just return the core count - unary call
-      /// </summary>
-      global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, CallOptions options);
-      /// <summary>
-      ///  Just return the core count - unary call
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Just return the core count - unary call
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, CallOptions options);
-      /// <summary>
-      ///  Quit this worker
-      /// </summary>
-      global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Quit this worker
-      /// </summary>
-      global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, CallOptions options);
-      /// <summary>
-      ///  Quit this worker
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Quit this worker
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of WorkerService</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface IWorkerService
-    {
-      /// <summary>
-      ///  Start server with specified workload.
-      ///  First request sent specifies the ServerConfig followed by ServerStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test server
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
-      /// </summary>
-      global::System.Threading.Tasks.Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context);
-      /// <summary>
-      ///  Start client with specified workload.
-      ///  First request sent specifies the ClientConfig followed by ClientStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test client
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
-      /// </summary>
-      global::System.Threading.Tasks.Task RunClient(IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, ServerCallContext context);
-      /// <summary>
-      ///  Just return the core count - unary call
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, ServerCallContext context);
-      /// <summary>
-      ///  Quit this worker
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of WorkerService</summary>
     /// <summary>Base class for server-side implementations of WorkerService</summary>
     public abstract class WorkerServiceBase
     public abstract class WorkerServiceBase
     {
     {
@@ -443,9 +271,7 @@ namespace Grpc.Testing {
     }
     }
 
 
     /// <summary>Client for WorkerService</summary>
     /// <summary>Client for WorkerService</summary>
-    #pragma warning disable 0618
-    public class WorkerServiceClient : ClientBase<WorkerServiceClient>, IWorkerServiceClient
-    #pragma warning restore 0618
+    public class WorkerServiceClient : ClientBase<WorkerServiceClient>
     {
     {
       public WorkerServiceClient(Channel channel) : base(channel)
       public WorkerServiceClient(Channel channel) : base(channel)
       {
       {
@@ -579,23 +405,9 @@ namespace Grpc.Testing {
     }
     }
 
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(IWorkerService serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_RunServer, serviceImpl.RunServer)
-          .AddMethod(__Method_RunClient, serviceImpl.RunClient)
-          .AddMethod(__Method_CoreCount, serviceImpl.CoreCount)
-          .AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(WorkerServiceBase serviceImpl)
     public static ServerServiceDefinition BindService(WorkerServiceBase serviceImpl)
-    #pragma warning restore 0618
     {
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_RunServer, serviceImpl.RunServer)
           .AddMethod(__Method_RunServer, serviceImpl.RunServer)
           .AddMethod(__Method_RunClient, serviceImpl.RunClient)
           .AddMethod(__Method_RunClient, serviceImpl.RunClient)
           .AddMethod(__Method_CoreCount, serviceImpl.CoreCount)
           .AddMethod(__Method_CoreCount, serviceImpl.CoreCount)

+ 6 - 226
src/csharp/Grpc.IntegrationTesting/TestGrpc.cs

@@ -105,127 +105,6 @@ namespace Grpc.Testing {
       get { return global::Grpc.Testing.TestReflection.Descriptor.Services[0]; }
       get { return global::Grpc.Testing.TestReflection.Descriptor.Services[0]; }
     }
     }
 
 
-    /// <summary>Client for TestService</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface ITestServiceClient
-    {
-      /// <summary>
-      ///  One empty request followed by one empty response.
-      /// </summary>
-      global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One empty request followed by one empty response.
-      /// </summary>
-      global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, CallOptions options);
-      /// <summary>
-      ///  One empty request followed by one empty response.
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One empty request followed by one empty response.
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, CallOptions options);
-      /// <summary>
-      ///  One request followed by one response.
-      /// </summary>
-      global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One request followed by one response.
-      /// </summary>
-      global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options);
-      /// <summary>
-      ///  One request followed by one response.
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One request followed by one response.
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options);
-      /// <summary>
-      ///  One request followed by a sequence of responses (streamed download).
-      ///  The server returns the payload with client desired type and sizes.
-      /// </summary>
-      AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One request followed by a sequence of responses (streamed download).
-      ///  The server returns the payload with client desired type and sizes.
-      /// </summary>
-      AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, CallOptions options);
-      /// <summary>
-      ///  A sequence of requests followed by one response (streamed upload).
-      ///  The server returns the aggregated size of client payload as the result.
-      /// </summary>
-      AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  A sequence of requests followed by one response (streamed upload).
-      ///  The server returns the aggregated size of client payload as the result.
-      /// </summary>
-      AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options);
-      /// <summary>
-      ///  A sequence of requests with each request served by the server immediately.
-      ///  As one request could lead to multiple responses, this interface
-      ///  demonstrates the idea of full duplexing.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  A sequence of requests with each request served by the server immediately.
-      ///  As one request could lead to multiple responses, this interface
-      ///  demonstrates the idea of full duplexing.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options);
-      /// <summary>
-      ///  A sequence of requests followed by a sequence of responses.
-      ///  The server buffers all the client requests and then serves them in order. A
-      ///  stream of responses are returned to the client when the server starts with
-      ///  first request.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  A sequence of requests followed by a sequence of responses.
-      ///  The server buffers all the client requests and then serves them in order. A
-      ///  stream of responses are returned to the client when the server starts with
-      ///  first request.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of TestService</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface ITestService
-    {
-      /// <summary>
-      ///  One empty request followed by one empty response.
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, ServerCallContext context);
-      /// <summary>
-      ///  One request followed by one response.
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context);
-      /// <summary>
-      ///  One request followed by a sequence of responses (streamed download).
-      ///  The server returns the payload with client desired type and sizes.
-      /// </summary>
-      global::System.Threading.Tasks.Task StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
-      /// <summary>
-      ///  A sequence of requests followed by one response (streamed upload).
-      ///  The server returns the aggregated size of client payload as the result.
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<global::Grpc.Testing.StreamingInputCallRequest> requestStream, ServerCallContext context);
-      /// <summary>
-      ///  A sequence of requests with each request served by the server immediately.
-      ///  As one request could lead to multiple responses, this interface
-      ///  demonstrates the idea of full duplexing.
-      /// </summary>
-      global::System.Threading.Tasks.Task FullDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
-      /// <summary>
-      ///  A sequence of requests followed by a sequence of responses.
-      ///  The server buffers all the client requests and then serves them in order. A
-      ///  stream of responses are returned to the client when the server starts with
-      ///  first request.
-      /// </summary>
-      global::System.Threading.Tasks.Task HalfDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of TestService</summary>
     /// <summary>Base class for server-side implementations of TestService</summary>
     public abstract class TestServiceBase
     public abstract class TestServiceBase
     {
     {
@@ -287,9 +166,7 @@ namespace Grpc.Testing {
     }
     }
 
 
     /// <summary>Client for TestService</summary>
     /// <summary>Client for TestService</summary>
-    #pragma warning disable 0618
-    public class TestServiceClient : ClientBase<TestServiceClient>, ITestServiceClient
-    #pragma warning restore 0618
+    public class TestServiceClient : ClientBase<TestServiceClient>
     {
     {
       public TestServiceClient(Channel channel) : base(channel)
       public TestServiceClient(Channel channel) : base(channel)
       {
       {
@@ -445,25 +322,9 @@ namespace Grpc.Testing {
     }
     }
 
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(ITestService serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_EmptyCall, serviceImpl.EmptyCall)
-          .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
-          .AddMethod(__Method_StreamingOutputCall, serviceImpl.StreamingOutputCall)
-          .AddMethod(__Method_StreamingInputCall, serviceImpl.StreamingInputCall)
-          .AddMethod(__Method_FullDuplexCall, serviceImpl.FullDuplexCall)
-          .AddMethod(__Method_HalfDuplexCall, serviceImpl.HalfDuplexCall).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(TestServiceBase serviceImpl)
     public static ServerServiceDefinition BindService(TestServiceBase serviceImpl)
-    #pragma warning restore 0618
     {
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_EmptyCall, serviceImpl.EmptyCall)
           .AddMethod(__Method_EmptyCall, serviceImpl.EmptyCall)
           .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
           .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
           .AddMethod(__Method_StreamingOutputCall, serviceImpl.StreamingOutputCall)
           .AddMethod(__Method_StreamingOutputCall, serviceImpl.StreamingOutputCall)
@@ -496,38 +357,6 @@ namespace Grpc.Testing {
       get { return global::Grpc.Testing.TestReflection.Descriptor.Services[1]; }
       get { return global::Grpc.Testing.TestReflection.Descriptor.Services[1]; }
     }
     }
 
 
-    /// <summary>Client for UnimplementedService</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface IUnimplementedServiceClient
-    {
-      /// <summary>
-      ///  A call that no server should implement
-      /// </summary>
-      global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  A call that no server should implement
-      /// </summary>
-      global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options);
-      /// <summary>
-      ///  A call that no server should implement
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  A call that no server should implement
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of UnimplementedService</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface IUnimplementedService
-    {
-      /// <summary>
-      ///  A call that no server should implement
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of UnimplementedService</summary>
     /// <summary>Base class for server-side implementations of UnimplementedService</summary>
     public abstract class UnimplementedServiceBase
     public abstract class UnimplementedServiceBase
     {
     {
@@ -542,9 +371,7 @@ namespace Grpc.Testing {
     }
     }
 
 
     /// <summary>Client for UnimplementedService</summary>
     /// <summary>Client for UnimplementedService</summary>
-    #pragma warning disable 0618
-    public class UnimplementedServiceClient : ClientBase<UnimplementedServiceClient>, IUnimplementedServiceClient
-    #pragma warning restore 0618
+    public class UnimplementedServiceClient : ClientBase<UnimplementedServiceClient>
     {
     {
       public UnimplementedServiceClient(Channel channel) : base(channel)
       public UnimplementedServiceClient(Channel channel) : base(channel)
       {
       {
@@ -602,20 +429,9 @@ namespace Grpc.Testing {
     }
     }
 
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(IUnimplementedService serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(UnimplementedServiceBase serviceImpl)
     public static ServerServiceDefinition BindService(UnimplementedServiceBase serviceImpl)
-    #pragma warning restore 0618
     {
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build();
           .AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build();
     }
     }
 
 
@@ -651,28 +467,6 @@ namespace Grpc.Testing {
       get { return global::Grpc.Testing.TestReflection.Descriptor.Services[2]; }
       get { return global::Grpc.Testing.TestReflection.Descriptor.Services[2]; }
     }
     }
 
 
-    /// <summary>Client for ReconnectService</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface IReconnectServiceClient
-    {
-      global::Grpc.Testing.Empty Start(global::Grpc.Testing.ReconnectParams request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      global::Grpc.Testing.Empty Start(global::Grpc.Testing.ReconnectParams request, CallOptions options);
-      AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.ReconnectParams request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.ReconnectParams request, CallOptions options);
-      global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, CallOptions options);
-      AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of ReconnectService</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface IReconnectService
-    {
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.ReconnectParams request, ServerCallContext context);
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.ReconnectInfo> Stop(global::Grpc.Testing.Empty request, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of ReconnectService</summary>
     /// <summary>Base class for server-side implementations of ReconnectService</summary>
     public abstract class ReconnectServiceBase
     public abstract class ReconnectServiceBase
     {
     {
@@ -689,9 +483,7 @@ namespace Grpc.Testing {
     }
     }
 
 
     /// <summary>Client for ReconnectService</summary>
     /// <summary>Client for ReconnectService</summary>
-    #pragma warning disable 0618
-    public class ReconnectServiceClient : ClientBase<ReconnectServiceClient>, IReconnectServiceClient
-    #pragma warning restore 0618
+    public class ReconnectServiceClient : ClientBase<ReconnectServiceClient>
     {
     {
       public ReconnectServiceClient(Channel channel) : base(channel)
       public ReconnectServiceClient(Channel channel) : base(channel)
       {
       {
@@ -753,21 +545,9 @@ namespace Grpc.Testing {
     }
     }
 
 
     /// <summary>Creates service definition that can be registered with a server</summary>
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(IReconnectService serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_Start, serviceImpl.Start)
-          .AddMethod(__Method_Stop, serviceImpl.Stop).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(ReconnectServiceBase serviceImpl)
     public static ServerServiceDefinition BindService(ReconnectServiceBase serviceImpl)
-    #pragma warning restore 0618
     {
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_Start, serviceImpl.Start)
           .AddMethod(__Method_Start, serviceImpl.Start)
           .AddMethod(__Method_Stop, serviceImpl.Stop).Build();
           .AddMethod(__Method_Stop, serviceImpl.Stop).Build();
     }
     }

+ 4 - 0
src/csharp/tests.json

@@ -7,6 +7,7 @@
     "Grpc.Core.Internal.Tests.CompletionQueueSafeHandleTest",
     "Grpc.Core.Internal.Tests.CompletionQueueSafeHandleTest",
     "Grpc.Core.Internal.Tests.MetadataArraySafeHandleTest",
     "Grpc.Core.Internal.Tests.MetadataArraySafeHandleTest",
     "Grpc.Core.Internal.Tests.TimespecTest",
     "Grpc.Core.Internal.Tests.TimespecTest",
+    "Grpc.Core.Tests.AppDomainUnloadTest",
     "Grpc.Core.Tests.CallCredentialsTest",
     "Grpc.Core.Tests.CallCredentialsTest",
     "Grpc.Core.Tests.CallOptionsTest",
     "Grpc.Core.Tests.CallOptionsTest",
     "Grpc.Core.Tests.ChannelCredentialsTest",
     "Grpc.Core.Tests.ChannelCredentialsTest",
@@ -25,6 +26,9 @@
     "Grpc.Core.Tests.ResponseHeadersTest",
     "Grpc.Core.Tests.ResponseHeadersTest",
     "Grpc.Core.Tests.SanityTest",
     "Grpc.Core.Tests.SanityTest",
     "Grpc.Core.Tests.ServerTest",
     "Grpc.Core.Tests.ServerTest",
+    "Grpc.Core.Tests.ShutdownHookClientTest",
+    "Grpc.Core.Tests.ShutdownHookPendingCallTest",
+    "Grpc.Core.Tests.ShutdownHookServerTest",
     "Grpc.Core.Tests.ShutdownTest",
     "Grpc.Core.Tests.ShutdownTest",
     "Grpc.Core.Tests.TimeoutsTest",
     "Grpc.Core.Tests.TimeoutsTest",
     "Grpc.Core.Tests.UserAgentStringTest"
     "Grpc.Core.Tests.UserAgentStringTest"

+ 2 - 0
src/objective-c/GRPCClient/GRPCCall+Cronet.h

@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  *
  */
  */
+#ifdef GRPC_COMPILE_WITH_CRONET
 #import <Cronet/Cronet.h>
 #import <Cronet/Cronet.h>
 
 
 #import "GRPCCall.h"
 #import "GRPCCall.h"
@@ -53,3 +54,4 @@
 +(BOOL)isUsingCronet;
 +(BOOL)isUsingCronet;
 
 
 @end
 @end
+#endif

+ 2 - 0
src/objective-c/GRPCClient/GRPCCall+Cronet.m

@@ -33,6 +33,7 @@
 
 
 #import "GRPCCall+Cronet.h"
 #import "GRPCCall+Cronet.h"
 
 
+#ifdef GRPC_COMPILE_WITH_CRONET
 static BOOL useCronet = NO;
 static BOOL useCronet = NO;
 static cronet_engine *globalCronetEngine;
 static cronet_engine *globalCronetEngine;
 
 
@@ -52,3 +53,4 @@ static cronet_engine *globalCronetEngine;
 }
 }
 
 
 @end
 @end
+#endif

+ 2 - 1
src/objective-c/GRPCClient/private/GRPCChannel.h

@@ -58,9 +58,10 @@ struct grpc_channel_credentials;
 /**
 /**
  * Creates a secure channel to the specified @c host using Cronet as a transport mechanism.
  * Creates a secure channel to the specified @c host using Cronet as a transport mechanism.
  */
  */
+#ifdef GRPC_COMPILE_WITH_CRONET
 + (nullable GRPCChannel *)secureCronetChannelWithHost:(NSString *)host
 + (nullable GRPCChannel *)secureCronetChannelWithHost:(NSString *)host
                                           channelArgs:(NSDictionary *)channelArgs;
                                           channelArgs:(NSDictionary *)channelArgs;
-
+#endif
 /**
 /**
  * Creates a secure channel to the specified @c host using the specified @c credentials and
  * Creates a secure channel to the specified @c host using the specified @c credentials and
  * @c channelArgs. Only in tests should @c GRPC_SSL_TARGET_NAME_OVERRIDE_ARG channel arg be set.
  * @c channelArgs. Only in tests should @c GRPC_SSL_TARGET_NAME_OVERRIDE_ARG channel arg be set.

+ 8 - 0
src/objective-c/GRPCClient/private/GRPCChannel.m

@@ -34,13 +34,17 @@
 #import "GRPCChannel.h"
 #import "GRPCChannel.h"
 
 
 #include <grpc/grpc_security.h>
 #include <grpc/grpc_security.h>
+#ifdef GRPC_COMPILE_WITH_CRONET
 #include <grpc/grpc_cronet.h>
 #include <grpc/grpc_cronet.h>
+#endif
 #include <grpc/support/alloc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/string_util.h>
 
 
+#ifdef GRPC_COMPILE_WITH_CRONET
 #import <Cronet/Cronet.h>
 #import <Cronet/Cronet.h>
 #import <GRPCClient/GRPCCall+Cronet.h>
 #import <GRPCClient/GRPCCall+Cronet.h>
+#endif
 #import "GRPCCompletionQueue.h"
 #import "GRPCCompletionQueue.h"
 
 
 void freeChannelArgs(grpc_channel_args *channel_args) {
 void freeChannelArgs(grpc_channel_args *channel_args) {
@@ -102,6 +106,7 @@ grpc_channel_args * buildChannelArgs(NSDictionary *dictionary) {
   grpc_channel_args *_channelArgs;
   grpc_channel_args *_channelArgs;
 }
 }
 
 
+#ifdef GRPC_COMPILE_WITH_CRONET
 - (instancetype)initWithHost:(NSString *)host
 - (instancetype)initWithHost:(NSString *)host
                 cronetEngine:(cronet_engine *)cronetEngine
                 cronetEngine:(cronet_engine *)cronetEngine
                  channelArgs:(NSDictionary *)channelArgs {
                  channelArgs:(NSDictionary *)channelArgs {
@@ -118,6 +123,7 @@ grpc_channel_args * buildChannelArgs(NSDictionary *dictionary) {
 
 
   return self;
   return self;
 }
 }
+#endif
 
 
 - (instancetype)initWithHost:(NSString *)host
 - (instancetype)initWithHost:(NSString *)host
                       secure:(BOOL)secure
                       secure:(BOOL)secure
@@ -152,6 +158,7 @@ grpc_channel_args * buildChannelArgs(NSDictionary *dictionary) {
   freeChannelArgs(_channelArgs);
   freeChannelArgs(_channelArgs);
 }
 }
 
 
+#ifdef GRPC_COMPILE_WITH_CRONET
 + (GRPCChannel *)secureCronetChannelWithHost:(NSString *)host
 + (GRPCChannel *)secureCronetChannelWithHost:(NSString *)host
                                  channelArgs:(NSDictionary *)channelArgs {
                                  channelArgs:(NSDictionary *)channelArgs {
   cronet_engine *engine = [GRPCCall cronetEngine];
   cronet_engine *engine = [GRPCCall cronetEngine];
@@ -162,6 +169,7 @@ grpc_channel_args * buildChannelArgs(NSDictionary *dictionary) {
   }
   }
   return [[GRPCChannel alloc] initWithHost:host cronetEngine:engine channelArgs:channelArgs];
   return [[GRPCChannel alloc] initWithHost:host cronetEngine:engine channelArgs:channelArgs];
 }
 }
+#endif
 
 
 + (GRPCChannel *)secureChannelWithHost:(NSString *)host {
 + (GRPCChannel *)secureChannelWithHost:(NSString *)host {
   return [[GRPCChannel alloc] initWithHost:host secure:YES credentials:NULL channelArgs:NULL];
   return [[GRPCChannel alloc] initWithHost:host secure:YES credentials:NULL channelArgs:NULL];

+ 8 - 1
src/objective-c/GRPCClient/private/GRPCHost.m

@@ -36,8 +36,10 @@
 #include <grpc/grpc.h>
 #include <grpc/grpc.h>
 #include <grpc/grpc_security.h>
 #include <grpc/grpc_security.h>
 #import <GRPCClient/GRPCCall.h>
 #import <GRPCClient/GRPCCall.h>
+#ifdef GRPC_COMPILE_WITH_CRONET
 #import <GRPCClient/GRPCCall+ChannelArg.h>
 #import <GRPCClient/GRPCCall+ChannelArg.h>
 #import <GRPCClient/GRPCCall+Cronet.h>
 #import <GRPCClient/GRPCCall+Cronet.h>
+#endif
 
 
 #import "GRPCChannel.h"
 #import "GRPCChannel.h"
 #import "GRPCCompletionQueue.h"
 #import "GRPCCompletionQueue.h"
@@ -201,17 +203,22 @@ NS_ASSUME_NONNULL_BEGIN
 
 
 - (GRPCChannel *)newChannel {
 - (GRPCChannel *)newChannel {
   NSDictionary *args = [self channelArgs];
   NSDictionary *args = [self channelArgs];
+#ifdef GRPC_COMPILE_WITH_CRONET
   BOOL useCronet = [GRPCCall isUsingCronet];
   BOOL useCronet = [GRPCCall isUsingCronet];
+#endif
   if (_secure) {
   if (_secure) {
       GRPCChannel *channel;
       GRPCChannel *channel;
       @synchronized(self) {
       @synchronized(self) {
         if (_channelCreds == nil) {
         if (_channelCreds == nil) {
           [self setTLSPEMRootCerts:nil withPrivateKey:nil withCertChain:nil error:nil];
           [self setTLSPEMRootCerts:nil withPrivateKey:nil withCertChain:nil error:nil];
         }
         }
+#ifdef GRPC_COMPILE_WITH_CRONET
         if (useCronet) {
         if (useCronet) {
           channel = [GRPCChannel secureCronetChannelWithHost:_address
           channel = [GRPCChannel secureCronetChannelWithHost:_address
                                                  channelArgs:args];
                                                  channelArgs:args];
-        } else {
+        } else
+#endif
+        {
           channel = [GRPCChannel secureChannelWithHost:_address
           channel = [GRPCChannel secureChannelWithHost:_address
                                             credentials:_channelCreds
                                             credentials:_channelCreds
                                             channelArgs:args];
                                             channelArgs:args];

+ 3 - 3
src/proto/math/math.proto

@@ -55,8 +55,8 @@ message FibReply {
 }
 }
 
 
 service Math {
 service Math {
-  // Div divides args.dividend by args.divisor and returns the quotient and
-  // remainder.
+  // Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+  // and remainder.
   rpc Div (DivArgs) returns (DivReply) {
   rpc Div (DivArgs) returns (DivReply) {
   }
   }
 
 
@@ -67,7 +67,7 @@ service Math {
   rpc DivMany (stream DivArgs) returns (stream DivReply) {
   rpc DivMany (stream DivArgs) returns (stream DivReply) {
   }
   }
 
 
-  // Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
+  // Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
   // generates up to limit numbers; otherwise it continues until the call is
   // generates up to limit numbers; otherwise it continues until the call is
   // canceled.  Unlike Fib above, Fib has no final FibReply.
   // canceled.  Unlike Fib above, Fib has no final FibReply.
   rpc Fib (FibArgs) returns (stream Num) {
   rpc Fib (FibArgs) returns (stream Num) {

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác