Browse Source

Merge branch 'grand-unified-closures' into who-combines-the-combiners

Craig Tiller 9 years ago
parent
commit
56f21aa79c
100 changed files with 2799 additions and 1527 deletions
  1. 415 62
      BUILD
  2. 243 51
      CMakeLists.txt
  3. 256 61
      Makefile
  4. 1 1
      PYTHON-MANIFEST.in
  5. 10 10
      README.md
  6. 2 2
      binding.gyp
  7. 17 12
      build.yaml
  8. 2 2
      config.m4
  9. 20 2
      doc/PROTOCOL-HTTP2.md
  10. 1 15
      doc/fail_fast.md
  11. 8 0
      doc/g_stands_for.md
  12. 14 0
      doc/wait-for-ready.md
  13. 8 5
      examples/objective-c/auth_sample/AuthTestService.podspec
  14. 8 5
      examples/objective-c/helloworld/HelloWorld.podspec
  15. 8 5
      examples/objective-c/route_guide/RouteGuide.podspec
  16. 1 2
      examples/php/composer.json
  17. 1 1
      examples/php/run_greeter_client.sh
  18. 10 10
      gRPC-Core.podspec
  19. 5 3
      gRPC-ProtoRPC.podspec
  20. 2 2
      gRPC-RxLibrary.podspec
  21. 7 2
      gRPC.podspec
  22. 1 0
      grpc.def
  23. 5 5
      grpc.gemspec
  24. 0 1
      include/grpc++/create_channel.h
  25. 4 0
      include/grpc++/grpc++.h
  26. 5 1
      include/grpc++/impl/codegen/client_context.h
  27. 4 0
      include/grpc++/impl/codegen/server_context.h
  28. 30 7
      include/grpc++/impl/codegen/sync_stream.h
  29. 5 0
      include/grpc++/impl/server_builder_plugin.h
  30. 3 0
      include/grpc/grpc.h
  31. 7 3
      include/grpc/impl/codegen/grpc_types.h
  32. 39 9
      package.xml
  33. 19 18
      setup.py
  34. 4 0
      src/core/ext/census/gen/README.md
  35. 81 0
      src/core/ext/census/gen/trace_context.pb.c
  36. 99 0
      src/core/ext/census/gen/trace_context.pb.h
  37. 2 2
      src/core/ext/client_config/README.md
  38. 395 146
      src/core/ext/client_config/client_channel.c
  39. 0 2
      src/core/ext/client_config/lb_policy_factory.h
  40. 2 2
      src/core/ext/client_config/resolver.c
  41. 6 6
      src/core/ext/client_config/resolver.h
  42. 1 1
      src/core/ext/client_config/resolver_factory.h
  43. 12 11
      src/core/ext/client_config/resolver_result.c
  44. 13 14
      src/core/ext/client_config/resolver_result.h
  45. 0 296
      src/core/ext/client_config/subchannel_call_holder.c
  46. 0 99
      src/core/ext/client_config/subchannel_call_holder.h
  47. 21 21
      src/core/ext/resolver/dns/native/dns_resolver.c
  48. 9 9
      src/core/ext/resolver/sockaddr/sockaddr_resolver.c
  49. 170 12
      src/core/lib/channel/http_client_filter.c
  50. 3 0
      src/core/lib/channel/http_client_filter.h
  51. 77 2
      src/core/lib/channel/http_server_filter.c
  52. 3 0
      src/core/lib/iomgr/combiner.c
  53. 7 5
      src/core/lib/iomgr/combiner.h
  54. 2 1
      src/core/lib/iomgr/error.h
  55. 5 1
      src/core/lib/iomgr/ev_epoll_linux.c
  56. 3 1
      src/core/lib/iomgr/tcp_server_posix.c
  57. 6 0
      src/core/lib/security/context/security_context.c
  58. 12 0
      src/core/lib/security/context/security_context.h
  59. 7 4
      src/core/lib/support/mpscq.c
  60. 2 2
      src/core/lib/support/mpscq.h
  61. 8 3
      src/core/lib/surface/server.c
  62. 2 0
      src/core/lib/surface/version.c
  63. 8 7
      src/core/lib/transport/static_metadata.c
  64. 50 48
      src/core/lib/transport/static_metadata.h
  65. 1 0
      src/core/lib/transport/transport.h
  66. 5 2
      src/cpp/common/channel_filter.h
  67. 6 9
      src/cpp/server/server_builder.cc
  68. 2 2
      src/cpp/util/byte_buffer.cc
  69. 3 4
      src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
  70. 262 252
      src/objective-c/BoringSSL.podspec
  71. 1 1
      src/objective-c/GRPCClient/private/GRPCHost.m
  72. 8 5
      src/objective-c/README.md
  73. 3 5
      src/objective-c/RxLibrary/transformations/GRXMappingWriter.m
  74. 8 5
      src/objective-c/examples/RemoteTestClient/RemoteTest.podspec
  75. 8 5
      src/objective-c/tests/RemoteTestClient/RemoteTest.podspec
  76. 1 1
      src/php/composer.json
  77. 3 0
      src/php/ext/grpc/call.c
  78. 6 14
      src/php/ext/grpc/call_credentials.c
  79. 24 13
      src/php/lib/Grpc/AbstractCall.php
  80. 5 5
      src/php/lib/Grpc/BidiStreamingCall.php
  81. 3 3
      src/php/lib/Grpc/ClientStreamingCall.php
  82. 6 6
      src/php/lib/Grpc/ServerStreamingCall.php
  83. 2 2
      src/php/lib/Grpc/UnaryCall.php
  84. 23 14
      src/php/tests/interop/interop_client.php
  85. 65 0
      src/php/tests/unit_tests/CallCredentials2Test.php
  86. 0 135
      src/php/tests/unit_tests/CallCredentials3Test.php
  87. 23 1
      src/php/tests/unit_tests/CallTest.php
  88. 0 0
      src/proto/census/trace_context.options
  89. 48 0
      src/proto/census/trace_context.proto
  90. 29 33
      src/python/grpcio/_spawn_patch.py
  91. 2 2
      src/python/grpcio/grpc_core_dependencies.py
  92. 2 2
      src/python/grpcio_health_checking/setup.py
  93. 3 7
      src/python/grpcio_tests/setup.py
  94. 0 3
      src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
  95. 2 0
      src/ruby/ext/grpc/rb_grpc_imports.generated.c
  96. 3 0
      src/ruby/ext/grpc/rb_grpc_imports.generated.h
  97. 65 0
      summerofcode/2016/siddharth_shukla.md
  98. 2 0
      templates/BUILD.template
  99. 1 1
      templates/Makefile.template
  100. 3 3
      templates/gRPC-Core.podspec.template

+ 415 - 62
BUILD

@@ -36,6 +36,8 @@
 
 
 licenses(["notice"])  # 3-clause BSD
 licenses(["notice"])  # 3-clause BSD
 
 
+exports_files(["LICENSE"])
+
 package(default_visibility = ["//visibility:public"])
 package(default_visibility = ["//visibility:public"])
 
 
 
 
@@ -289,7 +291,6 @@ cc_library(
     "src/core/lib/tsi/transport_security_interface.h",
     "src/core/lib/tsi/transport_security_interface.h",
     "src/core/ext/client_config/client_channel.h",
     "src/core/ext/client_config/client_channel.h",
     "src/core/ext/client_config/client_channel_factory.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/connector.h",
     "src/core/ext/client_config/initial_connect_string.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.h",
@@ -299,8 +300,8 @@ cc_library(
     "src/core/ext/client_config/resolver.h",
     "src/core/ext/client_config/resolver.h",
     "src/core/ext/client_config/resolver_factory.h",
     "src/core/ext/client_config/resolver_factory.h",
     "src/core/ext/client_config/resolver_registry.h",
     "src/core/ext/client_config/resolver_registry.h",
+    "src/core/ext/client_config/resolver_result.h",
     "src/core/ext/client_config/subchannel.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/subchannel_index.h",
     "src/core/ext/client_config/uri_parser.h",
     "src/core/ext/client_config/uri_parser.h",
     "src/core/ext/lb_policy/grpclb/grpclb.h",
     "src/core/ext/lb_policy/grpclb/grpclb.h",
@@ -313,6 +314,7 @@ cc_library(
     "src/core/ext/census/census_interface.h",
     "src/core/ext/census/census_interface.h",
     "src/core/ext/census/census_rpc_stats.h",
     "src/core/ext/census/census_rpc_stats.h",
     "src/core/ext/census/gen/census.pb.h",
     "src/core/ext/census/gen/census.pb.h",
+    "src/core/ext/census/gen/trace_context.pb.h",
     "src/core/ext/census/grpc_filter.h",
     "src/core/ext/census/grpc_filter.h",
     "src/core/ext/census/mlog.h",
     "src/core/ext/census/mlog.h",
     "src/core/ext/census/resource.h",
     "src/core/ext/census/resource.h",
@@ -463,7 +465,6 @@ cc_library(
     "src/core/ext/client_config/channel_connectivity.c",
     "src/core/ext/client_config/channel_connectivity.c",
     "src/core/ext/client_config/client_channel.c",
     "src/core/ext/client_config/client_channel.c",
     "src/core/ext/client_config/client_channel_factory.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/client_config_plugin.c",
     "src/core/ext/client_config/connector.c",
     "src/core/ext/client_config/connector.c",
     "src/core/ext/client_config/default_initial_connect_string.c",
     "src/core/ext/client_config/default_initial_connect_string.c",
@@ -475,8 +476,8 @@ cc_library(
     "src/core/ext/client_config/resolver.c",
     "src/core/ext/client_config/resolver.c",
     "src/core/ext/client_config/resolver_factory.c",
     "src/core/ext/client_config/resolver_factory.c",
     "src/core/ext/client_config/resolver_registry.c",
     "src/core/ext/client_config/resolver_registry.c",
+    "src/core/ext/client_config/resolver_result.c",
     "src/core/ext/client_config/subchannel.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/subchannel_index.c",
     "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",
@@ -495,6 +496,7 @@ cc_library(
     "src/core/ext/census/base_resources.c",
     "src/core/ext/census/base_resources.c",
     "src/core/ext/census/context.c",
     "src/core/ext/census/context.c",
     "src/core/ext/census/gen/census.pb.c",
     "src/core/ext/census/gen/census.pb.c",
+    "src/core/ext/census/gen/trace_context.pb.c",
     "src/core/ext/census/grpc_context.c",
     "src/core/ext/census/grpc_context.c",
     "src/core/ext/census/grpc_filter.c",
     "src/core/ext/census/grpc_filter.c",
     "src/core/ext/census/grpc_plugin.c",
     "src/core/ext/census/grpc_plugin.c",
@@ -512,6 +514,7 @@ cc_library(
     "include/grpc/compression.h",
     "include/grpc/compression.h",
     "include/grpc/grpc.h",
     "include/grpc/grpc.h",
     "include/grpc/grpc_posix.h",
     "include/grpc/grpc_posix.h",
+    "include/grpc/grpc_security_constants.h",
     "include/grpc/status.h",
     "include/grpc/status.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
@@ -535,7 +538,6 @@ cc_library(
     "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_security.h",
     "include/grpc/grpc_security.h",
-    "include/grpc/grpc_security_constants.h",
     "include/grpc/census.h",
     "include/grpc/census.h",
   ],
   ],
   includes = [
   includes = [
@@ -663,7 +665,6 @@ cc_library(
     "src/core/ext/transport/chttp2/alpn/alpn.h",
     "src/core/ext/transport/chttp2/alpn/alpn.h",
     "src/core/ext/client_config/client_channel.h",
     "src/core/ext/client_config/client_channel.h",
     "src/core/ext/client_config/client_channel_factory.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/connector.h",
     "src/core/ext/client_config/initial_connect_string.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.h",
@@ -673,8 +674,8 @@ cc_library(
     "src/core/ext/client_config/resolver.h",
     "src/core/ext/client_config/resolver.h",
     "src/core/ext/client_config/resolver_factory.h",
     "src/core/ext/client_config/resolver_factory.h",
     "src/core/ext/client_config/resolver_registry.h",
     "src/core/ext/client_config/resolver_registry.h",
+    "src/core/ext/client_config/resolver_result.h",
     "src/core/ext/client_config/subchannel.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/subchannel_index.h",
     "src/core/ext/client_config/uri_parser.h",
     "src/core/ext/client_config/uri_parser.h",
     "src/core/lib/security/context/security_context.h",
     "src/core/lib/security/context/security_context.h",
@@ -821,7 +822,6 @@ cc_library(
     "src/core/ext/client_config/channel_connectivity.c",
     "src/core/ext/client_config/channel_connectivity.c",
     "src/core/ext/client_config/client_channel.c",
     "src/core/ext/client_config/client_channel.c",
     "src/core/ext/client_config/client_channel_factory.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/client_config_plugin.c",
     "src/core/ext/client_config/connector.c",
     "src/core/ext/client_config/connector.c",
     "src/core/ext/client_config/default_initial_connect_string.c",
     "src/core/ext/client_config/default_initial_connect_string.c",
@@ -833,8 +833,8 @@ cc_library(
     "src/core/ext/client_config/resolver.c",
     "src/core/ext/client_config/resolver.c",
     "src/core/ext/client_config/resolver_factory.c",
     "src/core/ext/client_config/resolver_factory.c",
     "src/core/ext/client_config/resolver_registry.c",
     "src/core/ext/client_config/resolver_registry.c",
+    "src/core/ext/client_config/resolver_result.c",
     "src/core/ext/client_config/subchannel.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/subchannel_index.c",
     "src/core/ext/client_config/uri_parser.c",
     "src/core/ext/client_config/uri_parser.c",
     "src/core/lib/http/httpcli_security_connector.c",
     "src/core/lib/http/httpcli_security_connector.c",
@@ -873,6 +873,7 @@ cc_library(
     "include/grpc/compression.h",
     "include/grpc/compression.h",
     "include/grpc/grpc.h",
     "include/grpc/grpc.h",
     "include/grpc/grpc_posix.h",
     "include/grpc/grpc_posix.h",
+    "include/grpc/grpc_security_constants.h",
     "include/grpc/status.h",
     "include/grpc/status.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
@@ -897,7 +898,6 @@ cc_library(
     "include/grpc/impl/codegen/time.h",
     "include/grpc/impl/codegen/time.h",
     "include/grpc/grpc_cronet.h",
     "include/grpc/grpc_cronet.h",
     "include/grpc/grpc_security.h",
     "include/grpc/grpc_security.h",
-    "include/grpc/grpc_security_constants.h",
   ],
   ],
   includes = [
   includes = [
     "include",
     "include",
@@ -1018,7 +1018,6 @@ cc_library(
     "src/core/ext/transport/chttp2/alpn/alpn.h",
     "src/core/ext/transport/chttp2/alpn/alpn.h",
     "src/core/ext/client_config/client_channel.h",
     "src/core/ext/client_config/client_channel.h",
     "src/core/ext/client_config/client_channel_factory.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/connector.h",
     "src/core/ext/client_config/initial_connect_string.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.h",
@@ -1028,8 +1027,8 @@ cc_library(
     "src/core/ext/client_config/resolver.h",
     "src/core/ext/client_config/resolver.h",
     "src/core/ext/client_config/resolver_factory.h",
     "src/core/ext/client_config/resolver_factory.h",
     "src/core/ext/client_config/resolver_registry.h",
     "src/core/ext/client_config/resolver_registry.h",
+    "src/core/ext/client_config/resolver_result.h",
     "src/core/ext/client_config/subchannel.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/subchannel_index.h",
     "src/core/ext/client_config/uri_parser.h",
     "src/core/ext/client_config/uri_parser.h",
     "src/core/ext/load_reporting/load_reporting.h",
     "src/core/ext/load_reporting/load_reporting.h",
@@ -1042,6 +1041,7 @@ cc_library(
     "src/core/ext/census/census_interface.h",
     "src/core/ext/census/census_interface.h",
     "src/core/ext/census/census_rpc_stats.h",
     "src/core/ext/census/census_rpc_stats.h",
     "src/core/ext/census/gen/census.pb.h",
     "src/core/ext/census/gen/census.pb.h",
+    "src/core/ext/census/gen/trace_context.pb.h",
     "src/core/ext/census/grpc_filter.h",
     "src/core/ext/census/grpc_filter.h",
     "src/core/ext/census/mlog.h",
     "src/core/ext/census/mlog.h",
     "src/core/ext/census/resource.h",
     "src/core/ext/census/resource.h",
@@ -1167,7 +1167,6 @@ cc_library(
     "src/core/ext/client_config/channel_connectivity.c",
     "src/core/ext/client_config/channel_connectivity.c",
     "src/core/ext/client_config/client_channel.c",
     "src/core/ext/client_config/client_channel.c",
     "src/core/ext/client_config/client_channel_factory.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/client_config_plugin.c",
     "src/core/ext/client_config/connector.c",
     "src/core/ext/client_config/connector.c",
     "src/core/ext/client_config/default_initial_connect_string.c",
     "src/core/ext/client_config/default_initial_connect_string.c",
@@ -1179,8 +1178,8 @@ cc_library(
     "src/core/ext/client_config/resolver.c",
     "src/core/ext/client_config/resolver.c",
     "src/core/ext/client_config/resolver_factory.c",
     "src/core/ext/client_config/resolver_factory.c",
     "src/core/ext/client_config/resolver_registry.c",
     "src/core/ext/client_config/resolver_registry.c",
+    "src/core/ext/client_config/resolver_result.c",
     "src/core/ext/client_config/subchannel.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/subchannel_index.c",
     "src/core/ext/client_config/uri_parser.c",
     "src/core/ext/client_config/uri_parser.c",
     "src/core/ext/resolver/dns/native/dns_resolver.c",
     "src/core/ext/resolver/dns/native/dns_resolver.c",
@@ -1195,6 +1194,7 @@ cc_library(
     "src/core/ext/census/base_resources.c",
     "src/core/ext/census/base_resources.c",
     "src/core/ext/census/context.c",
     "src/core/ext/census/context.c",
     "src/core/ext/census/gen/census.pb.c",
     "src/core/ext/census/gen/census.pb.c",
+    "src/core/ext/census/gen/trace_context.pb.c",
     "src/core/ext/census/grpc_context.c",
     "src/core/ext/census/grpc_context.c",
     "src/core/ext/census/grpc_filter.c",
     "src/core/ext/census/grpc_filter.c",
     "src/core/ext/census/grpc_plugin.c",
     "src/core/ext/census/grpc_plugin.c",
@@ -1212,6 +1212,7 @@ cc_library(
     "include/grpc/compression.h",
     "include/grpc/compression.h",
     "include/grpc/grpc.h",
     "include/grpc/grpc.h",
     "include/grpc/grpc_posix.h",
     "include/grpc/grpc_posix.h",
+    "include/grpc/grpc_security_constants.h",
     "include/grpc/status.h",
     "include/grpc/status.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
@@ -1262,6 +1263,86 @@ cc_library(
     "src/cpp/common/channel_filter.h",
     "src/cpp/common/channel_filter.h",
     "src/cpp/server/dynamic_thread_pool.h",
     "src/cpp/server/dynamic_thread_pool.h",
     "src/cpp/server/thread_pool_interface.h",
     "src/cpp/server/thread_pool_interface.h",
+    "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/handshaker.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/error.h",
+    "src/core/lib/iomgr/ev_epoll_linux.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/load_file.h",
+    "src/core/lib/iomgr/network_status_tracker.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/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/timeout_encoding.h",
+    "src/core/lib/transport/transport.h",
+    "src/core/lib/transport/transport_impl.h",
     "src/cpp/client/secure_credentials.cc",
     "src/cpp/client/secure_credentials.cc",
     "src/cpp/common/auth_property_iterator.cc",
     "src/cpp/common/auth_property_iterator.cc",
     "src/cpp/common/secure_auth_context.cc",
     "src/cpp/common/secure_auth_context.cc",
@@ -1295,6 +1376,95 @@ cc_library(
     "src/cpp/util/status.cc",
     "src/cpp/util/status.cc",
     "src/cpp/util/string_ref.cc",
     "src/cpp/util/string_ref.cc",
     "src/cpp/util/time.cc",
     "src/cpp/util/time.cc",
+    "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/handshaker.c",
+    "src/core/lib/channel/http_client_filter.c",
+    "src/core/lib/channel/http_server_filter.c",
+    "src/core/lib/compression/compression.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/error.c",
+    "src/core/lib/iomgr/ev_epoll_linux.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/load_file.c",
+    "src/core/lib/iomgr/network_status_tracker.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/timeout_encoding.c",
+    "src/core/lib/transport/transport.c",
+    "src/core/lib/transport/transport_op_string.c",
     "src/cpp/codegen/codegen_init.cc",
     "src/cpp/codegen/codegen_init.cc",
   ],
   ],
   hdrs = [
   hdrs = [
@@ -1345,6 +1515,34 @@ cc_library(
     "include/grpc++/support/stub_options.h",
     "include/grpc++/support/stub_options.h",
     "include/grpc++/support/sync_stream.h",
     "include/grpc++/support/sync_stream.h",
     "include/grpc++/support/time.h",
     "include/grpc++/support/time.h",
+    "include/grpc/byte_buffer.h",
+    "include/grpc/byte_buffer_reader.h",
+    "include/grpc/compression.h",
+    "include/grpc/grpc.h",
+    "include/grpc/grpc_posix.h",
+    "include/grpc/grpc_security_constants.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++/impl/codegen/async_stream.h",
     "include/grpc++/impl/codegen/async_stream.h",
     "include/grpc++/impl/codegen/async_unary_call.h",
     "include/grpc++/impl/codegen/async_unary_call.h",
     "include/grpc++/impl/codegen/call.h",
     "include/grpc++/impl/codegen/call.h",
@@ -1375,27 +1573,6 @@ cc_library(
     "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",
-    "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",
   ],
   ],
   includes = [
   includes = [
     "include",
     "include",
@@ -1405,6 +1582,7 @@ cc_library(
     "//external:libssl",
     "//external:libssl",
     "//external:protobuf_clib",
     "//external:protobuf_clib",
     ":grpc",
     ":grpc",
+    ":gpr",
   ],
   ],
 )
 )
 
 
@@ -1495,6 +1673,86 @@ cc_library(
     "src/cpp/common/channel_filter.h",
     "src/cpp/common/channel_filter.h",
     "src/cpp/server/dynamic_thread_pool.h",
     "src/cpp/server/dynamic_thread_pool.h",
     "src/cpp/server/thread_pool_interface.h",
     "src/cpp/server/thread_pool_interface.h",
+    "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/handshaker.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/error.h",
+    "src/core/lib/iomgr/ev_epoll_linux.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/load_file.h",
+    "src/core/lib/iomgr/network_status_tracker.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/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/timeout_encoding.h",
+    "src/core/lib/transport/transport.h",
+    "src/core/lib/transport/transport_impl.h",
     "src/cpp/common/insecure_create_auth_context.cc",
     "src/cpp/common/insecure_create_auth_context.cc",
     "src/cpp/client/channel.cc",
     "src/cpp/client/channel.cc",
     "src/cpp/client/client_context.cc",
     "src/cpp/client/client_context.cc",
@@ -1523,6 +1781,95 @@ cc_library(
     "src/cpp/util/status.cc",
     "src/cpp/util/status.cc",
     "src/cpp/util/string_ref.cc",
     "src/cpp/util/string_ref.cc",
     "src/cpp/util/time.cc",
     "src/cpp/util/time.cc",
+    "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/handshaker.c",
+    "src/core/lib/channel/http_client_filter.c",
+    "src/core/lib/channel/http_server_filter.c",
+    "src/core/lib/compression/compression.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/error.c",
+    "src/core/lib/iomgr/ev_epoll_linux.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/load_file.c",
+    "src/core/lib/iomgr/network_status_tracker.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/timeout_encoding.c",
+    "src/core/lib/transport/transport.c",
+    "src/core/lib/transport/transport_op_string.c",
     "src/cpp/codegen/codegen_init.cc",
     "src/cpp/codegen/codegen_init.cc",
   ],
   ],
   hdrs = [
   hdrs = [
@@ -1573,6 +1920,34 @@ cc_library(
     "include/grpc++/support/stub_options.h",
     "include/grpc++/support/stub_options.h",
     "include/grpc++/support/sync_stream.h",
     "include/grpc++/support/sync_stream.h",
     "include/grpc++/support/time.h",
     "include/grpc++/support/time.h",
+    "include/grpc/byte_buffer.h",
+    "include/grpc/byte_buffer_reader.h",
+    "include/grpc/compression.h",
+    "include/grpc/grpc.h",
+    "include/grpc/grpc_posix.h",
+    "include/grpc/grpc_security_constants.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++/impl/codegen/async_stream.h",
     "include/grpc++/impl/codegen/async_stream.h",
     "include/grpc++/impl/codegen/async_unary_call.h",
     "include/grpc++/impl/codegen/async_unary_call.h",
     "include/grpc++/impl/codegen/call.h",
     "include/grpc++/impl/codegen/call.h",
@@ -1603,27 +1978,6 @@ cc_library(
     "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",
-    "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",
   ],
   ],
   includes = [
   includes = [
     "include",
     "include",
@@ -1633,7 +1987,6 @@ cc_library(
     "//external:protobuf_clib",
     "//external:protobuf_clib",
     ":gpr",
     ":gpr",
     ":grpc_unsecure",
     ":grpc_unsecure",
-    ":grpc",
   ],
   ],
 )
 )
 
 
@@ -1963,7 +2316,6 @@ objc_library(
     "src/core/ext/client_config/channel_connectivity.c",
     "src/core/ext/client_config/channel_connectivity.c",
     "src/core/ext/client_config/client_channel.c",
     "src/core/ext/client_config/client_channel.c",
     "src/core/ext/client_config/client_channel_factory.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/client_config_plugin.c",
     "src/core/ext/client_config/connector.c",
     "src/core/ext/client_config/connector.c",
     "src/core/ext/client_config/default_initial_connect_string.c",
     "src/core/ext/client_config/default_initial_connect_string.c",
@@ -1975,8 +2327,8 @@ objc_library(
     "src/core/ext/client_config/resolver.c",
     "src/core/ext/client_config/resolver.c",
     "src/core/ext/client_config/resolver_factory.c",
     "src/core/ext/client_config/resolver_factory.c",
     "src/core/ext/client_config/resolver_registry.c",
     "src/core/ext/client_config/resolver_registry.c",
+    "src/core/ext/client_config/resolver_result.c",
     "src/core/ext/client_config/subchannel.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/subchannel_index.c",
     "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",
@@ -1995,6 +2347,7 @@ objc_library(
     "src/core/ext/census/base_resources.c",
     "src/core/ext/census/base_resources.c",
     "src/core/ext/census/context.c",
     "src/core/ext/census/context.c",
     "src/core/ext/census/gen/census.pb.c",
     "src/core/ext/census/gen/census.pb.c",
+    "src/core/ext/census/gen/trace_context.pb.c",
     "src/core/ext/census/grpc_context.c",
     "src/core/ext/census/grpc_context.c",
     "src/core/ext/census/grpc_filter.c",
     "src/core/ext/census/grpc_filter.c",
     "src/core/ext/census/grpc_plugin.c",
     "src/core/ext/census/grpc_plugin.c",
@@ -2012,6 +2365,7 @@ objc_library(
     "include/grpc/compression.h",
     "include/grpc/compression.h",
     "include/grpc/grpc.h",
     "include/grpc/grpc.h",
     "include/grpc/grpc_posix.h",
     "include/grpc/grpc_posix.h",
+    "include/grpc/grpc_security_constants.h",
     "include/grpc/status.h",
     "include/grpc/status.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
@@ -2035,7 +2389,6 @@ objc_library(
     "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_security.h",
     "include/grpc/grpc_security.h",
-    "include/grpc/grpc_security_constants.h",
     "include/grpc/census.h",
     "include/grpc/census.h",
     "src/core/lib/channel/channel_args.h",
     "src/core/lib/channel/channel_args.h",
     "src/core/lib/channel/channel_stack.h",
     "src/core/lib/channel/channel_stack.h",
@@ -2165,7 +2518,6 @@ objc_library(
     "src/core/lib/tsi/transport_security_interface.h",
     "src/core/lib/tsi/transport_security_interface.h",
     "src/core/ext/client_config/client_channel.h",
     "src/core/ext/client_config/client_channel.h",
     "src/core/ext/client_config/client_channel_factory.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/connector.h",
     "src/core/ext/client_config/initial_connect_string.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.h",
@@ -2175,8 +2527,8 @@ objc_library(
     "src/core/ext/client_config/resolver.h",
     "src/core/ext/client_config/resolver.h",
     "src/core/ext/client_config/resolver_factory.h",
     "src/core/ext/client_config/resolver_factory.h",
     "src/core/ext/client_config/resolver_registry.h",
     "src/core/ext/client_config/resolver_registry.h",
+    "src/core/ext/client_config/resolver_result.h",
     "src/core/ext/client_config/subchannel.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/subchannel_index.h",
     "src/core/ext/client_config/uri_parser.h",
     "src/core/ext/client_config/uri_parser.h",
     "src/core/ext/lb_policy/grpclb/grpclb.h",
     "src/core/ext/lb_policy/grpclb/grpclb.h",
@@ -2189,6 +2541,7 @@ objc_library(
     "src/core/ext/census/census_interface.h",
     "src/core/ext/census/census_interface.h",
     "src/core/ext/census/census_rpc_stats.h",
     "src/core/ext/census/census_rpc_stats.h",
     "src/core/ext/census/gen/census.pb.h",
     "src/core/ext/census/gen/census.pb.h",
+    "src/core/ext/census/gen/trace_context.pb.h",
     "src/core/ext/census/grpc_filter.h",
     "src/core/ext/census/grpc_filter.h",
     "src/core/ext/census/mlog.h",
     "src/core/ext/census/mlog.h",
     "src/core/ext/census/resource.h",
     "src/core/ext/census/resource.h",

+ 243 - 51
CMakeLists.txt

@@ -437,7 +437,6 @@ add_library(grpc
   src/core/ext/client_config/channel_connectivity.c
   src/core/ext/client_config/channel_connectivity.c
   src/core/ext/client_config/client_channel.c
   src/core/ext/client_config/client_channel.c
   src/core/ext/client_config/client_channel_factory.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/client_config_plugin.c
   src/core/ext/client_config/connector.c
   src/core/ext/client_config/connector.c
   src/core/ext/client_config/default_initial_connect_string.c
   src/core/ext/client_config/default_initial_connect_string.c
@@ -449,8 +448,8 @@ add_library(grpc
   src/core/ext/client_config/resolver.c
   src/core/ext/client_config/resolver.c
   src/core/ext/client_config/resolver_factory.c
   src/core/ext/client_config/resolver_factory.c
   src/core/ext/client_config/resolver_registry.c
   src/core/ext/client_config/resolver_registry.c
+  src/core/ext/client_config/resolver_result.c
   src/core/ext/client_config/subchannel.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/subchannel_index.c
   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
@@ -472,6 +471,7 @@ add_library(grpc
   src/core/ext/census/base_resources.c
   src/core/ext/census/base_resources.c
   src/core/ext/census/context.c
   src/core/ext/census/context.c
   src/core/ext/census/gen/census.pb.c
   src/core/ext/census/gen/census.pb.c
+  src/core/ext/census/gen/trace_context.pb.c
   src/core/ext/census/grpc_context.c
   src/core/ext/census/grpc_context.c
   src/core/ext/census/grpc_filter.c
   src/core/ext/census/grpc_filter.c
   src/core/ext/census/grpc_plugin.c
   src/core/ext/census/grpc_plugin.c
@@ -506,6 +506,7 @@ foreach(_hdr
   include/grpc/compression.h
   include/grpc/compression.h
   include/grpc/grpc.h
   include/grpc/grpc.h
   include/grpc/grpc_posix.h
   include/grpc/grpc_posix.h
+  include/grpc/grpc_security_constants.h
   include/grpc/status.h
   include/grpc/status.h
   include/grpc/impl/codegen/byte_buffer.h
   include/grpc/impl/codegen/byte_buffer.h
   include/grpc/impl/codegen/byte_buffer_reader.h
   include/grpc/impl/codegen/byte_buffer_reader.h
@@ -529,7 +530,6 @@ foreach(_hdr
   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_security.h
   include/grpc/grpc_security.h
-  include/grpc/grpc_security_constants.h
   include/grpc/census.h
   include/grpc/census.h
 )
 )
   string(REPLACE "include/" "" _path ${_hdr})
   string(REPLACE "include/" "" _path ${_hdr})
@@ -670,7 +670,6 @@ add_library(grpc_cronet
   src/core/ext/client_config/channel_connectivity.c
   src/core/ext/client_config/channel_connectivity.c
   src/core/ext/client_config/client_channel.c
   src/core/ext/client_config/client_channel.c
   src/core/ext/client_config/client_channel_factory.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/client_config_plugin.c
   src/core/ext/client_config/connector.c
   src/core/ext/client_config/connector.c
   src/core/ext/client_config/default_initial_connect_string.c
   src/core/ext/client_config/default_initial_connect_string.c
@@ -682,8 +681,8 @@ add_library(grpc_cronet
   src/core/ext/client_config/resolver.c
   src/core/ext/client_config/resolver.c
   src/core/ext/client_config/resolver_factory.c
   src/core/ext/client_config/resolver_factory.c
   src/core/ext/client_config/resolver_registry.c
   src/core/ext/client_config/resolver_registry.c
+  src/core/ext/client_config/resolver_result.c
   src/core/ext/client_config/subchannel.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/subchannel_index.c
   src/core/ext/client_config/uri_parser.c
   src/core/ext/client_config/uri_parser.c
   src/core/lib/http/httpcli_security_connector.c
   src/core/lib/http/httpcli_security_connector.c
@@ -738,6 +737,7 @@ foreach(_hdr
   include/grpc/compression.h
   include/grpc/compression.h
   include/grpc/grpc.h
   include/grpc/grpc.h
   include/grpc/grpc_posix.h
   include/grpc/grpc_posix.h
+  include/grpc/grpc_security_constants.h
   include/grpc/status.h
   include/grpc/status.h
   include/grpc/impl/codegen/byte_buffer.h
   include/grpc/impl/codegen/byte_buffer.h
   include/grpc/impl/codegen/byte_buffer_reader.h
   include/grpc/impl/codegen/byte_buffer_reader.h
@@ -762,7 +762,6 @@ foreach(_hdr
   include/grpc/impl/codegen/time.h
   include/grpc/impl/codegen/time.h
   include/grpc/grpc_cronet.h
   include/grpc/grpc_cronet.h
   include/grpc/grpc_security.h
   include/grpc/grpc_security.h
-  include/grpc/grpc_security_constants.h
 )
 )
   string(REPLACE "include/" "" _path ${_hdr})
   string(REPLACE "include/" "" _path ${_hdr})
   get_filename_component(_path ${_path} PATH)
   get_filename_component(_path ${_path} PATH)
@@ -903,7 +902,6 @@ add_library(grpc_unsecure
   src/core/ext/client_config/channel_connectivity.c
   src/core/ext/client_config/channel_connectivity.c
   src/core/ext/client_config/client_channel.c
   src/core/ext/client_config/client_channel.c
   src/core/ext/client_config/client_channel_factory.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/client_config_plugin.c
   src/core/ext/client_config/connector.c
   src/core/ext/client_config/connector.c
   src/core/ext/client_config/default_initial_connect_string.c
   src/core/ext/client_config/default_initial_connect_string.c
@@ -915,8 +913,8 @@ add_library(grpc_unsecure
   src/core/ext/client_config/resolver.c
   src/core/ext/client_config/resolver.c
   src/core/ext/client_config/resolver_factory.c
   src/core/ext/client_config/resolver_factory.c
   src/core/ext/client_config/resolver_registry.c
   src/core/ext/client_config/resolver_registry.c
+  src/core/ext/client_config/resolver_result.c
   src/core/ext/client_config/subchannel.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/subchannel_index.c
   src/core/ext/client_config/uri_parser.c
   src/core/ext/client_config/uri_parser.c
   src/core/ext/resolver/dns/native/dns_resolver.c
   src/core/ext/resolver/dns/native/dns_resolver.c
@@ -934,6 +932,7 @@ add_library(grpc_unsecure
   src/core/ext/census/base_resources.c
   src/core/ext/census/base_resources.c
   src/core/ext/census/context.c
   src/core/ext/census/context.c
   src/core/ext/census/gen/census.pb.c
   src/core/ext/census/gen/census.pb.c
+  src/core/ext/census/gen/trace_context.pb.c
   src/core/ext/census/grpc_context.c
   src/core/ext/census/grpc_context.c
   src/core/ext/census/grpc_filter.c
   src/core/ext/census/grpc_filter.c
   src/core/ext/census/grpc_plugin.c
   src/core/ext/census/grpc_plugin.c
@@ -966,6 +965,7 @@ foreach(_hdr
   include/grpc/compression.h
   include/grpc/compression.h
   include/grpc/grpc.h
   include/grpc/grpc.h
   include/grpc/grpc_posix.h
   include/grpc/grpc_posix.h
+  include/grpc/grpc_security_constants.h
   include/grpc/status.h
   include/grpc/status.h
   include/grpc/impl/codegen/byte_buffer.h
   include/grpc/impl/codegen/byte_buffer.h
   include/grpc/impl/codegen/byte_buffer_reader.h
   include/grpc/impl/codegen/byte_buffer_reader.h
@@ -1041,6 +1041,95 @@ add_library(grpc++
   src/cpp/util/status.cc
   src/cpp/util/status.cc
   src/cpp/util/string_ref.cc
   src/cpp/util/string_ref.cc
   src/cpp/util/time.cc
   src/cpp/util/time.cc
+  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/handshaker.c
+  src/core/lib/channel/http_client_filter.c
+  src/core/lib/channel/http_server_filter.c
+  src/core/lib/compression/compression.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/error.c
+  src/core/lib/iomgr/ev_epoll_linux.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/load_file.c
+  src/core/lib/iomgr/network_status_tracker.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/timeout_encoding.c
+  src/core/lib/transport/transport.c
+  src/core/lib/transport/transport_op_string.c
   src/cpp/codegen/codegen_init.cc
   src/cpp/codegen/codegen_init.cc
 )
 )
 
 
@@ -1058,6 +1147,7 @@ target_link_libraries(grpc++
   ${_gRPC_SSL_LIBRARIES}
   ${_gRPC_SSL_LIBRARIES}
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_PROTOBUF_LIBRARIES}
   grpc
   grpc
+  gpr
 )
 )
 
 
 foreach(_hdr
 foreach(_hdr
@@ -1108,6 +1198,34 @@ foreach(_hdr
   include/grpc++/support/stub_options.h
   include/grpc++/support/stub_options.h
   include/grpc++/support/sync_stream.h
   include/grpc++/support/sync_stream.h
   include/grpc++/support/time.h
   include/grpc++/support/time.h
+  include/grpc/byte_buffer.h
+  include/grpc/byte_buffer_reader.h
+  include/grpc/compression.h
+  include/grpc/grpc.h
+  include/grpc/grpc_posix.h
+  include/grpc/grpc_security_constants.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++/impl/codegen/async_stream.h
   include/grpc++/impl/codegen/async_stream.h
   include/grpc++/impl/codegen/async_unary_call.h
   include/grpc++/impl/codegen/async_unary_call.h
   include/grpc++/impl/codegen/call.h
   include/grpc++/impl/codegen/call.h
@@ -1138,27 +1256,6 @@ foreach(_hdr
   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
-  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
 )
 )
   string(REPLACE "include/" "" _path ${_hdr})
   string(REPLACE "include/" "" _path ${_hdr})
   get_filename_component(_path ${_path} PATH)
   get_filename_component(_path ${_path} PATH)
@@ -1301,6 +1398,95 @@ add_library(grpc++_unsecure
   src/cpp/util/status.cc
   src/cpp/util/status.cc
   src/cpp/util/string_ref.cc
   src/cpp/util/string_ref.cc
   src/cpp/util/time.cc
   src/cpp/util/time.cc
+  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/handshaker.c
+  src/core/lib/channel/http_client_filter.c
+  src/core/lib/channel/http_server_filter.c
+  src/core/lib/compression/compression.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/error.c
+  src/core/lib/iomgr/ev_epoll_linux.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/load_file.c
+  src/core/lib/iomgr/network_status_tracker.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/timeout_encoding.c
+  src/core/lib/transport/transport.c
+  src/core/lib/transport/transport_op_string.c
   src/cpp/codegen/codegen_init.cc
   src/cpp/codegen/codegen_init.cc
 )
 )
 
 
@@ -1318,7 +1504,6 @@ target_link_libraries(grpc++_unsecure
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_PROTOBUF_LIBRARIES}
   gpr
   gpr
   grpc_unsecure
   grpc_unsecure
-  grpc
 )
 )
 
 
 foreach(_hdr
 foreach(_hdr
@@ -1369,6 +1554,34 @@ foreach(_hdr
   include/grpc++/support/stub_options.h
   include/grpc++/support/stub_options.h
   include/grpc++/support/sync_stream.h
   include/grpc++/support/sync_stream.h
   include/grpc++/support/time.h
   include/grpc++/support/time.h
+  include/grpc/byte_buffer.h
+  include/grpc/byte_buffer_reader.h
+  include/grpc/compression.h
+  include/grpc/grpc.h
+  include/grpc/grpc_posix.h
+  include/grpc/grpc_security_constants.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++/impl/codegen/async_stream.h
   include/grpc++/impl/codegen/async_stream.h
   include/grpc++/impl/codegen/async_unary_call.h
   include/grpc++/impl/codegen/async_unary_call.h
   include/grpc++/impl/codegen/call.h
   include/grpc++/impl/codegen/call.h
@@ -1399,27 +1612,6 @@ foreach(_hdr
   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
-  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
 )
 )
   string(REPLACE "include/" "" _path ${_hdr})
   string(REPLACE "include/" "" _path ${_hdr})
   get_filename_component(_path ${_path} PATH)
   get_filename_component(_path ${_path} PATH)

+ 256 - 61
Makefile

@@ -492,7 +492,7 @@ ifeq ($(HAS_PKG_CONFIG),true)
 OPENSSL_ALPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.2 openssl
 OPENSSL_ALPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.2 openssl
 OPENSSL_NPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.1 openssl
 OPENSSL_NPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.1 openssl
 ZLIB_CHECK_CMD = $(PKG_CONFIG) --exists zlib
 ZLIB_CHECK_CMD = $(PKG_CONFIG) --exists zlib
-PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0-alpha-3 protobuf
+PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0 protobuf
 else # HAS_PKG_CONFIG
 else # HAS_PKG_CONFIG
 
 
 ifeq ($(SYSTEM),MINGW32)
 ifeq ($(SYSTEM),MINGW32)
@@ -2661,7 +2661,6 @@ LIBGRPC_SRC = \
     src/core/ext/client_config/channel_connectivity.c \
     src/core/ext/client_config/channel_connectivity.c \
     src/core/ext/client_config/client_channel.c \
     src/core/ext/client_config/client_channel.c \
     src/core/ext/client_config/client_channel_factory.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/client_config_plugin.c \
     src/core/ext/client_config/connector.c \
     src/core/ext/client_config/connector.c \
     src/core/ext/client_config/default_initial_connect_string.c \
     src/core/ext/client_config/default_initial_connect_string.c \
@@ -2673,8 +2672,8 @@ LIBGRPC_SRC = \
     src/core/ext/client_config/resolver.c \
     src/core/ext/client_config/resolver.c \
     src/core/ext/client_config/resolver_factory.c \
     src/core/ext/client_config/resolver_factory.c \
     src/core/ext/client_config/resolver_registry.c \
     src/core/ext/client_config/resolver_registry.c \
+    src/core/ext/client_config/resolver_result.c \
     src/core/ext/client_config/subchannel.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/subchannel_index.c \
     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 \
@@ -2696,6 +2695,7 @@ LIBGRPC_SRC = \
     src/core/ext/census/base_resources.c \
     src/core/ext/census/base_resources.c \
     src/core/ext/census/context.c \
     src/core/ext/census/context.c \
     src/core/ext/census/gen/census.pb.c \
     src/core/ext/census/gen/census.pb.c \
+    src/core/ext/census/gen/trace_context.pb.c \
     src/core/ext/census/grpc_context.c \
     src/core/ext/census/grpc_context.c \
     src/core/ext/census/grpc_filter.c \
     src/core/ext/census/grpc_filter.c \
     src/core/ext/census/grpc_plugin.c \
     src/core/ext/census/grpc_plugin.c \
@@ -2713,6 +2713,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/compression.h \
     include/grpc/compression.h \
     include/grpc/grpc.h \
     include/grpc/grpc.h \
     include/grpc/grpc_posix.h \
     include/grpc/grpc_posix.h \
+    include/grpc/grpc_security_constants.h \
     include/grpc/status.h \
     include/grpc/status.h \
     include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.h \
     include/grpc/impl/codegen/byte_buffer_reader.h \
@@ -2736,7 +2737,6 @@ PUBLIC_HEADERS_C += \
     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_security.h \
     include/grpc/grpc_security.h \
-    include/grpc/grpc_security_constants.h \
     include/grpc/census.h \
     include/grpc/census.h \
 
 
 LIBGRPC_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_SRC))))
 LIBGRPC_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_SRC))))
@@ -2912,7 +2912,6 @@ LIBGRPC_CRONET_SRC = \
     src/core/ext/client_config/channel_connectivity.c \
     src/core/ext/client_config/channel_connectivity.c \
     src/core/ext/client_config/client_channel.c \
     src/core/ext/client_config/client_channel.c \
     src/core/ext/client_config/client_channel_factory.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/client_config_plugin.c \
     src/core/ext/client_config/connector.c \
     src/core/ext/client_config/connector.c \
     src/core/ext/client_config/default_initial_connect_string.c \
     src/core/ext/client_config/default_initial_connect_string.c \
@@ -2924,8 +2923,8 @@ LIBGRPC_CRONET_SRC = \
     src/core/ext/client_config/resolver.c \
     src/core/ext/client_config/resolver.c \
     src/core/ext/client_config/resolver_factory.c \
     src/core/ext/client_config/resolver_factory.c \
     src/core/ext/client_config/resolver_registry.c \
     src/core/ext/client_config/resolver_registry.c \
+    src/core/ext/client_config/resolver_result.c \
     src/core/ext/client_config/subchannel.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/subchannel_index.c \
     src/core/ext/client_config/uri_parser.c \
     src/core/ext/client_config/uri_parser.c \
     src/core/lib/http/httpcli_security_connector.c \
     src/core/lib/http/httpcli_security_connector.c \
@@ -2964,6 +2963,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/compression.h \
     include/grpc/compression.h \
     include/grpc/grpc.h \
     include/grpc/grpc.h \
     include/grpc/grpc_posix.h \
     include/grpc/grpc_posix.h \
+    include/grpc/grpc_security_constants.h \
     include/grpc/status.h \
     include/grpc/status.h \
     include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.h \
     include/grpc/impl/codegen/byte_buffer_reader.h \
@@ -2988,7 +2988,6 @@ PUBLIC_HEADERS_C += \
     include/grpc/impl/codegen/time.h \
     include/grpc/impl/codegen/time.h \
     include/grpc/grpc_cronet.h \
     include/grpc/grpc_cronet.h \
     include/grpc/grpc_security.h \
     include/grpc/grpc_security.h \
-    include/grpc/grpc_security_constants.h \
 
 
 LIBGRPC_CRONET_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_CRONET_SRC))))
 LIBGRPC_CRONET_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_CRONET_SRC))))
 
 
@@ -3157,6 +3156,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/compression.h \
     include/grpc/compression.h \
     include/grpc/grpc.h \
     include/grpc/grpc.h \
     include/grpc/grpc_posix.h \
     include/grpc/grpc_posix.h \
+    include/grpc/grpc_security_constants.h \
     include/grpc/status.h \
     include/grpc/status.h \
     include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.h \
     include/grpc/impl/codegen/byte_buffer_reader.h \
@@ -3372,7 +3372,6 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/client_config/channel_connectivity.c \
     src/core/ext/client_config/channel_connectivity.c \
     src/core/ext/client_config/client_channel.c \
     src/core/ext/client_config/client_channel.c \
     src/core/ext/client_config/client_channel_factory.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/client_config_plugin.c \
     src/core/ext/client_config/connector.c \
     src/core/ext/client_config/connector.c \
     src/core/ext/client_config/default_initial_connect_string.c \
     src/core/ext/client_config/default_initial_connect_string.c \
@@ -3384,8 +3383,8 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/client_config/resolver.c \
     src/core/ext/client_config/resolver.c \
     src/core/ext/client_config/resolver_factory.c \
     src/core/ext/client_config/resolver_factory.c \
     src/core/ext/client_config/resolver_registry.c \
     src/core/ext/client_config/resolver_registry.c \
+    src/core/ext/client_config/resolver_result.c \
     src/core/ext/client_config/subchannel.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/subchannel_index.c \
     src/core/ext/client_config/uri_parser.c \
     src/core/ext/client_config/uri_parser.c \
     src/core/ext/resolver/dns/native/dns_resolver.c \
     src/core/ext/resolver/dns/native/dns_resolver.c \
@@ -3403,6 +3402,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/census/base_resources.c \
     src/core/ext/census/base_resources.c \
     src/core/ext/census/context.c \
     src/core/ext/census/context.c \
     src/core/ext/census/gen/census.pb.c \
     src/core/ext/census/gen/census.pb.c \
+    src/core/ext/census/gen/trace_context.pb.c \
     src/core/ext/census/grpc_context.c \
     src/core/ext/census/grpc_context.c \
     src/core/ext/census/grpc_filter.c \
     src/core/ext/census/grpc_filter.c \
     src/core/ext/census/grpc_plugin.c \
     src/core/ext/census/grpc_plugin.c \
@@ -3420,6 +3420,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/compression.h \
     include/grpc/compression.h \
     include/grpc/grpc.h \
     include/grpc/grpc.h \
     include/grpc/grpc_posix.h \
     include/grpc/grpc_posix.h \
+    include/grpc/grpc_security_constants.h \
     include/grpc/status.h \
     include/grpc/status.h \
     include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.h \
     include/grpc/impl/codegen/byte_buffer_reader.h \
@@ -3593,6 +3594,95 @@ LIBGRPC++_SRC = \
     src/cpp/util/status.cc \
     src/cpp/util/status.cc \
     src/cpp/util/string_ref.cc \
     src/cpp/util/string_ref.cc \
     src/cpp/util/time.cc \
     src/cpp/util/time.cc \
+    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/handshaker.c \
+    src/core/lib/channel/http_client_filter.c \
+    src/core/lib/channel/http_server_filter.c \
+    src/core/lib/compression/compression.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/error.c \
+    src/core/lib/iomgr/ev_epoll_linux.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/load_file.c \
+    src/core/lib/iomgr/network_status_tracker.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/timeout_encoding.c \
+    src/core/lib/transport/transport.c \
+    src/core/lib/transport/transport_op_string.c \
     src/cpp/codegen/codegen_init.cc \
     src/cpp/codegen/codegen_init.cc \
 
 
 PUBLIC_HEADERS_CXX += \
 PUBLIC_HEADERS_CXX += \
@@ -3643,6 +3733,34 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/support/stub_options.h \
     include/grpc++/support/stub_options.h \
     include/grpc++/support/sync_stream.h \
     include/grpc++/support/sync_stream.h \
     include/grpc++/support/time.h \
     include/grpc++/support/time.h \
+    include/grpc/byte_buffer.h \
+    include/grpc/byte_buffer_reader.h \
+    include/grpc/compression.h \
+    include/grpc/grpc.h \
+    include/grpc/grpc_posix.h \
+    include/grpc/grpc_security_constants.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++/impl/codegen/async_stream.h \
     include/grpc++/impl/codegen/async_stream.h \
     include/grpc++/impl/codegen/async_unary_call.h \
     include/grpc++/impl/codegen/async_unary_call.h \
     include/grpc++/impl/codegen/call.h \
     include/grpc++/impl/codegen/call.h \
@@ -3673,27 +3791,6 @@ PUBLIC_HEADERS_CXX += \
     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 \
-    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 \
 
 
 LIBGRPC++_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_SRC))))
 LIBGRPC++_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_SRC))))
 
 
@@ -3730,18 +3827,18 @@ endif
 
 
 
 
 ifeq ($(SYSTEM),MINGW32)
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc-imp
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc-imp -lgpr-imp
 else
 else
-$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc -lgpr
 else
 else
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc -lgpr
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).so.1
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).so.1
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).so
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).so
 endif
 endif
@@ -4132,6 +4229,95 @@ LIBGRPC++_UNSECURE_SRC = \
     src/cpp/util/status.cc \
     src/cpp/util/status.cc \
     src/cpp/util/string_ref.cc \
     src/cpp/util/string_ref.cc \
     src/cpp/util/time.cc \
     src/cpp/util/time.cc \
+    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/handshaker.c \
+    src/core/lib/channel/http_client_filter.c \
+    src/core/lib/channel/http_server_filter.c \
+    src/core/lib/compression/compression.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/error.c \
+    src/core/lib/iomgr/ev_epoll_linux.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/load_file.c \
+    src/core/lib/iomgr/network_status_tracker.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/timeout_encoding.c \
+    src/core/lib/transport/transport.c \
+    src/core/lib/transport/transport_op_string.c \
     src/cpp/codegen/codegen_init.cc \
     src/cpp/codegen/codegen_init.cc \
 
 
 PUBLIC_HEADERS_CXX += \
 PUBLIC_HEADERS_CXX += \
@@ -4182,6 +4368,34 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/support/stub_options.h \
     include/grpc++/support/stub_options.h \
     include/grpc++/support/sync_stream.h \
     include/grpc++/support/sync_stream.h \
     include/grpc++/support/time.h \
     include/grpc++/support/time.h \
+    include/grpc/byte_buffer.h \
+    include/grpc/byte_buffer_reader.h \
+    include/grpc/compression.h \
+    include/grpc/grpc.h \
+    include/grpc/grpc_posix.h \
+    include/grpc/grpc_security_constants.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++/impl/codegen/async_stream.h \
     include/grpc++/impl/codegen/async_stream.h \
     include/grpc++/impl/codegen/async_unary_call.h \
     include/grpc++/impl/codegen/async_unary_call.h \
     include/grpc++/impl/codegen/call.h \
     include/grpc++/impl/codegen/call.h \
@@ -4212,27 +4426,6 @@ PUBLIC_HEADERS_CXX += \
     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 \
-    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 \
 
 
 LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC))))
 LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC))))
 
 
@@ -4259,18 +4452,18 @@ endif
 
 
 
 
 ifeq ($(SYSTEM),MINGW32)
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT)
+$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT)
 	$(E) "[LD]      Linking $@"
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++_unsecure.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_unsecure-imp -lgrpc-imp
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++_unsecure.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_unsecure-imp
 else
 else
-$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT)
+$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT)
 	$(E) "[LD]      Linking $@"
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure -lgrpc
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
 else
 else
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure -lgrpc
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).so.1
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).so.1
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).so
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).so
 endif
 endif
@@ -6589,6 +6782,7 @@ LIBEND2END_TESTS_SRC = \
     test/core/end2end/tests/max_message_length.c \
     test/core/end2end/tests/max_message_length.c \
     test/core/end2end/tests/negative_deadline.c \
     test/core/end2end/tests/negative_deadline.c \
     test/core/end2end/tests/network_status_change.c \
     test/core/end2end/tests/network_status_change.c \
+    test/core/end2end/tests/no_logging.c \
     test/core/end2end/tests/no_op.c \
     test/core/end2end/tests/no_op.c \
     test/core/end2end/tests/payload.c \
     test/core/end2end/tests/payload.c \
     test/core/end2end/tests/ping.c \
     test/core/end2end/tests/ping.c \
@@ -6669,6 +6863,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \
     test/core/end2end/tests/max_message_length.c \
     test/core/end2end/tests/max_message_length.c \
     test/core/end2end/tests/negative_deadline.c \
     test/core/end2end/tests/negative_deadline.c \
     test/core/end2end/tests/network_status_change.c \
     test/core/end2end/tests/network_status_change.c \
+    test/core/end2end/tests/no_logging.c \
     test/core/end2end/tests/no_op.c \
     test/core/end2end/tests/no_op.c \
     test/core/end2end/tests/payload.c \
     test/core/end2end/tests/payload.c \
     test/core/end2end/tests/ping.c \
     test/core/end2end/tests/ping.c \

+ 1 - 1
PYTHON-MANIFEST.in

@@ -7,7 +7,7 @@ graft include/grpc
 graft third_party/boringssl
 graft third_party/boringssl
 graft third_party/nanopb
 graft third_party/nanopb
 graft third_party/zlib
 graft third_party/zlib
-include src/python/grpcio/_unixccompiler_patch.py
+include src/python/grpcio/_spawn_patch.py
 include src/python/grpcio/commands.py
 include src/python/grpcio/commands.py
 include src/python/grpcio/grpc_version.py
 include src/python/grpcio/grpc_version.py
 include src/python/grpcio/grpc_core_dependencies.py
 include src/python/grpcio/grpc_core_dependencies.py

+ 10 - 10
README.md

@@ -23,16 +23,16 @@ This repository contains source code for gRPC libraries for multiple languages w
 
 
 Libraries in different languages are in different states of development. We are seeking contributions for all of these libraries.
 Libraries in different languages are in different states of development. We are seeking contributions for all of these libraries.
 
 
-| Language                | Source                              | Status                           |
-|-------------------------|-------------------------------------|----------------------------------|
-| Shared C [core library] | [src/core] (src/core)               | Beta - the surface API is stable |
-| C++                     | [src/cpp] (src/cpp)                 | Beta - the surface API is stable |
-| Ruby                    | [src/ruby] (src/ruby)               | Beta - the surface API is stable |
-| NodeJS                  | [src/node] (src/node)               | Beta - the surface API is stable |
-| Python                  | [src/python] (src/python)           | Beta - the surface API is stable |
-| PHP                     | [src/php] (src/php)                 | Beta - the surface API is stable |
-| C#                      | [src/csharp] (src/csharp)           | Beta - the surface API is stable |
-| Objective-C             | [src/objective-c] (src/objective-c) | Beta - the surface API is stable |
+| Language                | Source                              | Status  |
+|-------------------------|-------------------------------------|---------|
+| Shared C [core library] | [src/core] (src/core)               | 1.0     |
+| C++                     | [src/cpp] (src/cpp)                 | 1.0     |
+| Ruby                    | [src/ruby] (src/ruby)               | 1.0     |
+| NodeJS                  | [src/node] (src/node)               | 1.0     |
+| Python                  | [src/python] (src/python)           | 1.0     |
+| PHP                     | [src/php] (src/php)                 | 1.0     |
+| C#                      | [src/csharp] (src/csharp)           | 1.0     |
+| Objective-C             | [src/objective-c] (src/objective-c) | 1.0     |
 
 
 <small>
 <small>
 Java source code is in the [grpc-java] (http://github.com/grpc/grpc-java) repository.
 Java source code is in the [grpc-java] (http://github.com/grpc/grpc-java) repository.

+ 2 - 2
binding.gyp

@@ -709,7 +709,6 @@
         'src/core/ext/client_config/channel_connectivity.c',
         'src/core/ext/client_config/channel_connectivity.c',
         'src/core/ext/client_config/client_channel.c',
         'src/core/ext/client_config/client_channel.c',
         'src/core/ext/client_config/client_channel_factory.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/client_config_plugin.c',
         'src/core/ext/client_config/connector.c',
         'src/core/ext/client_config/connector.c',
         'src/core/ext/client_config/default_initial_connect_string.c',
         'src/core/ext/client_config/default_initial_connect_string.c',
@@ -721,8 +720,8 @@
         'src/core/ext/client_config/resolver.c',
         'src/core/ext/client_config/resolver.c',
         'src/core/ext/client_config/resolver_factory.c',
         'src/core/ext/client_config/resolver_factory.c',
         'src/core/ext/client_config/resolver_registry.c',
         'src/core/ext/client_config/resolver_registry.c',
+        'src/core/ext/client_config/resolver_result.c',
         'src/core/ext/client_config/subchannel.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/subchannel_index.c',
         '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',
@@ -744,6 +743,7 @@
         'src/core/ext/census/base_resources.c',
         'src/core/ext/census/base_resources.c',
         'src/core/ext/census/context.c',
         'src/core/ext/census/context.c',
         'src/core/ext/census/gen/census.pb.c',
         'src/core/ext/census/gen/census.pb.c',
+        'src/core/ext/census/gen/trace_context.pb.c',
         'src/core/ext/census/grpc_context.c',
         'src/core/ext/census/grpc_context.c',
         'src/core/ext/census/grpc_filter.c',
         'src/core/ext/census/grpc_filter.c',
         'src/core/ext/census/grpc_plugin.c',
         'src/core/ext/census/grpc_plugin.c',

+ 17 - 12
build.yaml

@@ -2,11 +2,17 @@
 '#2': It is used among other things to generate all of our project files.
 '#2': It is used among other things to generate all of our project files.
 '#3': Please refer to the templates directory for more information.
 '#3': Please refer to the templates directory for more information.
 settings:
 settings:
-  '#1': The public version number of the library.
-  '#2': Master always has a "-dev" suffix
-  '#3': Use "-preN" suffixes to identify pre-release versions
-  '#4': Per-language overrides are possible with (eg) ruby_version tag here
-  '#5': See the expand_version.py for all the quirks here
+  '#01': The public version number of the library.
+  '#02': ===
+  '#03': Please update the 'g_stands_for' field periodically with a new g word
+  '#04': not listed in doc/g_stands_for.md - and update that document to list the
+  '#05': new word.
+  '#06': ===
+  '#07': Master always has a "-dev" suffix
+  '#08': Use "-preN" suffixes to identify pre-release versions
+  '#09': Per-language overrides are possible with (eg) ruby_version tag here
+  '#10': See the expand_version.py for all the quirks here
+  g_stands_for: good
   version: 1.1.0-dev
   version: 1.1.0-dev
 filegroups:
 filegroups:
 - name: census
 - name: census
@@ -18,6 +24,7 @@ filegroups:
   - src/core/ext/census/census_interface.h
   - src/core/ext/census/census_interface.h
   - src/core/ext/census/census_rpc_stats.h
   - src/core/ext/census/census_rpc_stats.h
   - src/core/ext/census/gen/census.pb.h
   - src/core/ext/census/gen/census.pb.h
+  - src/core/ext/census/gen/trace_context.pb.h
   - src/core/ext/census/grpc_filter.h
   - src/core/ext/census/grpc_filter.h
   - src/core/ext/census/mlog.h
   - src/core/ext/census/mlog.h
   - src/core/ext/census/resource.h
   - src/core/ext/census/resource.h
@@ -26,6 +33,7 @@ filegroups:
   - src/core/ext/census/base_resources.c
   - src/core/ext/census/base_resources.c
   - src/core/ext/census/context.c
   - src/core/ext/census/context.c
   - src/core/ext/census/gen/census.pb.c
   - src/core/ext/census/gen/census.pb.c
+  - src/core/ext/census/gen/trace_context.pb.c
   - src/core/ext/census/grpc_context.c
   - src/core/ext/census/grpc_context.c
   - src/core/ext/census/grpc_filter.c
   - src/core/ext/census/grpc_filter.c
   - src/core/ext/census/grpc_plugin.c
   - src/core/ext/census/grpc_plugin.c
@@ -154,6 +162,7 @@ filegroups:
   - include/grpc/compression.h
   - include/grpc/compression.h
   - include/grpc/grpc.h
   - include/grpc/grpc.h
   - include/grpc/grpc_posix.h
   - include/grpc/grpc_posix.h
+  - include/grpc/grpc_security_constants.h
   - include/grpc/status.h
   - include/grpc/status.h
   headers:
   headers:
   - src/core/lib/channel/channel_args.h
   - src/core/lib/channel/channel_args.h
@@ -336,7 +345,6 @@ filegroups:
   headers:
   headers:
   - src/core/ext/client_config/client_channel.h
   - src/core/ext/client_config/client_channel.h
   - src/core/ext/client_config/client_channel_factory.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/connector.h
   - src/core/ext/client_config/initial_connect_string.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.h
@@ -346,15 +354,14 @@ filegroups:
   - src/core/ext/client_config/resolver.h
   - src/core/ext/client_config/resolver.h
   - src/core/ext/client_config/resolver_factory.h
   - src/core/ext/client_config/resolver_factory.h
   - src/core/ext/client_config/resolver_registry.h
   - src/core/ext/client_config/resolver_registry.h
+  - src/core/ext/client_config/resolver_result.h
   - src/core/ext/client_config/subchannel.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/subchannel_index.h
   - src/core/ext/client_config/uri_parser.h
   - src/core/ext/client_config/uri_parser.h
   src:
   src:
   - src/core/ext/client_config/channel_connectivity.c
   - src/core/ext/client_config/channel_connectivity.c
   - src/core/ext/client_config/client_channel.c
   - src/core/ext/client_config/client_channel.c
   - src/core/ext/client_config/client_channel_factory.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/client_config_plugin.c
   - src/core/ext/client_config/connector.c
   - src/core/ext/client_config/connector.c
   - src/core/ext/client_config/default_initial_connect_string.c
   - src/core/ext/client_config/default_initial_connect_string.c
@@ -366,8 +373,8 @@ filegroups:
   - src/core/ext/client_config/resolver.c
   - src/core/ext/client_config/resolver.c
   - src/core/ext/client_config/resolver_factory.c
   - src/core/ext/client_config/resolver_factory.c
   - src/core/ext/client_config/resolver_registry.c
   - src/core/ext/client_config/resolver_registry.c
+  - src/core/ext/client_config/resolver_result.c
   - src/core/ext/client_config/subchannel.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/subchannel_index.c
   - src/core/ext/client_config/uri_parser.c
   - src/core/ext/client_config/uri_parser.c
   plugin: grpc_client_config
   plugin: grpc_client_config
@@ -439,7 +446,6 @@ filegroups:
 - name: grpc_secure
 - name: grpc_secure
   public_headers:
   public_headers:
   - include/grpc/grpc_security.h
   - include/grpc/grpc_security.h
-  - include/grpc/grpc_security_constants.h
   headers:
   headers:
   - src/core/lib/security/context/security_context.h
   - src/core/lib/security/context/security_context.h
   - src/core/lib/security/credentials/composite/composite_credentials.h
   - src/core/lib/security/credentials/composite/composite_credentials.h
@@ -727,9 +733,8 @@ filegroups:
   - src/cpp/util/status.cc
   - src/cpp/util/status.cc
   - src/cpp/util/string_ref.cc
   - src/cpp/util/string_ref.cc
   - src/cpp/util/time.cc
   - src/cpp/util/time.cc
-  deps:
-  - grpc
   uses:
   uses:
+  - grpc_base
   - grpc++_codegen_base
   - grpc++_codegen_base
 - name: grpc++_codegen_base
 - name: grpc++_codegen_base
   language: c++
   language: c++

+ 2 - 2
config.m4

@@ -228,7 +228,6 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/client_config/channel_connectivity.c \
     src/core/ext/client_config/channel_connectivity.c \
     src/core/ext/client_config/client_channel.c \
     src/core/ext/client_config/client_channel.c \
     src/core/ext/client_config/client_channel_factory.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/client_config_plugin.c \
     src/core/ext/client_config/connector.c \
     src/core/ext/client_config/connector.c \
     src/core/ext/client_config/default_initial_connect_string.c \
     src/core/ext/client_config/default_initial_connect_string.c \
@@ -240,8 +239,8 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/client_config/resolver.c \
     src/core/ext/client_config/resolver.c \
     src/core/ext/client_config/resolver_factory.c \
     src/core/ext/client_config/resolver_factory.c \
     src/core/ext/client_config/resolver_registry.c \
     src/core/ext/client_config/resolver_registry.c \
+    src/core/ext/client_config/resolver_result.c \
     src/core/ext/client_config/subchannel.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/subchannel_index.c \
     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 \
@@ -263,6 +262,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/census/base_resources.c \
     src/core/ext/census/base_resources.c \
     src/core/ext/census/context.c \
     src/core/ext/census/context.c \
     src/core/ext/census/gen/census.pb.c \
     src/core/ext/census/gen/census.pb.c \
+    src/core/ext/census/gen/trace_context.pb.c \
     src/core/ext/census/grpc_context.c \
     src/core/ext/census/grpc_context.c \
     src/core/ext/census/grpc_filter.c \
     src/core/ext/census/grpc_filter.c \
     src/core/ext/census/grpc_plugin.c \
     src/core/ext/census/grpc_plugin.c \

+ 20 - 2
doc/PROTOCOL-HTTP2.md

@@ -98,8 +98,11 @@ For requests, **EOS** (end-of-stream) is indicated by the presence of the END_ST
 * **Trailers-Only** → HTTP-Status Content-Type Trailers
 * **Trailers-Only** → HTTP-Status Content-Type Trailers
 * **Trailers** → Status [Status-Message] \*Custom-Metadata
 * **Trailers** → Status [Status-Message] \*Custom-Metadata
 * **HTTP-Status** → ":status 200"
 * **HTTP-Status** → ":status 200"
-* **Status** → "grpc-status" <status-code-as-ASCII-string>
-* **Status-Message** → "grpc-message" <descriptive text for status as ASCII string>
+* **Status** → "grpc-status" 1\*DIGIT ; 0-9
+* **Status-Message** → "grpc-message" Percent-Encoded
+* **Percent-Encoded** → 1\*(Percent-Byte-Unencoded / Percent-Byte-Encoded)
+* **Percent-Byte-Unencoded** → 1\*( %x20-%x24 / %x26-%x7E ) ; space and VCHAR, except %
+* **Percent-Byte-Encoded** → "%" 2HEXDIGIT ; 0-9 A-F
 
 
 **Response-Headers** & **Trailers-Only** are each delivered in a single HTTP2 HEADERS frame block. Most responses are expected to have both headers and trailers but **Trailers-Only** is permitted for calls that produce an immediate error. Status must be sent in **Trailers** even if the status code is OK.
 **Response-Headers** & **Trailers-Only** are each delivered in a single HTTP2 HEADERS frame block. Most responses are expected to have both headers and trailers but **Trailers-Only** is permitted for calls that produce an immediate error. Status must be sent in **Trailers** even if the status code is OK.
 
 
@@ -110,6 +113,21 @@ Implementations should expect broken deployments to send non-200 HTTP status cod
 Clients may limit the size of **Response-Headers**, **Trailers**, and
 Clients may limit the size of **Response-Headers**, **Trailers**, and
 **Trailers-Only**, with a default of 8 KiB each suggested.
 **Trailers-Only**, with a default of 8 KiB each suggested.
 
 
+The value portion of **Status** is a decimal-encoded integer as an ASCII string,
+without any leading zeros.
+
+The value portion of **Status-Message** is conceptually a Unicode string
+description of the error, physically encoded as UTF-8 followed by
+percent-encoding. Percent-encoding is specified in [RFC 3986
+§2.1](https://tools.ietf.org/html/rfc3986#section-2.1), although the form used
+here has different restricted characters. When decoding invalid values,
+implementations MUST NOT error or throw away the message. At worst, the
+implementation can abort decoding the status message altogether such that the
+user would received the raw percent-encoded form. Alternatively, the
+implementation can decode valid portions while leaving broken %-encodings as-is
+or replacing them with a replacement character (e.g., '?' or the Unicode
+replacement character).
+
 ####Example
 ####Example
 
 
 Sample unary-call showing HTTP2 framing sequence
 Sample unary-call showing HTTP2 framing sequence

+ 1 - 15
doc/fail_fast.md

@@ -1,15 +1 @@
-gRPC Fail Fast Semantics
-========================
-
-Fail fast requests allow terminating requests (with status UNAVAILABLE) prior
-to the deadline of the request being met.
-
-gRPC implementations of fail fast can terminate requests whenever a channel is
-in the TRANSIENT_FAILURE or SHUTDOWN states. If the channel is in any other
-state (CONNECTING, READY, or IDLE) the request should not be terminated.
-
-Fail fast SHOULD be the default for gRPC implementations, with an option to
-switch to non fail fast.
-
-The opposite of fail fast is 'ignore connectivity'.
-
+Moved to wait-for-ready.md

+ 8 - 0
doc/g_stands_for.md

@@ -0,0 +1,8 @@
+Each version of gRPC gets a new description of what the 'g' stands for, since
+we've never really been able to figure it out.
+
+Below is a list of already-used definitions (that should not be repeated in the
+future), and the corresponding version numbers that used them:
+
+- 1.0 'g' stands for 'gRPC'
+- 1.1 'g' stands for 'good'

+ 14 - 0
doc/wait-for-ready.md

@@ -0,0 +1,14 @@
+gRPC Wait for Ready Semantics
+=============================
+
+If an RPC is issued but the channel is in `TRANSIENT_FAILURE` or `SHUTDOWN`
+states, the RPC is unable to be transmited promptly. By default, gRPC
+implementations SHOULD fail such RPCs immediately. This is known as "fail fast,"
+but usage of the term is historical. RPCs SHOULD NOT fail as a result of the
+channel being in other states (`CONNECTING`, `READY`, or `IDLE`).
+
+gRPC implementations MAY provide a per-RPC option to not fail RPCs as a result
+of the channel being in `TRANSIENT_FAILURE` state. Instead, the implementation
+queues the RPCs until the channel is `READY`. This is known as "wait for ready."
+The RPCs SHOULD still fail before `READY` if there are unrelated reasons, such
+as the channel is `SHUTDOWN` or the RPC's deadline is reached.

+ 8 - 5
examples/objective-c/auth_sample/AuthTestService.podspec

@@ -14,7 +14,7 @@ Pod::Spec.new do |s|
   src = "../../protos"
   src = "../../protos"
 
 
   # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
   # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
-  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2"
+  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0"
 
 
   # Pods directory corresponding to this app's Podfile, relative to the location of this podspec.
   # Pods directory corresponding to this app's Podfile, relative to the location of this podspec.
   pods_root = 'Pods'
   pods_root = 'Pods'
@@ -45,10 +45,6 @@ Pod::Spec.new do |s|
     ms.requires_arc = false
     ms.requires_arc = false
     # The generated files depend on the protobuf runtime.
     # The generated files depend on the protobuf runtime.
     ms.dependency "Protobuf"
     ms.dependency "Protobuf"
-    # This is needed by all pods that depend on Protobuf:
-    ms.pod_target_xcconfig = {
-      'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
-    }
   end
   end
 
 
   # Files generated by the gRPC plugin
   # Files generated by the gRPC plugin
@@ -60,4 +56,11 @@ Pod::Spec.new do |s|
     ss.dependency "gRPC-ProtoRPC"
     ss.dependency "gRPC-ProtoRPC"
     ss.dependency "#{s.name}/Messages"
     ss.dependency "#{s.name}/Messages"
   end
   end
+
+  s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on Protobuf:
+    'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
+  }
 end
 end

+ 8 - 5
examples/objective-c/helloworld/HelloWorld.podspec

@@ -14,7 +14,7 @@ Pod::Spec.new do |s|
   src = "../../protos"
   src = "../../protos"
 
 
   # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
   # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
-  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2"
+  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0"
 
 
   # Pods directory corresponding to this app's Podfile, relative to the location of this podspec.
   # Pods directory corresponding to this app's Podfile, relative to the location of this podspec.
   pods_root = 'Pods'
   pods_root = 'Pods'
@@ -45,10 +45,6 @@ Pod::Spec.new do |s|
     ms.requires_arc = false
     ms.requires_arc = false
     # The generated files depend on the protobuf runtime.
     # The generated files depend on the protobuf runtime.
     ms.dependency "Protobuf"
     ms.dependency "Protobuf"
-    # This is needed by all pods that depend on Protobuf:
-    ms.pod_target_xcconfig = {
-      'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
-    }
   end
   end
 
 
   # Files generated by the gRPC plugin
   # Files generated by the gRPC plugin
@@ -60,4 +56,11 @@ Pod::Spec.new do |s|
     ss.dependency "gRPC-ProtoRPC"
     ss.dependency "gRPC-ProtoRPC"
     ss.dependency "#{s.name}/Messages"
     ss.dependency "#{s.name}/Messages"
   end
   end
+
+  s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on Protobuf:
+    'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
+  }
 end
 end

+ 8 - 5
examples/objective-c/route_guide/RouteGuide.podspec

@@ -14,7 +14,7 @@ Pod::Spec.new do |s|
   src = "../../protos"
   src = "../../protos"
 
 
   # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
   # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
-  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2"
+  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0"
 
 
   # Pods directory corresponding to this app's Podfile, relative to the location of this podspec.
   # Pods directory corresponding to this app's Podfile, relative to the location of this podspec.
   pods_root = 'Pods'
   pods_root = 'Pods'
@@ -45,10 +45,6 @@ Pod::Spec.new do |s|
     ms.requires_arc = false
     ms.requires_arc = false
     # The generated files depend on the protobuf runtime.
     # The generated files depend on the protobuf runtime.
     ms.dependency "Protobuf"
     ms.dependency "Protobuf"
-    # This is needed by all pods that depend on Protobuf:
-    ms.pod_target_xcconfig = {
-      'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
-    }
   end
   end
 
 
   # Files generated by the gRPC plugin
   # Files generated by the gRPC plugin
@@ -60,4 +56,11 @@ Pod::Spec.new do |s|
     ss.dependency "gRPC-ProtoRPC"
     ss.dependency "gRPC-ProtoRPC"
     ss.dependency "#{s.name}/Messages"
     ss.dependency "#{s.name}/Messages"
   end
   end
+
+  s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on Protobuf:
+    'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
+  }
 end
 end

+ 1 - 2
examples/php/composer.json

@@ -1,8 +1,7 @@
 {
 {
   "name": "grpc/grpc-demo",
   "name": "grpc/grpc-demo",
   "description": "gRPC example for PHP",
   "description": "gRPC example for PHP",
-  "minimum-stability": "dev",
   "require": {
   "require": {
-    "grpc/grpc": "v0.15.2"
+    "grpc/grpc": "v1.0.0"
   }
   }
 }
 }

+ 1 - 1
examples/php/run_greeter_client.sh

@@ -30,5 +30,5 @@
 
 
 set -e
 set -e
 cd $(dirname $0)
 cd $(dirname $0)
-php $extension_dir -d extension=grpc.so -d max_execution_time=300 \
+php -d extension=grpc.so -d max_execution_time=300 \
   greeter_client.php $1
   greeter_client.php $1

+ 10 - 10
gRPC-Core.podspec

@@ -35,7 +35,7 @@
 
 
 Pod::Spec.new do |s|
 Pod::Spec.new do |s|
   s.name     = 'gRPC-Core'
   s.name     = 'gRPC-Core'
-  version = '1.0.0-pre1'
+  version = '1.0.0'
   s.version  = version
   s.version  = version
   s.summary  = 'Core cross-platform gRPC library, written in C'
   s.summary  = 'Core cross-platform gRPC library, written in C'
   s.homepage = 'http://www.grpc.io'
   s.homepage = 'http://www.grpc.io'
@@ -44,7 +44,7 @@ Pod::Spec.new do |s|
 
 
   s.source = {
   s.source = {
     :git => 'https://github.com/grpc/grpc.git',
     :git => 'https://github.com/grpc/grpc.git',
-    :tag => "objective-c-v#{version}",
+    :tag => "v#{version}",
     # TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules.
     # TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules.
     :submodules => true,
     :submodules => true,
   }
   }
@@ -163,6 +163,7 @@ Pod::Spec.new do |s|
                       'include/grpc/compression.h',
                       'include/grpc/compression.h',
                       'include/grpc/grpc.h',
                       'include/grpc/grpc.h',
                       'include/grpc/grpc_posix.h',
                       'include/grpc/grpc_posix.h',
+                      'include/grpc/grpc_security_constants.h',
                       'include/grpc/status.h',
                       'include/grpc/status.h',
                       'include/grpc/impl/codegen/byte_buffer.h',
                       'include/grpc/impl/codegen/byte_buffer.h',
                       'include/grpc/impl/codegen/byte_buffer_reader.h',
                       'include/grpc/impl/codegen/byte_buffer_reader.h',
@@ -186,14 +187,13 @@ Pod::Spec.new do |s|
                       '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_security.h',
                       'include/grpc/grpc_security.h',
-                      'include/grpc/grpc_security_constants.h',
                       'include/grpc/census.h'
                       'include/grpc/census.h'
   end
   end
   s.subspec 'Implementation' do |ss|
   s.subspec 'Implementation' do |ss|
     ss.header_mappings_dir = '.'
     ss.header_mappings_dir = '.'
     ss.libraries = 'z'
     ss.libraries = 'z'
     ss.dependency "#{s.name}/Interface", version
     ss.dependency "#{s.name}/Interface", version
-    ss.dependency 'BoringSSL', '~> 5.0'
+    ss.dependency 'BoringSSL', '~> 6.0'
 
 
     # To save you from scrolling, this is the last part of the podspec.
     # To save you from scrolling, this is the last part of the podspec.
     ss.source_files = 'src/core/lib/profiling/timers.h',
     ss.source_files = 'src/core/lib/profiling/timers.h',
@@ -382,7 +382,6 @@ Pod::Spec.new do |s|
                       'src/core/lib/tsi/transport_security_interface.h',
                       'src/core/lib/tsi/transport_security_interface.h',
                       'src/core/ext/client_config/client_channel.h',
                       'src/core/ext/client_config/client_channel.h',
                       'src/core/ext/client_config/client_channel_factory.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/connector.h',
                       'src/core/ext/client_config/initial_connect_string.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.h',
@@ -392,8 +391,8 @@ Pod::Spec.new do |s|
                       'src/core/ext/client_config/resolver.h',
                       'src/core/ext/client_config/resolver.h',
                       'src/core/ext/client_config/resolver_factory.h',
                       'src/core/ext/client_config/resolver_factory.h',
                       'src/core/ext/client_config/resolver_registry.h',
                       'src/core/ext/client_config/resolver_registry.h',
+                      'src/core/ext/client_config/resolver_result.h',
                       'src/core/ext/client_config/subchannel.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/subchannel_index.h',
                       'src/core/ext/client_config/uri_parser.h',
                       'src/core/ext/client_config/uri_parser.h',
                       'src/core/ext/lb_policy/grpclb/grpclb.h',
                       'src/core/ext/lb_policy/grpclb/grpclb.h',
@@ -410,6 +409,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/census/census_interface.h',
                       'src/core/ext/census/census_interface.h',
                       'src/core/ext/census/census_rpc_stats.h',
                       'src/core/ext/census/census_rpc_stats.h',
                       'src/core/ext/census/gen/census.pb.h',
                       'src/core/ext/census/gen/census.pb.h',
+                      'src/core/ext/census/gen/trace_context.pb.h',
                       'src/core/ext/census/grpc_filter.h',
                       'src/core/ext/census/grpc_filter.h',
                       'src/core/ext/census/mlog.h',
                       'src/core/ext/census/mlog.h',
                       'src/core/ext/census/resource.h',
                       'src/core/ext/census/resource.h',
@@ -560,7 +560,6 @@ Pod::Spec.new do |s|
                       'src/core/ext/client_config/channel_connectivity.c',
                       'src/core/ext/client_config/channel_connectivity.c',
                       'src/core/ext/client_config/client_channel.c',
                       'src/core/ext/client_config/client_channel.c',
                       'src/core/ext/client_config/client_channel_factory.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/client_config_plugin.c',
                       'src/core/ext/client_config/connector.c',
                       'src/core/ext/client_config/connector.c',
                       'src/core/ext/client_config/default_initial_connect_string.c',
                       'src/core/ext/client_config/default_initial_connect_string.c',
@@ -572,8 +571,8 @@ Pod::Spec.new do |s|
                       'src/core/ext/client_config/resolver.c',
                       'src/core/ext/client_config/resolver.c',
                       'src/core/ext/client_config/resolver_factory.c',
                       'src/core/ext/client_config/resolver_factory.c',
                       'src/core/ext/client_config/resolver_registry.c',
                       'src/core/ext/client_config/resolver_registry.c',
+                      'src/core/ext/client_config/resolver_result.c',
                       'src/core/ext/client_config/subchannel.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/subchannel_index.c',
                       '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',
@@ -595,6 +594,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/census/base_resources.c',
                       'src/core/ext/census/base_resources.c',
                       'src/core/ext/census/context.c',
                       'src/core/ext/census/context.c',
                       'src/core/ext/census/gen/census.pb.c',
                       'src/core/ext/census/gen/census.pb.c',
+                      'src/core/ext/census/gen/trace_context.pb.c',
                       'src/core/ext/census/grpc_context.c',
                       'src/core/ext/census/grpc_context.c',
                       'src/core/ext/census/grpc_filter.c',
                       'src/core/ext/census/grpc_filter.c',
                       'src/core/ext/census/grpc_plugin.c',
                       'src/core/ext/census/grpc_plugin.c',
@@ -746,7 +746,6 @@ Pod::Spec.new do |s|
                               'src/core/lib/tsi/transport_security_interface.h',
                               'src/core/lib/tsi/transport_security_interface.h',
                               'src/core/ext/client_config/client_channel.h',
                               'src/core/ext/client_config/client_channel.h',
                               'src/core/ext/client_config/client_channel_factory.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/connector.h',
                               'src/core/ext/client_config/initial_connect_string.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.h',
@@ -756,8 +755,8 @@ Pod::Spec.new do |s|
                               'src/core/ext/client_config/resolver.h',
                               'src/core/ext/client_config/resolver.h',
                               'src/core/ext/client_config/resolver_factory.h',
                               'src/core/ext/client_config/resolver_factory.h',
                               'src/core/ext/client_config/resolver_registry.h',
                               'src/core/ext/client_config/resolver_registry.h',
+                              'src/core/ext/client_config/resolver_result.h',
                               'src/core/ext/client_config/subchannel.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/subchannel_index.h',
                               'src/core/ext/client_config/uri_parser.h',
                               'src/core/ext/client_config/uri_parser.h',
                               'src/core/ext/lb_policy/grpclb/grpclb.h',
                               'src/core/ext/lb_policy/grpclb/grpclb.h',
@@ -774,6 +773,7 @@ Pod::Spec.new do |s|
                               'src/core/ext/census/census_interface.h',
                               'src/core/ext/census/census_interface.h',
                               'src/core/ext/census/census_rpc_stats.h',
                               'src/core/ext/census/census_rpc_stats.h',
                               'src/core/ext/census/gen/census.pb.h',
                               'src/core/ext/census/gen/census.pb.h',
+                              'src/core/ext/census/gen/trace_context.pb.h',
                               'src/core/ext/census/grpc_filter.h',
                               'src/core/ext/census/grpc_filter.h',
                               'src/core/ext/census/mlog.h',
                               'src/core/ext/census/mlog.h',
                               'src/core/ext/census/resource.h',
                               'src/core/ext/census/resource.h',

+ 5 - 3
gRPC-ProtoRPC.podspec

@@ -30,7 +30,7 @@
 
 
 Pod::Spec.new do |s|
 Pod::Spec.new do |s|
   s.name     = 'gRPC-ProtoRPC'
   s.name     = 'gRPC-ProtoRPC'
-  version = '1.0.0-pre1'
+  version = '1.0.0'
   s.version  = version
   s.version  = version
   s.summary  = 'RPC library for Protocol Buffers, based on gRPC'
   s.summary  = 'RPC library for Protocol Buffers, based on gRPC'
   s.homepage = 'http://www.grpc.io'
   s.homepage = 'http://www.grpc.io'
@@ -39,7 +39,7 @@ Pod::Spec.new do |s|
 
 
   s.source = {
   s.source = {
     :git => 'https://github.com/grpc/grpc.git',
     :git => 'https://github.com/grpc/grpc.git',
-    :tag => "objective-c-v#{version}",
+    :tag => "v#{version}",
   }
   }
 
 
   s.ios.deployment_target = '7.1'
   s.ios.deployment_target = '7.1'
@@ -56,8 +56,10 @@ Pod::Spec.new do |s|
   s.dependency 'gRPC', version
   s.dependency 'gRPC', version
   s.dependency 'gRPC-RxLibrary', version
   s.dependency 'gRPC-RxLibrary', version
   s.dependency 'Protobuf', '~> 3.0'
   s.dependency 'Protobuf', '~> 3.0'
-  # This is needed by all pods that depend on Protobuf:
   s.pod_target_xcconfig = {
   s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on Protobuf:
     'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
     'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
   }
   }
 end
 end

+ 2 - 2
gRPC-RxLibrary.podspec

@@ -30,7 +30,7 @@
 
 
 Pod::Spec.new do |s|
 Pod::Spec.new do |s|
   s.name     = 'gRPC-RxLibrary'
   s.name     = 'gRPC-RxLibrary'
-  version = '1.0.0-pre1'
+  version = '1.0.0'
   s.version  = version
   s.version  = version
   s.summary  = 'Reactive Extensions library for iOS/OSX.'
   s.summary  = 'Reactive Extensions library for iOS/OSX.'
   s.homepage = 'http://www.grpc.io'
   s.homepage = 'http://www.grpc.io'
@@ -39,7 +39,7 @@ Pod::Spec.new do |s|
 
 
   s.source = {
   s.source = {
     :git => 'https://github.com/grpc/grpc.git',
     :git => 'https://github.com/grpc/grpc.git',
-    :tag => "objective-c-v#{version}",
+    :tag => "v#{version}",
   }
   }
 
 
   s.ios.deployment_target = '7.1'
   s.ios.deployment_target = '7.1'

+ 7 - 2
gRPC.podspec

@@ -30,7 +30,7 @@
 
 
 Pod::Spec.new do |s|
 Pod::Spec.new do |s|
   s.name     = 'gRPC'
   s.name     = 'gRPC'
-  version = '1.0.0-pre1'
+  version = '1.0.0'
   s.version  = version
   s.version  = version
   s.summary  = 'gRPC client library for iOS/OSX'
   s.summary  = 'gRPC client library for iOS/OSX'
   s.homepage = 'http://www.grpc.io'
   s.homepage = 'http://www.grpc.io'
@@ -39,7 +39,7 @@ Pod::Spec.new do |s|
 
 
   s.source = {
   s.source = {
     :git => 'https://github.com/grpc/grpc.git',
     :git => 'https://github.com/grpc/grpc.git',
-    :tag => "objective-c-v#{version}",
+    :tag => "v#{version}",
   }
   }
 
 
   s.ios.deployment_target = '7.1'
   s.ios.deployment_target = '7.1'
@@ -59,4 +59,9 @@ Pod::Spec.new do |s|
 
 
   # Certificates, to be able to establish TLS connections:
   # Certificates, to be able to establish TLS connections:
   s.resource_bundles = { 'gRPCCertificates' => ['etc/roots.pem'] }
   s.resource_bundles = { 'gRPCCertificates' => ['etc/roots.pem'] }
+
+  s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
+  }
 end
 end

+ 1 - 0
grpc.def

@@ -42,6 +42,7 @@ EXPORTS
     grpc_init
     grpc_init
     grpc_shutdown
     grpc_shutdown
     grpc_version_string
     grpc_version_string
+    grpc_g_stands_for
     grpc_completion_queue_create
     grpc_completion_queue_create
     grpc_completion_queue_next
     grpc_completion_queue_next
     grpc_completion_queue_pluck
     grpc_completion_queue_pluck

+ 5 - 5
grpc.gemspec

@@ -148,6 +148,7 @@ Gem::Specification.new do |s|
   s.files += %w( include/grpc/compression.h )
   s.files += %w( include/grpc/compression.h )
   s.files += %w( include/grpc/grpc.h )
   s.files += %w( include/grpc/grpc.h )
   s.files += %w( include/grpc/grpc_posix.h )
   s.files += %w( include/grpc/grpc_posix.h )
+  s.files += %w( include/grpc/grpc_security_constants.h )
   s.files += %w( include/grpc/status.h )
   s.files += %w( include/grpc/status.h )
   s.files += %w( include/grpc/impl/codegen/byte_buffer.h )
   s.files += %w( include/grpc/impl/codegen/byte_buffer.h )
   s.files += %w( include/grpc/impl/codegen/byte_buffer_reader.h )
   s.files += %w( include/grpc/impl/codegen/byte_buffer_reader.h )
@@ -171,7 +172,6 @@ Gem::Specification.new do |s|
   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_security.h )
   s.files += %w( include/grpc/grpc_security.h )
-  s.files += %w( include/grpc/grpc_security_constants.h )
   s.files += %w( include/grpc/census.h )
   s.files += %w( include/grpc/census.h )
   s.files += %w( src/core/lib/channel/channel_args.h )
   s.files += %w( src/core/lib/channel/channel_args.h )
   s.files += %w( src/core/lib/channel/channel_stack.h )
   s.files += %w( src/core/lib/channel/channel_stack.h )
@@ -301,7 +301,6 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/tsi/transport_security_interface.h )
   s.files += %w( src/core/lib/tsi/transport_security_interface.h )
   s.files += %w( src/core/ext/client_config/client_channel.h )
   s.files += %w( src/core/ext/client_config/client_channel.h )
   s.files += %w( src/core/ext/client_config/client_channel_factory.h )
   s.files += %w( src/core/ext/client_config/client_channel_factory.h )
-  s.files += %w( src/core/ext/client_config/client_config.h )
   s.files += %w( src/core/ext/client_config/connector.h )
   s.files += %w( src/core/ext/client_config/connector.h )
   s.files += %w( src/core/ext/client_config/initial_connect_string.h )
   s.files += %w( src/core/ext/client_config/initial_connect_string.h )
   s.files += %w( src/core/ext/client_config/lb_policy.h )
   s.files += %w( src/core/ext/client_config/lb_policy.h )
@@ -311,8 +310,8 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/client_config/resolver.h )
   s.files += %w( src/core/ext/client_config/resolver.h )
   s.files += %w( src/core/ext/client_config/resolver_factory.h )
   s.files += %w( src/core/ext/client_config/resolver_factory.h )
   s.files += %w( src/core/ext/client_config/resolver_registry.h )
   s.files += %w( src/core/ext/client_config/resolver_registry.h )
+  s.files += %w( src/core/ext/client_config/resolver_result.h )
   s.files += %w( src/core/ext/client_config/subchannel.h )
   s.files += %w( src/core/ext/client_config/subchannel.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( src/core/ext/lb_policy/grpclb/grpclb.h )
   s.files += %w( src/core/ext/lb_policy/grpclb/grpclb.h )
@@ -329,6 +328,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/census/census_interface.h )
   s.files += %w( src/core/ext/census/census_interface.h )
   s.files += %w( src/core/ext/census/census_rpc_stats.h )
   s.files += %w( src/core/ext/census/census_rpc_stats.h )
   s.files += %w( src/core/ext/census/gen/census.pb.h )
   s.files += %w( src/core/ext/census/gen/census.pb.h )
+  s.files += %w( src/core/ext/census/gen/trace_context.pb.h )
   s.files += %w( src/core/ext/census/grpc_filter.h )
   s.files += %w( src/core/ext/census/grpc_filter.h )
   s.files += %w( src/core/ext/census/mlog.h )
   s.files += %w( src/core/ext/census/mlog.h )
   s.files += %w( src/core/ext/census/resource.h )
   s.files += %w( src/core/ext/census/resource.h )
@@ -479,7 +479,6 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/client_config/channel_connectivity.c )
   s.files += %w( src/core/ext/client_config/channel_connectivity.c )
   s.files += %w( src/core/ext/client_config/client_channel.c )
   s.files += %w( src/core/ext/client_config/client_channel.c )
   s.files += %w( src/core/ext/client_config/client_channel_factory.c )
   s.files += %w( src/core/ext/client_config/client_channel_factory.c )
-  s.files += %w( src/core/ext/client_config/client_config.c )
   s.files += %w( src/core/ext/client_config/client_config_plugin.c )
   s.files += %w( src/core/ext/client_config/client_config_plugin.c )
   s.files += %w( src/core/ext/client_config/connector.c )
   s.files += %w( src/core/ext/client_config/connector.c )
   s.files += %w( src/core/ext/client_config/default_initial_connect_string.c )
   s.files += %w( src/core/ext/client_config/default_initial_connect_string.c )
@@ -491,8 +490,8 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/client_config/resolver.c )
   s.files += %w( src/core/ext/client_config/resolver.c )
   s.files += %w( src/core/ext/client_config/resolver_factory.c )
   s.files += %w( src/core/ext/client_config/resolver_factory.c )
   s.files += %w( src/core/ext/client_config/resolver_registry.c )
   s.files += %w( src/core/ext/client_config/resolver_registry.c )
+  s.files += %w( src/core/ext/client_config/resolver_result.c )
   s.files += %w( src/core/ext/client_config/subchannel.c )
   s.files += %w( src/core/ext/client_config/subchannel.c )
-  s.files += %w( src/core/ext/client_config/subchannel_call_holder.c )
   s.files += %w( src/core/ext/client_config/subchannel_index.c )
   s.files += %w( src/core/ext/client_config/subchannel_index.c )
   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 )
@@ -514,6 +513,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/census/base_resources.c )
   s.files += %w( src/core/ext/census/base_resources.c )
   s.files += %w( src/core/ext/census/context.c )
   s.files += %w( src/core/ext/census/context.c )
   s.files += %w( src/core/ext/census/gen/census.pb.c )
   s.files += %w( src/core/ext/census/gen/census.pb.c )
+  s.files += %w( src/core/ext/census/gen/trace_context.pb.c )
   s.files += %w( src/core/ext/census/grpc_context.c )
   s.files += %w( src/core/ext/census/grpc_context.c )
   s.files += %w( src/core/ext/census/grpc_filter.c )
   s.files += %w( src/core/ext/census/grpc_filter.c )
   s.files += %w( src/core/ext/census/grpc_plugin.c )
   s.files += %w( src/core/ext/census/grpc_plugin.c )

+ 0 - 1
include/grpc++/create_channel.h

@@ -48,7 +48,6 @@ namespace grpc {
 /// \param target The URI of the endpoint to connect to.
 /// \param target The URI of the endpoint to connect to.
 /// \param creds Credentials to use for the created channel. If it does not hold
 /// \param creds Credentials to use for the created channel. If it does not hold
 /// an object or is invalid, a lame channel is returned.
 /// an object or is invalid, a lame channel is returned.
-/// \param args Options for channel creation.
 std::shared_ptr<Channel> CreateChannel(
 std::shared_ptr<Channel> CreateChannel(
     const grpc::string& target,
     const grpc::string& target,
     const std::shared_ptr<ChannelCredentials>& creds);
     const std::shared_ptr<ChannelCredentials>& creds);

+ 4 - 0
include/grpc++/grpc++.h

@@ -51,6 +51,9 @@
 #ifndef GRPCXX_GRPCXX_H
 #ifndef GRPCXX_GRPCXX_H
 #define GRPCXX_GRPCXX_H
 #define GRPCXX_GRPCXX_H
 
 
+// Pragma for http://include-what-you-use.org/ tool, tells that following
+// headers are not private for grpc++.h and are part of its interface.
+// IWYU pragma: begin_exports
 #include <grpc/grpc.h>
 #include <grpc/grpc.h>
 
 
 #include <grpc++/channel.h>
 #include <grpc++/channel.h>
@@ -62,5 +65,6 @@
 #include <grpc++/server_builder.h>
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
 #include <grpc++/server_context.h>
 #include <grpc++/server_posix.h>
 #include <grpc++/server_posix.h>
+// IWYU pragma: end_exports
 
 
 #endif  // GRPCXX_GRPCXX_H
 #endif  // GRPCXX_GRPCXX_H

+ 5 - 1
include/grpc++/impl/codegen/client_context.h

@@ -271,7 +271,7 @@ class ClientContext {
 
 
   /// Set \a algorithm to be the compression algorithm used for the client call.
   /// Set \a algorithm to be the compression algorithm used for the client call.
   ///
   ///
-  /// \param algorith The compression algorithm used for the client call.
+  /// \param algorithm The compression algorithm used for the client call.
   void set_compression_algorithm(grpc_compression_algorithm algorithm);
   void set_compression_algorithm(grpc_compression_algorithm algorithm);
 
 
   /// Return the peer uri in a string.
   /// Return the peer uri in a string.
@@ -307,6 +307,10 @@ class ClientContext {
   };
   };
   static void SetGlobalCallbacks(GlobalCallbacks* callbacks);
   static void SetGlobalCallbacks(GlobalCallbacks* callbacks);
 
 
+  // Should be used for framework-level extensions only.
+  // Applications never need to call this method.
+  grpc_call* c_call() { return call_; }
+
  private:
  private:
   // Disallow copy and assign.
   // Disallow copy and assign.
   ClientContext(const ClientContext&);
   ClientContext(const ClientContext&);

+ 4 - 0
include/grpc++/impl/codegen/server_context.h

@@ -166,6 +166,10 @@ class ServerContext {
     async_notify_when_done_tag_ = tag;
     async_notify_when_done_tag_ = tag;
   }
   }
 
 
+  // Should be used for framework-level extensions only.
+  // Applications never need to call this method.
+  grpc_call* c_call() { return call_; }
+
  private:
  private:
   friend class ::grpc::testing::InteropServerContextInspector;
   friend class ::grpc::testing::InteropServerContextInspector;
   friend class ::grpc::ServerInterface;
   friend class ::grpc::ServerInterface;

+ 30 - 7
include/grpc++/impl/codegen/sync_stream.h

@@ -64,6 +64,15 @@ class ClientStreamingInterface {
   virtual Status Finish() = 0;
   virtual Status Finish() = 0;
 };
 };
 
 
+/// Common interface for all synchronous server side streaming.
+class ServerStreamingInterface {
+ public:
+  virtual ~ServerStreamingInterface() {}
+
+  /// Blocking send initial metadata to client.
+  virtual void SendInitialMetadata() = 0;
+};
+
 /// An interface that yields a sequence of messages of type \a R.
 /// An interface that yields a sequence of messages of type \a R.
 template <class R>
 template <class R>
 class ReaderInterface {
 class ReaderInterface {
@@ -336,12 +345,17 @@ class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface<W, R> {
   Call call_;
   Call call_;
 };
 };
 
 
+/// Server-side interface for streaming reads of message of type \a R.
+template <class R>
+class ServerReaderInterface : public ServerStreamingInterface,
+                              public ReaderInterface<R> {};
+
 template <class R>
 template <class R>
-class ServerReader GRPC_FINAL : public ReaderInterface<R> {
+class ServerReader GRPC_FINAL : public ServerReaderInterface<R> {
  public:
  public:
   ServerReader(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
   ServerReader(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
 
 
-  void SendInitialMetadata() {
+  void SendInitialMetadata() GRPC_OVERRIDE {
     GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
     GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
 
 
     CallOpSet<CallOpSendInitialMetadata> ops;
     CallOpSet<CallOpSendInitialMetadata> ops;
@@ -367,12 +381,17 @@ class ServerReader GRPC_FINAL : public ReaderInterface<R> {
   ServerContext* const ctx_;
   ServerContext* const ctx_;
 };
 };
 
 
+/// Server-side interface for streaming writes of message of type \a W.
 template <class W>
 template <class W>
-class ServerWriter GRPC_FINAL : public WriterInterface<W> {
+class ServerWriterInterface : public ServerStreamingInterface,
+                              public WriterInterface<W> {};
+
+template <class W>
+class ServerWriter GRPC_FINAL : public ServerWriterInterface<W> {
  public:
  public:
   ServerWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
   ServerWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
 
 
-  void SendInitialMetadata() {
+  void SendInitialMetadata() GRPC_OVERRIDE {
     GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
     GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
 
 
     CallOpSet<CallOpSendInitialMetadata> ops;
     CallOpSet<CallOpSendInitialMetadata> ops;
@@ -411,12 +430,16 @@ class ServerWriter GRPC_FINAL : public WriterInterface<W> {
 
 
 /// Server-side interface for bi-directional streaming.
 /// Server-side interface for bi-directional streaming.
 template <class W, class R>
 template <class W, class R>
-class ServerReaderWriter GRPC_FINAL : public WriterInterface<W>,
-                                      public ReaderInterface<R> {
+class ServerReaderWriterInterface : public ServerStreamingInterface,
+                                    public WriterInterface<W>,
+                                    public ReaderInterface<R> {};
+
+template <class W, class R>
+class ServerReaderWriter GRPC_FINAL : public ServerReaderWriterInterface<W, R> {
  public:
  public:
   ServerReaderWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
   ServerReaderWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
 
 
-  void SendInitialMetadata() {
+  void SendInitialMetadata() GRPC_OVERRIDE {
     GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
     GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
 
 
     CallOpSet<CallOpSendInitialMetadata> ops;
     CallOpSet<CallOpSendInitialMetadata> ops;

+ 5 - 0
include/grpc++/impl/server_builder_plugin.h

@@ -41,6 +41,7 @@
 namespace grpc {
 namespace grpc {
 
 
 class ServerInitializer;
 class ServerInitializer;
+class ChannelArguments;
 
 
 class ServerBuilderPlugin {
 class ServerBuilderPlugin {
  public:
  public:
@@ -58,6 +59,10 @@ class ServerBuilderPlugin {
   // ServerBuilderOption::UpdatePlugins
   // ServerBuilderOption::UpdatePlugins
   virtual void ChangeArguments(const grpc::string& name, void* value) = 0;
   virtual void ChangeArguments(const grpc::string& name, void* value) = 0;
 
 
+  // UpdateChannelArguments will be called in ServerBuilder::BuildAndStart(),
+  // before the Server instance is created.
+  virtual void UpdateChannelArguments(ChannelArguments* args) {}
+
   virtual bool has_sync_methods() const { return false; }
   virtual bool has_sync_methods() const { return false; }
   virtual bool has_async_methods() const { return false; }
   virtual bool has_async_methods() const { return false; }
 };
 };

+ 3 - 0
include/grpc/grpc.h

@@ -90,6 +90,9 @@ GRPCAPI void grpc_shutdown(void);
 /** Return a string representing the current version of grpc */
 /** Return a string representing the current version of grpc */
 GRPCAPI const char *grpc_version_string(void);
 GRPCAPI const char *grpc_version_string(void);
 
 
+/** Return a string specifying what the 'g' in gRPC stands for */
+GRPCAPI const char *grpc_g_stands_for(void);
+
 /** Create a completion queue */
 /** Create a completion queue */
 GRPCAPI grpc_completion_queue *grpc_completion_queue_create(void *reserved);
 GRPCAPI grpc_completion_queue *grpc_completion_queue_create(void *reserved);
 
 

+ 7 - 3
include/grpc/impl/codegen/grpc_types.h

@@ -222,10 +222,14 @@ typedef enum grpc_call_error {
 #define GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST (0x00000010u)
 #define GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST (0x00000010u)
 /** Signal that the call should not return UNAVAILABLE before it has started */
 /** Signal that the call should not return UNAVAILABLE before it has started */
 #define GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY (0x00000020u)
 #define GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY (0x00000020u)
+/** Signal that the call is cacheable. GRPC is free to use GET verb */
+#define GRPC_INITIAL_METADATA_CACHEABLE_REQUEST (0x00000040u)
+
 /** Mask of all valid flags */
 /** Mask of all valid flags */
-#define GRPC_INITIAL_METADATA_USED_MASK       \
-  (GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST | \
-   GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY)
+#define GRPC_INITIAL_METADATA_USED_MASK        \
+  (GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST |  \
+   GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY | \
+   GRPC_INITIAL_METADATA_CACHEABLE_REQUEST)
 
 
 /** A single metadata element */
 /** A single metadata element */
 typedef struct grpc_metadata {
 typedef struct grpc_metadata {

+ 39 - 9
package.xml

@@ -10,11 +10,11 @@
   <email>grpc-packages@google.com</email>
   <email>grpc-packages@google.com</email>
   <active>yes</active>
   <active>yes</active>
  </lead>
  </lead>
- <date>2016-08-09</date>
+ <date>2016-08-22</date>
  <time>16:06:07</time>
  <time>16:06:07</time>
  <version>
  <version>
-  <release>1.1.0</release>
-  <api>1.1.0</api>
+  <release>1.1.0dev</release>
+  <api>1.1.0dev</api>
  </version>
  </version>
  <stability>
  <stability>
   <release>stable</release>
   <release>stable</release>
@@ -22,7 +22,7 @@
  </stability>
  </stability>
  <license>BSD</license>
  <license>BSD</license>
  <notes>
  <notes>
-- Fixed Ubuntu compile error #7571, #7642
+- Reject metadata keys which are not legal #7881
  </notes>
  </notes>
  <contents>
  <contents>
   <dir baseinstalldir="/" name="/">
   <dir baseinstalldir="/" name="/">
@@ -156,6 +156,7 @@
     <file baseinstalldir="/" name="include/grpc/compression.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/compression.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc_posix.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc_posix.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/grpc_security_constants.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/status.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/status.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/byte_buffer.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/byte_buffer.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/byte_buffer_reader.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/byte_buffer_reader.h" role="src" />
@@ -179,7 +180,6 @@
     <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_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/census.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/census.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/channel_args.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/channel_args.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/channel_stack.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/channel_stack.h" role="src" />
@@ -309,7 +309,6 @@
     <file baseinstalldir="/" name="src/core/lib/tsi/transport_security_interface.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/tsi/transport_security_interface.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/client_channel.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/client_channel.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/client_channel_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/client_channel_factory.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_config/client_config.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/connector.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/connector.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/initial_connect_string.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/initial_connect_string.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/lb_policy.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/lb_policy.h" role="src" />
@@ -319,8 +318,8 @@
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_registry.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_registry.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/client_config/resolver_result.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel.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="src/core/ext/lb_policy/grpclb/grpclb.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/grpclb.h" role="src" />
@@ -337,6 +336,7 @@
     <file baseinstalldir="/" name="src/core/ext/census/census_interface.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/census_interface.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/census_rpc_stats.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/census_rpc_stats.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/gen/census.pb.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/gen/census.pb.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/census/gen/trace_context.pb.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/grpc_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/grpc_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/mlog.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/mlog.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/resource.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/resource.h" role="src" />
@@ -487,7 +487,6 @@
     <file baseinstalldir="/" name="src/core/ext/client_config/channel_connectivity.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/channel_connectivity.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/client_channel.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/client_channel.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/client_channel_factory.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/client_channel_factory.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_config/client_config.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/client_config_plugin.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/client_config_plugin.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/connector.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/connector.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/default_initial_connect_string.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/default_initial_connect_string.c" role="src" />
@@ -499,8 +498,8 @@
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_factory.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_factory.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_registry.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_registry.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/client_config/resolver_result.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_config/subchannel_call_holder.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel_index.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel_index.c" role="src" />
     <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" />
@@ -522,6 +521,7 @@
     <file baseinstalldir="/" name="src/core/ext/census/base_resources.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/base_resources.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/context.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/context.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/gen/census.pb.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/gen/census.pb.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/census/gen/trace_context.pb.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/grpc_context.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/grpc_context.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/grpc_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/grpc_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/grpc_plugin.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/grpc_plugin.c" role="src" />
@@ -1158,5 +1158,35 @@ Update to wrap gRPC C Core version 0.10.0
 - Fixed Ubuntu compile error #7571, #7642
 - Fixed Ubuntu compile error #7571, #7642
    </notes>
    </notes>
   </release>
   </release>
+  <release>
+   <version>
+    <release>1.0.0</release>
+    <api>1.0.0</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2016-08-18</date>
+   <license>BSD</license>
+   <notes>
+- gRPC 1.0.0 release
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>1.1.0dev</release>
+    <api>1.1.0dev</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2016-08-22</date>
+   <license>BSD</license>
+   <notes>
+- Reject metadata keys which are not legal #7881
+   </notes>
+  </release>
  </changelog>
  </changelog>
 </package>
 </package>

+ 19 - 18
setup.py

@@ -28,7 +28,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.
 
 
 """A setup module for the GRPC Python package."""
 """A setup module for the GRPC Python package."""
-
+from distutils import cygwinccompiler
 from distutils import extension as _extension
 from distutils import extension as _extension
 from distutils import util
 from distutils import util
 import os
 import os
@@ -58,14 +58,12 @@ os.chdir(os.path.dirname(os.path.abspath(__file__)))
 sys.path.insert(0, os.path.abspath(PYTHON_STEM))
 sys.path.insert(0, os.path.abspath(PYTHON_STEM))
 
 
 # Break import-style to ensure we can actually find our in-repo dependencies.
 # Break import-style to ensure we can actually find our in-repo dependencies.
-import _unixccompiler_patch
+import _spawn_patch
 import commands
 import commands
 import grpc_core_dependencies
 import grpc_core_dependencies
 import grpc_version
 import grpc_version
 
 
-if 'win32' in sys.platform:
-  _unixccompiler_patch.monkeypatch_unix_compiler()
-
+_spawn_patch.monkeypatch_spawn()
 
 
 LICENSE = '3-clause BSD'
 LICENSE = '3-clause BSD'
 
 
@@ -91,8 +89,8 @@ ENABLE_CYTHON_TRACING = os.environ.get(
 EXTRA_ENV_COMPILE_ARGS = os.environ.get('GRPC_PYTHON_CFLAGS', None)
 EXTRA_ENV_COMPILE_ARGS = os.environ.get('GRPC_PYTHON_CFLAGS', None)
 EXTRA_ENV_LINK_ARGS = os.environ.get('GRPC_PYTHON_LDFLAGS', None)
 EXTRA_ENV_LINK_ARGS = os.environ.get('GRPC_PYTHON_LDFLAGS', None)
 if EXTRA_ENV_COMPILE_ARGS is None:
 if EXTRA_ENV_COMPILE_ARGS is None:
-  EXTRA_ENV_COMPILE_ARGS = '-fno-wrapv'
-  if 'win32' in sys.platform:
+  EXTRA_ENV_COMPILE_ARGS = ''
+  if 'win32' in sys.platform and sys.version_info < (3, 5):
     # We use define flags here and don't directly add to DEFINE_MACROS below to
     # We use define flags here and don't directly add to DEFINE_MACROS below to
     # ensure that the expert user/builder has a way of turning it off (via the
     # ensure that the expert user/builder has a way of turning it off (via the
     # envvars) without adding yet more GRPC-specific envvars.
     # envvars) without adding yet more GRPC-specific envvars.
@@ -102,21 +100,21 @@ if EXTRA_ENV_COMPILE_ARGS is None:
     else:
     else:
       EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime64 -D_timeb=__timeb64'
       EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime64 -D_timeb=__timeb64'
   elif "linux" in sys.platform or "darwin" in sys.platform:
   elif "linux" in sys.platform or "darwin" in sys.platform:
-    EXTRA_ENV_COMPILE_ARGS += ' -fvisibility=hidden'
+    EXTRA_ENV_COMPILE_ARGS += ' -fvisibility=hidden -fno-wrapv'
 if EXTRA_ENV_LINK_ARGS is None:
 if EXTRA_ENV_LINK_ARGS is None:
-  EXTRA_ENV_LINK_ARGS = '-lpthread'
-  if 'win32' in sys.platform:
-    # TODO(atash) check if this is actually safe to just import and call on
-    # non-Windows (to avoid breaking import style)
-    from distutils.cygwinccompiler import get_msvcr
-    msvcr = get_msvcr()[0]
+  EXTRA_ENV_LINK_ARGS = ''
+  if "linux" in sys.platform or "darwin" in sys.platform:
+    EXTRA_ENV_LINK_ARGS += ' -lpthread'
+  elif "win32" in sys.platform and sys.version_info < (3, 5):
+    msvcr = cygwinccompiler.get_msvcr()[0]
     # TODO(atash) sift through the GCC specs to see if libstdc++ can have any
     # TODO(atash) sift through the GCC specs to see if libstdc++ can have any
     # influence on the linkage outcome on MinGW for non-C++ programs.
     # influence on the linkage outcome on MinGW for non-C++ programs.
     EXTRA_ENV_LINK_ARGS += (
     EXTRA_ENV_LINK_ARGS += (
         ' -static-libgcc -static-libstdc++ -mcrtdll={msvcr} '
         ' -static-libgcc -static-libstdc++ -mcrtdll={msvcr} '
         '-static'.format(msvcr=msvcr))
         '-static'.format(msvcr=msvcr))
-  elif "linux" in sys.platform:
+  if "linux" in sys.platform:
     EXTRA_ENV_LINK_ARGS += ' -Wl,-wrap,memcpy'
     EXTRA_ENV_LINK_ARGS += ' -Wl,-wrap,memcpy'
+
 EXTRA_COMPILE_ARGS = shlex.split(EXTRA_ENV_COMPILE_ARGS)
 EXTRA_COMPILE_ARGS = shlex.split(EXTRA_ENV_COMPILE_ARGS)
 EXTRA_LINK_ARGS = shlex.split(EXTRA_ENV_LINK_ARGS)
 EXTRA_LINK_ARGS = shlex.split(EXTRA_ENV_LINK_ARGS)
 
 
@@ -137,15 +135,19 @@ if "linux" in sys.platform:
 if not "win32" in sys.platform:
 if not "win32" in sys.platform:
   EXTENSION_LIBRARIES += ('m',)
   EXTENSION_LIBRARIES += ('m',)
 if "win32" in sys.platform:
 if "win32" in sys.platform:
-  EXTENSION_LIBRARIES += ('ws2_32',)
+  EXTENSION_LIBRARIES += ('advapi32', 'ws2_32',)
 
 
 DEFINE_MACROS = (
 DEFINE_MACROS = (
     ('OPENSSL_NO_ASM', 1), ('_WIN32_WINNT', 0x600),
     ('OPENSSL_NO_ASM', 1), ('_WIN32_WINNT', 0x600),
     ('GPR_BACKWARDS_COMPATIBILITY_MODE', 1),)
     ('GPR_BACKWARDS_COMPATIBILITY_MODE', 1),)
 if "win32" in sys.platform:
 if "win32" in sys.platform:
-  DEFINE_MACROS += (('OPENSSL_WINDOWS', 1), ('WIN32_LEAN_AND_MEAN', 1),)
+  DEFINE_MACROS += (('WIN32_LEAN_AND_MEAN', 1),)
   if '64bit' in platform.architecture()[0]:
   if '64bit' in platform.architecture()[0]:
     DEFINE_MACROS += (('MS_WIN64', 1),)
     DEFINE_MACROS += (('MS_WIN64', 1),)
+  elif sys.version_info >= (3, 5):
+    # For some reason, this is needed to get access to inet_pton/inet_ntop
+    # on msvc, but only for 32 bits
+    DEFINE_MACROS += (('NTDDI_VERSION', 0x06000000),)
 
 
 LDFLAGS = tuple(EXTRA_LINK_ARGS)
 LDFLAGS = tuple(EXTRA_LINK_ARGS)
 CFLAGS = tuple(EXTRA_COMPILE_ARGS)
 CFLAGS = tuple(EXTRA_COMPILE_ARGS)
@@ -154,7 +156,6 @@ if "linux" in sys.platform or "darwin" in sys.platform:
   pymodinit = '__attribute__((visibility ("default"))) {}'.format(pymodinit_type)
   pymodinit = '__attribute__((visibility ("default"))) {}'.format(pymodinit_type)
   DEFINE_MACROS += (('PyMODINIT_FUNC', pymodinit),)
   DEFINE_MACROS += (('PyMODINIT_FUNC', pymodinit),)
 
 
-
 # By default, Python3 distutils enforces compatibility of
 # By default, Python3 distutils enforces compatibility of
 # c plugins (.so files) with the OSX version Python3 was built with.
 # c plugins (.so files) with the OSX version Python3 was built with.
 # For Python3.4, this is OSX 10.6, but we need Thread Local Support (__thread)
 # For Python3.4, this is OSX 10.6, but we need Thread Local Support (__thread)

+ 4 - 0
src/core/ext/census/gen/README.md

@@ -4,3 +4,7 @@ Files generated for use by Census stats and trace recording subsystem.
 * census.pb.{h,c} - Generated from src/core/ext/census/census.proto, using the
 * census.pb.{h,c} - Generated from src/core/ext/census/census.proto, using the
   script `tools/codegen/core/gen_nano_proto.sh src/proto/census/census.proto
   script `tools/codegen/core/gen_nano_proto.sh src/proto/census/census.proto
   $PWD/src/core/ext/census/gen src/core/ext/census/gen`
   $PWD/src/core/ext/census/gen src/core/ext/census/gen`
+* trace_context.pb.{h,c} - Generated from
+  src/core/ext/census/trace_context.proto, using the script
+  `tools/codegen/core/gen_nano_proto.sh src/proto/census/trace_context.proto
+  $PWD/src/core/ext/census/gen src/core/ext/census/gen`

+ 81 - 0
src/core/ext/census/gen/trace_context.pb.c

@@ -0,0 +1,81 @@
+/*
+ *
+ * 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.
+ *
+ */
+/* Automatically generated nanopb constant definitions */
+/* Generated by nanopb-0.3.5-dev */
+
+#include "src/core/ext/census/gen/trace_context.pb.h"
+
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+
+
+const pb_field_t google_trace_TraceId_fields[3] = {
+    PB_FIELD(  1, FIXED64 , OPTIONAL, STATIC  , FIRST, google_trace_TraceId, hi, hi, 0),
+    PB_FIELD(  2, FIXED64 , OPTIONAL, STATIC  , OTHER, google_trace_TraceId, lo, hi, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_trace_TraceContext_fields[4] = {
+    PB_FIELD(  1, MESSAGE , OPTIONAL, STATIC  , FIRST, google_trace_TraceContext, trace_id, trace_id, &google_trace_TraceId_fields),
+    PB_FIELD(  2, FIXED64 , OPTIONAL, STATIC  , OTHER, google_trace_TraceContext, span_id, trace_id, 0),
+    PB_FIELD(  3, BOOL    , OPTIONAL, STATIC  , OTHER, google_trace_TraceContext, is_sampled, span_id, 0),
+    PB_LAST_FIELD
+};
+
+
+/* Check that field information fits in pb_field_t */
+#if !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_32BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ * 
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in 8 or 16 bit
+ * field descriptors.
+ */
+PB_STATIC_ASSERT((pb_membersize(google_trace_TraceContext, trace_id) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_trace_TraceId_google_trace_TraceContext)
+#endif
+
+#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_16BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ * 
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in the default
+ * 8 bit descriptors.
+ */
+PB_STATIC_ASSERT((pb_membersize(google_trace_TraceContext, trace_id) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_trace_TraceId_google_trace_TraceContext)
+#endif
+
+

+ 99 - 0
src/core/ext/census/gen/trace_context.pb.h

@@ -0,0 +1,99 @@
+/*
+ *
+ * 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.
+ *
+ */
+/* Automatically generated nanopb header */
+/* Generated by nanopb-0.3.5-dev */
+
+#ifndef GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H
+#define GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H
+#include "third_party/nanopb/pb.h"
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Struct definitions */
+typedef struct _google_trace_TraceId {
+    bool has_hi;
+    uint64_t hi;
+    bool has_lo;
+    uint64_t lo;
+} google_trace_TraceId;
+
+typedef struct _google_trace_TraceContext {
+    bool has_trace_id;
+    google_trace_TraceId trace_id;
+    bool has_span_id;
+    uint64_t span_id;
+    bool has_is_sampled;
+    bool is_sampled;
+} google_trace_TraceContext;
+
+/* Default values for struct fields */
+
+/* Initializer values for message structs */
+#define google_trace_TraceId_init_default        {false, 0, false, 0}
+#define google_trace_TraceContext_init_default   {false, google_trace_TraceId_init_default, false, 0, false, 0}
+#define google_trace_TraceId_init_zero           {false, 0, false, 0}
+#define google_trace_TraceContext_init_zero      {false, google_trace_TraceId_init_zero, false, 0, false, 0}
+
+/* Field tags (for use in manual encoding/decoding) */
+#define google_trace_TraceId_hi_tag              1
+#define google_trace_TraceId_lo_tag              2
+#define google_trace_TraceContext_trace_id_tag   1
+#define google_trace_TraceContext_span_id_tag    2
+#define google_trace_TraceContext_is_sampled_tag 3
+
+/* Struct field encoding specification for nanopb */
+extern const pb_field_t google_trace_TraceId_fields[3];
+extern const pb_field_t google_trace_TraceContext_fields[4];
+
+/* Maximum encoded size of messages (where known) */
+#define google_trace_TraceId_size                18
+#define google_trace_TraceContext_size           31
+
+/* Message IDs (where set with "msgid" option) */
+#ifdef PB_MSGID
+
+#define TRACE_CONTEXT_MESSAGES \
+
+
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif

+ 2 - 2
src/core/ext/client_config/README.md

@@ -12,7 +12,7 @@ data might include:
 - a load balancing policy to decide which server to send a request to
 - a load balancing policy to decide which server to send a request to
 - a set of filters to mutate outgoing requests (say, by adding metadata)
 - a set of filters to mutate outgoing requests (say, by adding metadata)
 
 
-The resolver provides this data as a stream of grpc_client_config objects to
+The resolver provides this data as a stream of grpc_resolver_result objects to
 the channel. We represent configuration as a stream so that it can be changed
 the channel. We represent configuration as a stream so that it can be changed
 by the resolver during execution, by reacting to external events (such as a
 by the resolver during execution, by reacting to external events (such as a
 new configuration file being pushed to some store).
 new configuration file being pushed to some store).
@@ -22,7 +22,7 @@ Load Balancing
 --------------
 --------------
 
 
 Load balancing configuration is provided by a grpc_lb_policy object, stored as
 Load balancing configuration is provided by a grpc_lb_policy object, stored as
-part of grpc_client_config.
+part of grpc_resolver_result.
 
 
 The primary job of the load balancing policies is to pick a target server given only the
 The primary job of the load balancing policies is to pick a target server given only the
 initial metadata for a request. It does this by providing a grpc_subchannel
 initial metadata for a request. It does this by providing a grpc_subchannel

+ 395 - 146
src/core/ext/client_config/client_channel.c

@@ -33,6 +33,7 @@
 
 
 #include "src/core/ext/client_config/client_channel.h"
 #include "src/core/ext/client_config/client_channel.h"
 
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdio.h>
 #include <string.h>
 #include <string.h>
 
 
@@ -41,10 +42,11 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/useful.h>
 #include <grpc/support/useful.h>
 
 
-#include "src/core/ext/client_config/subchannel_call_holder.h"
+#include "src/core/ext/client_config/subchannel.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/connected_channel.h"
 #include "src/core/lib/channel/connected_channel.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/iomgr/iomgr.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/channel.h"
@@ -52,30 +54,31 @@
 
 
 /* Client channel implementation */
 /* Client channel implementation */
 
 
-typedef grpc_subchannel_call_holder call_data;
+/*************************************************************************
+ * CHANNEL-WIDE FUNCTIONS
+ */
 
 
 typedef struct client_channel_channel_data {
 typedef struct client_channel_channel_data {
   /** resolver for this channel */
   /** resolver for this channel */
   grpc_resolver *resolver;
   grpc_resolver *resolver;
   /** have we started resolving this channel */
   /** have we started resolving this channel */
-  int started_resolving;
+  bool started_resolving;
 
 
   /** mutex protecting client configuration, including all
   /** mutex protecting client configuration, including all
       variables below in this data structure */
       variables below in this data structure */
-  gpr_mu mu_config;
-  /** currently active load balancer - guarded by mu_config */
+  gpr_mu mu;
+  /** currently active load balancer - guarded by mu */
   grpc_lb_policy *lb_policy;
   grpc_lb_policy *lb_policy;
-  /** incoming configuration - set by resolver.next
-      guarded by mu_config */
-  grpc_client_config *incoming_configuration;
+  /** incoming resolver result - set by resolver.next(), guarded by mu */
+  grpc_resolver_result *resolver_result;
   /** a list of closures that are all waiting for config to come in */
   /** a list of closures that are all waiting for config to come in */
   grpc_closure_list waiting_for_config_closures;
   grpc_closure_list waiting_for_config_closures;
   /** resolver callback */
   /** resolver callback */
-  grpc_closure on_config_changed;
+  grpc_closure on_resolver_result_changed;
   /** connectivity state being tracked */
   /** connectivity state being tracked */
   grpc_connectivity_state_tracker state_tracker;
   grpc_connectivity_state_tracker state_tracker;
   /** when an lb_policy arrives, should we try to exit idle */
   /** when an lb_policy arrives, should we try to exit idle */
-  int exit_idle_when_lb_policy_arrives;
+  bool exit_idle_when_lb_policy_arrives;
   /** owning stack */
   /** owning stack */
   grpc_channel_stack *owning_stack;
   grpc_channel_stack *owning_stack;
   /** interested parties (owned) */
   /** interested parties (owned) */
@@ -83,10 +86,8 @@ typedef struct client_channel_channel_data {
 } channel_data;
 } channel_data;
 
 
 /** We create one watcher for each new lb_policy that is returned from a
 /** We create one watcher for each new lb_policy that is returned from a
-   resolver,
-    to watch for state changes from the lb_policy. When a state change is seen,
-   we
-    update the channel, and create a new watcher */
+    resolver, to watch for state changes from the lb_policy. When a state
+    change is seen, we update the channel, and create a new watcher. */
 typedef struct {
 typedef struct {
   channel_data *chand;
   channel_data *chand;
   grpc_closure on_changed;
   grpc_closure on_changed;
@@ -94,22 +95,6 @@ typedef struct {
   grpc_lb_policy *lb_policy;
   grpc_lb_policy *lb_policy;
 } lb_policy_connectivity_watcher;
 } lb_policy_connectivity_watcher;
 
 
-typedef struct {
-  grpc_closure closure;
-  grpc_call_element *elem;
-} waiting_call;
-
-static char *cc_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
-  return grpc_subchannel_call_holder_get_peer(exec_ctx, elem->call_data);
-}
-
-static void cc_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
-                                         grpc_call_element *elem,
-                                         grpc_transport_stream_op *op) {
-  GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
-  grpc_subchannel_call_holder_perform_op(exec_ctx, elem->call_data, op);
-}
-
 static void watch_lb_policy(grpc_exec_ctx *exec_ctx, channel_data *chand,
 static void watch_lb_policy(grpc_exec_ctx *exec_ctx, channel_data *chand,
                             grpc_lb_policy *lb_policy,
                             grpc_lb_policy *lb_policy,
                             grpc_connectivity_state current_state);
                             grpc_connectivity_state current_state);
@@ -156,9 +141,9 @@ static void on_lb_policy_state_changed(grpc_exec_ctx *exec_ctx, void *arg,
                                        grpc_error *error) {
                                        grpc_error *error) {
   lb_policy_connectivity_watcher *w = arg;
   lb_policy_connectivity_watcher *w = arg;
 
 
-  gpr_mu_lock(&w->chand->mu_config);
+  gpr_mu_lock(&w->chand->mu);
   on_lb_policy_state_changed_locked(exec_ctx, w, error);
   on_lb_policy_state_changed_locked(exec_ctx, w, error);
-  gpr_mu_unlock(&w->chand->mu_config);
+  gpr_mu_unlock(&w->chand->mu);
 
 
   GRPC_CHANNEL_STACK_UNREF(exec_ctx, w->chand->owning_stack, "watch_lb_policy");
   GRPC_CHANNEL_STACK_UNREF(exec_ctx, w->chand->owning_stack, "watch_lb_policy");
   gpr_free(w);
   gpr_free(w);
@@ -178,17 +163,17 @@ static void watch_lb_policy(grpc_exec_ctx *exec_ctx, channel_data *chand,
                                         &w->on_changed);
                                         &w->on_changed);
 }
 }
 
 
-static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg,
-                                 grpc_error *error) {
+static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
+                                       grpc_error *error) {
   channel_data *chand = arg;
   channel_data *chand = arg;
   grpc_lb_policy *lb_policy = NULL;
   grpc_lb_policy *lb_policy = NULL;
   grpc_lb_policy *old_lb_policy;
   grpc_lb_policy *old_lb_policy;
   grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE;
   grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE;
-  int exit_idle = 0;
+  bool exit_idle = false;
   grpc_error *state_error = GRPC_ERROR_CREATE("No load balancing policy");
   grpc_error *state_error = GRPC_ERROR_CREATE("No load balancing policy");
 
 
-  if (chand->incoming_configuration != NULL) {
-    lb_policy = grpc_client_config_get_lb_policy(chand->incoming_configuration);
+  if (chand->resolver_result != NULL) {
+    lb_policy = grpc_resolver_result_get_lb_policy(chand->resolver_result);
     if (lb_policy != NULL) {
     if (lb_policy != NULL) {
       GRPC_LB_POLICY_REF(lb_policy, "channel");
       GRPC_LB_POLICY_REF(lb_policy, "channel");
       GRPC_LB_POLICY_REF(lb_policy, "config_change");
       GRPC_LB_POLICY_REF(lb_policy, "config_change");
@@ -197,17 +182,17 @@ static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg,
           grpc_lb_policy_check_connectivity(exec_ctx, lb_policy, &state_error);
           grpc_lb_policy_check_connectivity(exec_ctx, lb_policy, &state_error);
     }
     }
 
 
-    grpc_client_config_unref(exec_ctx, chand->incoming_configuration);
+    grpc_resolver_result_unref(exec_ctx, chand->resolver_result);
   }
   }
 
 
-  chand->incoming_configuration = NULL;
+  chand->resolver_result = NULL;
 
 
   if (lb_policy != NULL) {
   if (lb_policy != NULL) {
     grpc_pollset_set_add_pollset_set(exec_ctx, lb_policy->interested_parties,
     grpc_pollset_set_add_pollset_set(exec_ctx, lb_policy->interested_parties,
                                      chand->interested_parties);
                                      chand->interested_parties);
   }
   }
 
 
-  gpr_mu_lock(&chand->mu_config);
+  gpr_mu_lock(&chand->mu);
   old_lb_policy = chand->lb_policy;
   old_lb_policy = chand->lb_policy;
   chand->lb_policy = lb_policy;
   chand->lb_policy = lb_policy;
   if (lb_policy != NULL) {
   if (lb_policy != NULL) {
@@ -222,8 +207,8 @@ static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg,
   }
   }
   if (lb_policy != NULL && chand->exit_idle_when_lb_policy_arrives) {
   if (lb_policy != NULL && chand->exit_idle_when_lb_policy_arrives) {
     GRPC_LB_POLICY_REF(lb_policy, "exit_idle");
     GRPC_LB_POLICY_REF(lb_policy, "exit_idle");
-    exit_idle = 1;
-    chand->exit_idle_when_lb_policy_arrives = 0;
+    exit_idle = true;
+    chand->exit_idle_when_lb_policy_arrives = false;
   }
   }
 
 
   if (error == GRPC_ERROR_NONE && chand->resolver) {
   if (error == GRPC_ERROR_NONE && chand->resolver) {
@@ -233,10 +218,9 @@ static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg,
       watch_lb_policy(exec_ctx, chand, lb_policy, state);
       watch_lb_policy(exec_ctx, chand, lb_policy, state);
     }
     }
     GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
     GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
-    grpc_resolver_next(exec_ctx, chand->resolver,
-                       &chand->incoming_configuration,
-                       &chand->on_config_changed);
-    gpr_mu_unlock(&chand->mu_config);
+    grpc_resolver_next(exec_ctx, chand->resolver, &chand->resolver_result,
+                       &chand->on_resolver_result_changed);
+    gpr_mu_unlock(&chand->mu);
   } else {
   } else {
     if (chand->resolver != NULL) {
     if (chand->resolver != NULL) {
       grpc_resolver_shutdown(exec_ctx, chand->resolver);
       grpc_resolver_shutdown(exec_ctx, chand->resolver);
@@ -249,7 +233,7 @@ static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg,
         GRPC_ERROR_CREATE_REFERENCING("Got config after disconnection", refs,
         GRPC_ERROR_CREATE_REFERENCING("Got config after disconnection", refs,
                                       GPR_ARRAY_SIZE(refs)),
                                       GPR_ARRAY_SIZE(refs)),
         "resolver_gone");
         "resolver_gone");
-    gpr_mu_unlock(&chand->mu_config);
+    gpr_mu_unlock(&chand->mu);
   }
   }
 
 
   if (exit_idle) {
   if (exit_idle) {
@@ -284,7 +268,7 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
                                  op->bind_pollset);
                                  op->bind_pollset);
   }
   }
 
 
-  gpr_mu_lock(&chand->mu_config);
+  gpr_mu_lock(&chand->mu);
   if (op->on_connectivity_state_change != NULL) {
   if (op->on_connectivity_state_change != NULL) {
     grpc_connectivity_state_notify_on_state_change(
     grpc_connectivity_state_notify_on_state_change(
         exec_ctx, &chand->state_tracker, op->connectivity_state,
         exec_ctx, &chand->state_tracker, op->connectivity_state,
@@ -329,7 +313,193 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
     }
     }
     GRPC_ERROR_UNREF(op->disconnect_with_error);
     GRPC_ERROR_UNREF(op->disconnect_with_error);
   }
   }
-  gpr_mu_unlock(&chand->mu_config);
+  gpr_mu_unlock(&chand->mu);
+}
+
+/* Constructor for channel_data */
+static void cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
+                                 grpc_channel_element *elem,
+                                 grpc_channel_element_args *args) {
+  channel_data *chand = elem->channel_data;
+
+  memset(chand, 0, sizeof(*chand));
+
+  GPR_ASSERT(args->is_last);
+  GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
+
+  gpr_mu_init(&chand->mu);
+  grpc_closure_init(&chand->on_resolver_result_changed,
+                    on_resolver_result_changed, chand);
+  chand->owning_stack = args->channel_stack;
+
+  grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
+                               "client_channel");
+  chand->interested_parties = grpc_pollset_set_create();
+}
+
+/* Destructor for channel_data */
+static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx,
+                                    grpc_channel_element *elem) {
+  channel_data *chand = elem->channel_data;
+
+  if (chand->resolver != NULL) {
+    grpc_resolver_shutdown(exec_ctx, chand->resolver);
+    GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel");
+  }
+  if (chand->lb_policy != NULL) {
+    grpc_pollset_set_del_pollset_set(exec_ctx,
+                                     chand->lb_policy->interested_parties,
+                                     chand->interested_parties);
+    GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel");
+  }
+  grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker);
+  grpc_pollset_set_destroy(chand->interested_parties);
+  gpr_mu_destroy(&chand->mu);
+}
+
+/*************************************************************************
+ * PER-CALL FUNCTIONS
+ */
+
+#define GET_CALL(call_data) \
+  ((grpc_subchannel_call *)(gpr_atm_acq_load(&(call_data)->subchannel_call)))
+
+#define CANCELLED_CALL ((grpc_subchannel_call *)1)
+
+typedef enum {
+  GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING,
+  GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL
+} subchannel_creation_phase;
+
+/** Call data.  Holds a pointer to grpc_subchannel_call and the
+    associated machinery to create such a pointer.
+    Handles queueing of stream ops until a call object is ready, waiting
+    for initial metadata before trying to create a call object,
+    and handling cancellation gracefully. */
+typedef struct client_channel_call_data {
+  /** either 0 for no call, 1 for cancelled, or a pointer to a
+      grpc_subchannel_call */
+  gpr_atm subchannel_call;
+
+  gpr_mu mu;
+
+  subchannel_creation_phase creation_phase;
+  grpc_connected_subchannel *connected_subchannel;
+  grpc_polling_entity *pollent;
+
+  grpc_transport_stream_op **waiting_ops;
+  size_t waiting_ops_count;
+  size_t waiting_ops_capacity;
+
+  grpc_closure next_step;
+
+  grpc_call_stack *owning_call;
+} call_data;
+
+static void add_waiting_locked(call_data *calld, grpc_transport_stream_op *op) {
+  GPR_TIMER_BEGIN("add_waiting_locked", 0);
+  if (calld->waiting_ops_count == calld->waiting_ops_capacity) {
+    calld->waiting_ops_capacity = GPR_MAX(3, 2 * calld->waiting_ops_capacity);
+    calld->waiting_ops =
+        gpr_realloc(calld->waiting_ops,
+                    calld->waiting_ops_capacity * sizeof(*calld->waiting_ops));
+  }
+  calld->waiting_ops[calld->waiting_ops_count++] = op;
+  GPR_TIMER_END("add_waiting_locked", 0);
+}
+
+static void fail_locked(grpc_exec_ctx *exec_ctx, call_data *calld,
+                        grpc_error *error) {
+  size_t i;
+  for (i = 0; i < calld->waiting_ops_count; i++) {
+    grpc_transport_stream_op_finish_with_failure(
+        exec_ctx, calld->waiting_ops[i], GRPC_ERROR_REF(error));
+  }
+  calld->waiting_ops_count = 0;
+  GRPC_ERROR_UNREF(error);
+}
+
+typedef struct {
+  grpc_transport_stream_op **ops;
+  size_t nops;
+  grpc_subchannel_call *call;
+} retry_ops_args;
+
+static void retry_ops(grpc_exec_ctx *exec_ctx, void *args, grpc_error *error) {
+  retry_ops_args *a = args;
+  size_t i;
+  for (i = 0; i < a->nops; i++) {
+    grpc_subchannel_call_process_op(exec_ctx, a->call, a->ops[i]);
+  }
+  GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, a->call, "retry_ops");
+  gpr_free(a->ops);
+  gpr_free(a);
+}
+
+static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, call_data *calld) {
+  if (calld->waiting_ops_count == 0) {
+    return;
+  }
+
+  retry_ops_args *a = gpr_malloc(sizeof(*a));
+  a->ops = calld->waiting_ops;
+  a->nops = calld->waiting_ops_count;
+  a->call = GET_CALL(calld);
+  if (a->call == CANCELLED_CALL) {
+    gpr_free(a);
+    fail_locked(exec_ctx, calld, GRPC_ERROR_CANCELLED);
+    return;
+  }
+  calld->waiting_ops = NULL;
+  calld->waiting_ops_count = 0;
+  calld->waiting_ops_capacity = 0;
+  GRPC_SUBCHANNEL_CALL_REF(a->call, "retry_ops");
+  grpc_exec_ctx_sched(exec_ctx, grpc_closure_create(retry_ops, a),
+                      GRPC_ERROR_NONE, NULL);
+}
+
+static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg,
+                             grpc_error *error) {
+  call_data *calld = arg;
+  gpr_mu_lock(&calld->mu);
+  GPR_ASSERT(calld->creation_phase ==
+             GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL);
+  calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
+  if (calld->connected_subchannel == NULL) {
+    gpr_atm_no_barrier_store(&calld->subchannel_call, 1);
+    fail_locked(exec_ctx, calld, GRPC_ERROR_CREATE_REFERENCING(
+                                     "Failed to create subchannel", &error, 1));
+  } else if (1 == gpr_atm_acq_load(&calld->subchannel_call)) {
+    /* already cancelled before subchannel became ready */
+    fail_locked(exec_ctx, calld,
+                GRPC_ERROR_CREATE_REFERENCING(
+                    "Cancelled before creating subchannel", &error, 1));
+  } else {
+    grpc_subchannel_call *subchannel_call = NULL;
+    grpc_error *new_error = grpc_connected_subchannel_create_call(
+        exec_ctx, calld->connected_subchannel, calld->pollent,
+        &subchannel_call);
+    if (new_error != GRPC_ERROR_NONE) {
+      new_error = grpc_error_add_child(new_error, error);
+      subchannel_call = CANCELLED_CALL;
+      fail_locked(exec_ctx, calld, new_error);
+    }
+    gpr_atm_rel_store(&calld->subchannel_call,
+                      (gpr_atm)(uintptr_t)subchannel_call);
+    retry_waiting_locked(exec_ctx, calld);
+  }
+  gpr_mu_unlock(&calld->mu);
+  GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
+}
+
+static char *cc_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
+  call_data *calld = elem->call_data;
+  grpc_subchannel_call *subchannel_call = GET_CALL(calld);
+  if (subchannel_call == NULL || subchannel_call == CANCELLED_CALL) {
+    return NULL;
+  } else {
+    return grpc_subchannel_call_get_peer(exec_ctx, subchannel_call);
+  }
 }
 }
 
 
 typedef struct {
 typedef struct {
@@ -341,11 +511,11 @@ typedef struct {
   grpc_closure closure;
   grpc_closure closure;
 } continue_picking_args;
 } continue_picking_args;
 
 
-static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *arg,
-                              grpc_metadata_batch *initial_metadata,
-                              uint32_t initial_metadata_flags,
-                              grpc_connected_subchannel **connected_subchannel,
-                              grpc_closure *on_ready);
+static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+                            grpc_metadata_batch *initial_metadata,
+                            uint32_t initial_metadata_flags,
+                            grpc_connected_subchannel **connected_subchannel,
+                            grpc_closure *on_ready);
 
 
 static void continue_picking(grpc_exec_ctx *exec_ctx, void *arg,
 static void continue_picking(grpc_exec_ctx *exec_ctx, void *arg,
                              grpc_error *error) {
                              grpc_error *error) {
@@ -354,22 +524,21 @@ static void continue_picking(grpc_exec_ctx *exec_ctx, void *arg,
     /* cancelled, do nothing */
     /* cancelled, do nothing */
   } else if (error != GRPC_ERROR_NONE) {
   } else if (error != GRPC_ERROR_NONE) {
     grpc_exec_ctx_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_REF(error), NULL);
     grpc_exec_ctx_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_REF(error), NULL);
-  } else if (cc_pick_subchannel(exec_ctx, cpa->elem, cpa->initial_metadata,
-                                cpa->initial_metadata_flags,
-                                cpa->connected_subchannel, cpa->on_ready)) {
+  } else if (pick_subchannel(exec_ctx, cpa->elem, cpa->initial_metadata,
+                             cpa->initial_metadata_flags,
+                             cpa->connected_subchannel, cpa->on_ready)) {
     grpc_exec_ctx_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_NONE, NULL);
     grpc_exec_ctx_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_NONE, NULL);
   }
   }
   gpr_free(cpa);
   gpr_free(cpa);
 }
 }
 
 
-static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp,
-                              grpc_metadata_batch *initial_metadata,
-                              uint32_t initial_metadata_flags,
-                              grpc_connected_subchannel **connected_subchannel,
-                              grpc_closure *on_ready) {
-  GPR_TIMER_BEGIN("cc_pick_subchannel", 0);
+static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+                            grpc_metadata_batch *initial_metadata,
+                            uint32_t initial_metadata_flags,
+                            grpc_connected_subchannel **connected_subchannel,
+                            grpc_closure *on_ready) {
+  GPR_TIMER_BEGIN("pick_subchannel", 0);
 
 
-  grpc_call_element *elem = elemp;
   channel_data *chand = elem->channel_data;
   channel_data *chand = elem->channel_data;
   call_data *calld = elem->call_data;
   call_data *calld = elem->call_data;
   continue_picking_args *cpa;
   continue_picking_args *cpa;
@@ -377,7 +546,7 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp,
 
 
   GPR_ASSERT(connected_subchannel);
   GPR_ASSERT(connected_subchannel);
 
 
-  gpr_mu_lock(&chand->mu_config);
+  gpr_mu_lock(&chand->mu);
   if (initial_metadata == NULL) {
   if (initial_metadata == NULL) {
     if (chand->lb_policy != NULL) {
     if (chand->lb_policy != NULL) {
       grpc_lb_policy_cancel_pick(exec_ctx, chand->lb_policy,
       grpc_lb_policy_cancel_pick(exec_ctx, chand->lb_policy,
@@ -392,28 +561,27 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp,
                             GRPC_ERROR_CREATE("Pick cancelled"), NULL);
                             GRPC_ERROR_CREATE("Pick cancelled"), NULL);
       }
       }
     }
     }
-    gpr_mu_unlock(&chand->mu_config);
-    GPR_TIMER_END("cc_pick_subchannel", 0);
-    return 1;
+    gpr_mu_unlock(&chand->mu);
+    GPR_TIMER_END("pick_subchannel", 0);
+    return true;
   }
   }
   if (chand->lb_policy != NULL) {
   if (chand->lb_policy != NULL) {
     grpc_lb_policy *lb_policy = chand->lb_policy;
     grpc_lb_policy *lb_policy = chand->lb_policy;
     int r;
     int r;
-    GRPC_LB_POLICY_REF(lb_policy, "cc_pick_subchannel");
-    gpr_mu_unlock(&chand->mu_config);
+    GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel");
+    gpr_mu_unlock(&chand->mu);
     r = grpc_lb_policy_pick(exec_ctx, lb_policy, calld->pollent,
     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");
-    GPR_TIMER_END("cc_pick_subchannel", 0);
+    GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "pick_subchannel");
+    GPR_TIMER_END("pick_subchannel", 0);
     return r;
     return r;
   }
   }
   if (chand->resolver != NULL && !chand->started_resolving) {
   if (chand->resolver != NULL && !chand->started_resolving) {
-    chand->started_resolving = 1;
+    chand->started_resolving = true;
     GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
     GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
-    grpc_resolver_next(exec_ctx, chand->resolver,
-                       &chand->incoming_configuration,
-                       &chand->on_config_changed);
+    grpc_resolver_next(exec_ctx, chand->resolver, &chand->resolver_result,
+                       &chand->on_resolver_result_changed);
   }
   }
   if (chand->resolver != NULL) {
   if (chand->resolver != NULL) {
     cpa = gpr_malloc(sizeof(*cpa));
     cpa = gpr_malloc(sizeof(*cpa));
@@ -429,67 +597,145 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp,
     grpc_exec_ctx_sched(exec_ctx, on_ready, GRPC_ERROR_CREATE("Disconnected"),
     grpc_exec_ctx_sched(exec_ctx, on_ready, GRPC_ERROR_CREATE("Disconnected"),
                         NULL);
                         NULL);
   }
   }
-  gpr_mu_unlock(&chand->mu_config);
+  gpr_mu_unlock(&chand->mu);
 
 
-  GPR_TIMER_END("cc_pick_subchannel", 0);
-  return 0;
+  GPR_TIMER_END("pick_subchannel", 0);
+  return false;
+}
+
+// The logic here is fairly complicated, due to (a) the fact that we
+// need to handle the case where we receive the send op before the
+// initial metadata op, and (b) the need for efficiency, especially in
+// the streaming case.
+// TODO(ctiller): Explain this more thoroughly.
+static void cc_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
+                                         grpc_call_element *elem,
+                                         grpc_transport_stream_op *op) {
+  call_data *calld = elem->call_data;
+  GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
+  /* try to (atomically) get the call */
+  grpc_subchannel_call *call = GET_CALL(calld);
+  GPR_TIMER_BEGIN("cc_start_transport_stream_op", 0);
+  if (call == CANCELLED_CALL) {
+    grpc_transport_stream_op_finish_with_failure(exec_ctx, op,
+                                                 GRPC_ERROR_CANCELLED);
+    GPR_TIMER_END("cc_start_transport_stream_op", 0);
+    return;
+  }
+  if (call != NULL) {
+    grpc_subchannel_call_process_op(exec_ctx, call, op);
+    GPR_TIMER_END("cc_start_transport_stream_op", 0);
+    return;
+  }
+  /* we failed; lock and figure out what to do */
+  gpr_mu_lock(&calld->mu);
+retry:
+  /* need to recheck that another thread hasn't set the call */
+  call = GET_CALL(calld);
+  if (call == CANCELLED_CALL) {
+    gpr_mu_unlock(&calld->mu);
+    grpc_transport_stream_op_finish_with_failure(exec_ctx, op,
+                                                 GRPC_ERROR_CANCELLED);
+    GPR_TIMER_END("cc_start_transport_stream_op", 0);
+    return;
+  }
+  if (call != NULL) {
+    gpr_mu_unlock(&calld->mu);
+    grpc_subchannel_call_process_op(exec_ctx, call, op);
+    GPR_TIMER_END("cc_start_transport_stream_op", 0);
+    return;
+  }
+  /* if this is a cancellation, then we can raise our cancelled flag */
+  if (op->cancel_error != GRPC_ERROR_NONE) {
+    if (!gpr_atm_rel_cas(&calld->subchannel_call, 0,
+                         (gpr_atm)(uintptr_t)CANCELLED_CALL)) {
+      goto retry;
+    } else {
+      switch (calld->creation_phase) {
+        case GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING:
+          fail_locked(exec_ctx, calld, GRPC_ERROR_REF(op->cancel_error));
+          break;
+        case GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL:
+          pick_subchannel(exec_ctx, elem, NULL, 0, &calld->connected_subchannel,
+                          NULL);
+          break;
+      }
+      gpr_mu_unlock(&calld->mu);
+      grpc_transport_stream_op_finish_with_failure(exec_ctx, op,
+                                                   GRPC_ERROR_CANCELLED);
+      GPR_TIMER_END("cc_start_transport_stream_op", 0);
+      return;
+    }
+  }
+  /* if we don't have a subchannel, try to get one */
+  if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING &&
+      calld->connected_subchannel == NULL &&
+      op->send_initial_metadata != NULL) {
+    calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL;
+    grpc_closure_init(&calld->next_step, subchannel_ready, calld);
+    GRPC_CALL_STACK_REF(calld->owning_call, "pick_subchannel");
+    if (pick_subchannel(exec_ctx, elem, op->send_initial_metadata,
+                        op->send_initial_metadata_flags,
+                        &calld->connected_subchannel, &calld->next_step)) {
+      calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
+      GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
+    }
+  }
+  /* if we've got a subchannel, then let's ask it to create a call */
+  if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING &&
+      calld->connected_subchannel != NULL) {
+    grpc_subchannel_call *subchannel_call = NULL;
+    grpc_error *error = grpc_connected_subchannel_create_call(
+        exec_ctx, calld->connected_subchannel, calld->pollent,
+        &subchannel_call);
+    if (error != GRPC_ERROR_NONE) {
+      subchannel_call = CANCELLED_CALL;
+      fail_locked(exec_ctx, calld, GRPC_ERROR_REF(error));
+      grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error);
+    }
+    gpr_atm_rel_store(&calld->subchannel_call,
+                      (gpr_atm)(uintptr_t)subchannel_call);
+    retry_waiting_locked(exec_ctx, calld);
+    goto retry;
+  }
+  /* nothing to be done but wait */
+  add_waiting_locked(calld, op);
+  gpr_mu_unlock(&calld->mu);
+  GPR_TIMER_END("cc_start_transport_stream_op", 0);
 }
 }
 
 
 /* Constructor for call_data */
 /* Constructor for call_data */
-static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
-                                  grpc_call_element *elem,
-                                  grpc_call_element_args *args) {
-  grpc_subchannel_call_holder_init(elem->call_data, cc_pick_subchannel, elem,
-                                   args->call_stack);
+static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
+                                     grpc_call_element *elem,
+                                     grpc_call_element_args *args) {
+  call_data *calld = elem->call_data;
+  gpr_atm_rel_store(&calld->subchannel_call, 0);
+  gpr_mu_init(&calld->mu);
+  calld->connected_subchannel = NULL;
+  calld->waiting_ops = NULL;
+  calld->waiting_ops_count = 0;
+  calld->waiting_ops_capacity = 0;
+  calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
+  calld->owning_call = args->call_stack;
+  calld->pollent = NULL;
   return GRPC_ERROR_NONE;
   return GRPC_ERROR_NONE;
 }
 }
 
 
 /* Destructor for call_data */
 /* Destructor for call_data */
-static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                              const grpc_call_final_info *final_info,
-                              void *and_free_memory) {
-  grpc_subchannel_call_holder_destroy(exec_ctx, elem->call_data);
-  gpr_free(and_free_memory);
-}
-
-/* Constructor for channel_data */
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
-                              grpc_channel_element *elem,
-                              grpc_channel_element_args *args) {
-  channel_data *chand = elem->channel_data;
-
-  memset(chand, 0, sizeof(*chand));
-
-  GPR_ASSERT(args->is_last);
-  GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
-
-  gpr_mu_init(&chand->mu_config);
-  grpc_closure_init(&chand->on_config_changed, cc_on_config_changed, chand);
-  chand->owning_stack = args->channel_stack;
-
-  grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
-                               "client_channel");
-  chand->interested_parties = grpc_pollset_set_create();
-}
-
-/* Destructor for channel_data */
-static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
-                                 grpc_channel_element *elem) {
-  channel_data *chand = elem->channel_data;
-
-  if (chand->resolver != NULL) {
-    grpc_resolver_shutdown(exec_ctx, chand->resolver);
-    GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel");
-  }
-  if (chand->lb_policy != NULL) {
-    grpc_pollset_set_del_pollset_set(exec_ctx,
-                                     chand->lb_policy->interested_parties,
-                                     chand->interested_parties);
-    GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel");
+static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
+                                 grpc_call_element *elem,
+                                 const grpc_call_final_info *final_info,
+                                 void *and_free_memory) {
+  call_data *calld = elem->call_data;
+  grpc_subchannel_call *call = GET_CALL(calld);
+  if (call != NULL && call != CANCELLED_CALL) {
+    GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "client_channel_destroy_call");
   }
   }
-  grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker);
-  grpc_pollset_set_destroy(chand->interested_parties);
-  gpr_mu_destroy(&chand->mu_config);
+  GPR_ASSERT(calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING);
+  gpr_mu_destroy(&calld->mu);
+  GPR_ASSERT(calld->waiting_ops_count == 0);
+  gpr_free(calld->waiting_ops);
+  gpr_free(and_free_memory);
 }
 }
 
 
 static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
 static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
@@ -499,16 +745,20 @@ static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
   calld->pollent = pollent;
   calld->pollent = pollent;
 }
 }
 
 
+/*************************************************************************
+ * EXPORTED SYMBOLS
+ */
+
 const grpc_channel_filter grpc_client_channel_filter = {
 const grpc_channel_filter grpc_client_channel_filter = {
     cc_start_transport_stream_op,
     cc_start_transport_stream_op,
     cc_start_transport_op,
     cc_start_transport_op,
     sizeof(call_data),
     sizeof(call_data),
-    init_call_elem,
+    cc_init_call_elem,
     cc_set_pollset_or_pollset_set,
     cc_set_pollset_or_pollset_set,
-    destroy_call_elem,
+    cc_destroy_call_elem,
     sizeof(channel_data),
     sizeof(channel_data),
-    init_channel_elem,
-    destroy_channel_elem,
+    cc_init_channel_elem,
+    cc_destroy_channel_elem,
     cc_get_peer,
     cc_get_peer,
     "client-channel",
     "client-channel",
 };
 };
@@ -519,41 +769,40 @@ void grpc_client_channel_set_resolver(grpc_exec_ctx *exec_ctx,
   /* post construction initialization: set the transport setup pointer */
   /* post construction initialization: set the transport setup pointer */
   grpc_channel_element *elem = grpc_channel_stack_last_element(channel_stack);
   grpc_channel_element *elem = grpc_channel_stack_last_element(channel_stack);
   channel_data *chand = elem->channel_data;
   channel_data *chand = elem->channel_data;
-  gpr_mu_lock(&chand->mu_config);
+  gpr_mu_lock(&chand->mu);
   GPR_ASSERT(!chand->resolver);
   GPR_ASSERT(!chand->resolver);
   chand->resolver = resolver;
   chand->resolver = resolver;
   GRPC_RESOLVER_REF(resolver, "channel");
   GRPC_RESOLVER_REF(resolver, "channel");
   if (!grpc_closure_list_empty(chand->waiting_for_config_closures) ||
   if (!grpc_closure_list_empty(chand->waiting_for_config_closures) ||
       chand->exit_idle_when_lb_policy_arrives) {
       chand->exit_idle_when_lb_policy_arrives) {
-    chand->started_resolving = 1;
+    chand->started_resolving = true;
     GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
     GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
-    grpc_resolver_next(exec_ctx, resolver, &chand->incoming_configuration,
-                       &chand->on_config_changed);
+    grpc_resolver_next(exec_ctx, resolver, &chand->resolver_result,
+                       &chand->on_resolver_result_changed);
   }
   }
-  gpr_mu_unlock(&chand->mu_config);
+  gpr_mu_unlock(&chand->mu);
 }
 }
 
 
 grpc_connectivity_state grpc_client_channel_check_connectivity_state(
 grpc_connectivity_state grpc_client_channel_check_connectivity_state(
     grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect) {
     grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect) {
   channel_data *chand = elem->channel_data;
   channel_data *chand = elem->channel_data;
   grpc_connectivity_state out;
   grpc_connectivity_state out;
-  gpr_mu_lock(&chand->mu_config);
+  gpr_mu_lock(&chand->mu);
   out = grpc_connectivity_state_check(&chand->state_tracker, NULL);
   out = grpc_connectivity_state_check(&chand->state_tracker, NULL);
   if (out == GRPC_CHANNEL_IDLE && try_to_connect) {
   if (out == GRPC_CHANNEL_IDLE && try_to_connect) {
     if (chand->lb_policy != NULL) {
     if (chand->lb_policy != NULL) {
       grpc_lb_policy_exit_idle(exec_ctx, chand->lb_policy);
       grpc_lb_policy_exit_idle(exec_ctx, chand->lb_policy);
     } else {
     } else {
-      chand->exit_idle_when_lb_policy_arrives = 1;
+      chand->exit_idle_when_lb_policy_arrives = true;
       if (!chand->started_resolving && chand->resolver != NULL) {
       if (!chand->started_resolving && chand->resolver != NULL) {
         GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
         GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
-        chand->started_resolving = 1;
-        grpc_resolver_next(exec_ctx, chand->resolver,
-                           &chand->incoming_configuration,
-                           &chand->on_config_changed);
+        chand->started_resolving = true;
+        grpc_resolver_next(exec_ctx, chand->resolver, &chand->resolver_result,
+                           &chand->on_resolver_result_changed);
       }
       }
     }
     }
   }
   }
-  gpr_mu_unlock(&chand->mu_config);
+  gpr_mu_unlock(&chand->mu);
   return out;
   return out;
 }
 }
 
 
@@ -588,8 +837,8 @@ void grpc_client_channel_watch_connectivity_state(
   grpc_closure_init(&w->my_closure, on_external_watch_complete, w);
   grpc_closure_init(&w->my_closure, on_external_watch_complete, w);
   GRPC_CHANNEL_STACK_REF(w->chand->owning_stack,
   GRPC_CHANNEL_STACK_REF(w->chand->owning_stack,
                          "external_connectivity_watcher");
                          "external_connectivity_watcher");
-  gpr_mu_lock(&chand->mu_config);
+  gpr_mu_lock(&chand->mu);
   grpc_connectivity_state_notify_on_state_change(
   grpc_connectivity_state_notify_on_state_change(
       exec_ctx, &chand->state_tracker, state, &w->my_closure);
       exec_ctx, &chand->state_tracker, state, &w->my_closure);
-  gpr_mu_unlock(&chand->mu_config);
+  gpr_mu_unlock(&chand->mu);
 }
 }

+ 0 - 2
src/core/ext/client_config/lb_policy_factory.h

@@ -43,8 +43,6 @@
 typedef struct grpc_lb_policy_factory grpc_lb_policy_factory;
 typedef struct grpc_lb_policy_factory grpc_lb_policy_factory;
 typedef struct grpc_lb_policy_factory_vtable grpc_lb_policy_factory_vtable;
 typedef struct grpc_lb_policy_factory_vtable grpc_lb_policy_factory_vtable;
 
 
-/** grpc_lb_policy provides grpc_client_config objects to grpc_channel
-    objects */
 struct grpc_lb_policy_factory {
 struct grpc_lb_policy_factory {
   const grpc_lb_policy_factory_vtable *vtable;
   const grpc_lb_policy_factory_vtable *vtable;
 };
 };

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

@@ -76,7 +76,7 @@ void grpc_resolver_channel_saw_error(grpc_exec_ctx *exec_ctx,
 }
 }
 
 
 void grpc_resolver_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
 void grpc_resolver_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
-                        grpc_client_config **target_config,
+                        grpc_resolver_result **result,
                         grpc_closure *on_complete) {
                         grpc_closure *on_complete) {
-  resolver->vtable->next(exec_ctx, resolver, target_config, on_complete);
+  resolver->vtable->next(exec_ctx, resolver, result, on_complete);
 }
 }

+ 6 - 6
src/core/ext/client_config/resolver.h

@@ -34,14 +34,14 @@
 #ifndef GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_H
 #ifndef GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_H
 #define GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_H
 #define GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_H
 
 
-#include "src/core/ext/client_config/client_config.h"
+#include "src/core/ext/client_config/resolver_result.h"
 #include "src/core/ext/client_config/subchannel.h"
 #include "src/core/ext/client_config/subchannel.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/iomgr/iomgr.h"
 
 
 typedef struct grpc_resolver grpc_resolver;
 typedef struct grpc_resolver grpc_resolver;
 typedef struct grpc_resolver_vtable grpc_resolver_vtable;
 typedef struct grpc_resolver_vtable grpc_resolver_vtable;
 
 
-/** grpc_resolver provides grpc_client_config objects to grpc_channel
+/** grpc_resolver provides grpc_resolver_result objects to grpc_channel
     objects */
     objects */
 struct grpc_resolver {
 struct grpc_resolver {
   const grpc_resolver_vtable *vtable;
   const grpc_resolver_vtable *vtable;
@@ -53,7 +53,7 @@ struct grpc_resolver_vtable {
   void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver);
   void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver);
   void (*channel_saw_error)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver);
   void (*channel_saw_error)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver);
   void (*next)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
   void (*next)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
-               grpc_client_config **target_config, grpc_closure *on_complete);
+               grpc_resolver_result **result, grpc_closure *on_complete);
 };
 };
 
 
 #ifdef GRPC_RESOLVER_REFCOUNT_DEBUG
 #ifdef GRPC_RESOLVER_REFCOUNT_DEBUG
@@ -82,13 +82,13 @@ void grpc_resolver_channel_saw_error(grpc_exec_ctx *exec_ctx,
                                      grpc_resolver *resolver);
                                      grpc_resolver *resolver);
 
 
 /** Get the next client config. Called by the channel to fetch a new
 /** Get the next client config. Called by the channel to fetch a new
-    configuration. Expected to set *target_config with a new configuration,
+    configuration. Expected to set *result with a new configuration,
     and then schedule on_complete for execution.
     and then schedule on_complete for execution.
 
 
-    If resolution is fatally broken, set *target_config to NULL and
+    If resolution is fatally broken, set *result to NULL and
     schedule on_complete. */
     schedule on_complete. */
 void grpc_resolver_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
 void grpc_resolver_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
-                        grpc_client_config **target_config,
+                        grpc_resolver_result **result,
                         grpc_closure *on_complete);
                         grpc_closure *on_complete);
 
 
 #endif /* GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_H */
 #endif /* GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_H */

+ 1 - 1
src/core/ext/client_config/resolver_factory.h

@@ -41,7 +41,7 @@
 typedef struct grpc_resolver_factory grpc_resolver_factory;
 typedef struct grpc_resolver_factory grpc_resolver_factory;
 typedef struct grpc_resolver_factory_vtable grpc_resolver_factory_vtable;
 typedef struct grpc_resolver_factory_vtable grpc_resolver_factory_vtable;
 
 
-/** grpc_resolver provides grpc_client_config objects to grpc_channel
+/** grpc_resolver provides grpc_resolver_result objects to grpc_channel
     objects */
     objects */
 struct grpc_resolver_factory {
 struct grpc_resolver_factory {
   const grpc_resolver_factory_vtable *vtable;
   const grpc_resolver_factory_vtable *vtable;

+ 12 - 11
src/core/ext/client_config/client_config.c → src/core/ext/client_config/resolver_result.c

@@ -31,44 +31,45 @@
  *
  *
  */
  */
 
 
-#include "src/core/ext/client_config/client_config.h"
+#include "src/core/ext/client_config/resolver_result.h"
 
 
 #include <string.h>
 #include <string.h>
 
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/alloc.h>
 
 
-struct grpc_client_config {
+struct grpc_resolver_result {
   gpr_refcount refs;
   gpr_refcount refs;
   grpc_lb_policy *lb_policy;
   grpc_lb_policy *lb_policy;
 };
 };
 
 
-grpc_client_config *grpc_client_config_create() {
-  grpc_client_config *c = gpr_malloc(sizeof(*c));
+grpc_resolver_result *grpc_resolver_result_create() {
+  grpc_resolver_result *c = gpr_malloc(sizeof(*c));
   memset(c, 0, sizeof(*c));
   memset(c, 0, sizeof(*c));
   gpr_ref_init(&c->refs, 1);
   gpr_ref_init(&c->refs, 1);
   return c;
   return c;
 }
 }
 
 
-void grpc_client_config_ref(grpc_client_config *c) { gpr_ref(&c->refs); }
+void grpc_resolver_result_ref(grpc_resolver_result *c) { gpr_ref(&c->refs); }
 
 
-void grpc_client_config_unref(grpc_exec_ctx *exec_ctx, grpc_client_config *c) {
+void grpc_resolver_result_unref(grpc_exec_ctx *exec_ctx,
+                                grpc_resolver_result *c) {
   if (gpr_unref(&c->refs)) {
   if (gpr_unref(&c->refs)) {
     if (c->lb_policy != NULL) {
     if (c->lb_policy != NULL) {
-      GRPC_LB_POLICY_UNREF(exec_ctx, c->lb_policy, "client_config");
+      GRPC_LB_POLICY_UNREF(exec_ctx, c->lb_policy, "resolver_result");
     }
     }
     gpr_free(c);
     gpr_free(c);
   }
   }
 }
 }
 
 
-void grpc_client_config_set_lb_policy(grpc_client_config *c,
-                                      grpc_lb_policy *lb_policy) {
+void grpc_resolver_result_set_lb_policy(grpc_resolver_result *c,
+                                        grpc_lb_policy *lb_policy) {
   GPR_ASSERT(c->lb_policy == NULL);
   GPR_ASSERT(c->lb_policy == NULL);
   if (lb_policy) {
   if (lb_policy) {
-    GRPC_LB_POLICY_REF(lb_policy, "client_config");
+    GRPC_LB_POLICY_REF(lb_policy, "resolver_result");
   }
   }
   c->lb_policy = lb_policy;
   c->lb_policy = lb_policy;
 }
 }
 
 
-grpc_lb_policy *grpc_client_config_get_lb_policy(grpc_client_config *c) {
+grpc_lb_policy *grpc_resolver_result_get_lb_policy(grpc_resolver_result *c) {
   return c->lb_policy;
   return c->lb_policy;
 }
 }

+ 13 - 14
src/core/ext/client_config/client_config.h → src/core/ext/client_config/resolver_result.h

@@ -31,23 +31,22 @@
  *
  *
  */
  */
 
 
-#ifndef GRPC_CORE_EXT_CLIENT_CONFIG_CLIENT_CONFIG_H
-#define GRPC_CORE_EXT_CLIENT_CONFIG_CLIENT_CONFIG_H
+#ifndef GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_RESULT_H
+#define GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_RESULT_H
 
 
 #include "src/core/ext/client_config/lb_policy.h"
 #include "src/core/ext/client_config/lb_policy.h"
 
 
-/** Total configuration for a client. Provided, and updated, by
-    grpc_resolver */
-typedef struct grpc_client_config grpc_client_config;
+/** Results reported from a grpc_resolver. */
+typedef struct grpc_resolver_result grpc_resolver_result;
 
 
-grpc_client_config *grpc_client_config_create();
-void grpc_client_config_ref(grpc_client_config *client_config);
-void grpc_client_config_unref(grpc_exec_ctx *exec_ctx,
-                              grpc_client_config *client_config);
+grpc_resolver_result *grpc_resolver_result_create();
+void grpc_resolver_result_ref(grpc_resolver_result *client_config);
+void grpc_resolver_result_unref(grpc_exec_ctx *exec_ctx,
+                                grpc_resolver_result *client_config);
 
 
-void grpc_client_config_set_lb_policy(grpc_client_config *client_config,
-                                      grpc_lb_policy *lb_policy);
-grpc_lb_policy *grpc_client_config_get_lb_policy(
-    grpc_client_config *client_config);
+void grpc_resolver_result_set_lb_policy(grpc_resolver_result *client_config,
+                                        grpc_lb_policy *lb_policy);
+grpc_lb_policy *grpc_resolver_result_get_lb_policy(
+    grpc_resolver_result *client_config);
 
 
-#endif /* GRPC_CORE_EXT_CLIENT_CONFIG_CLIENT_CONFIG_H */
+#endif /* GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_RESULT_H */

+ 0 - 296
src/core/ext/client_config/subchannel_call_holder.c

@@ -1,296 +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.
- *
- */
-
-#include "src/core/ext/client_config/subchannel_call_holder.h"
-
-#include <grpc/support/alloc.h>
-
-#include "src/core/lib/profiling/timers.h"
-
-#define GET_CALL(holder) \
-  ((grpc_subchannel_call *)(gpr_atm_acq_load(&(holder)->subchannel_call)))
-
-#define CANCELLED_CALL ((grpc_subchannel_call *)1)
-
-static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *holder,
-                             grpc_error *error);
-static void retry_ops(grpc_exec_ctx *exec_ctx, void *retry_ops_args,
-                      grpc_error *error);
-
-static void add_waiting_locked(grpc_subchannel_call_holder *holder,
-                               grpc_transport_stream_op *op);
-static void fail_locked(grpc_exec_ctx *exec_ctx,
-                        grpc_subchannel_call_holder *holder, grpc_error *error);
-static void retry_waiting_locked(grpc_exec_ctx *exec_ctx,
-                                 grpc_subchannel_call_holder *holder);
-
-void grpc_subchannel_call_holder_init(
-    grpc_subchannel_call_holder *holder,
-    grpc_subchannel_call_holder_pick_subchannel pick_subchannel,
-    void *pick_subchannel_arg, grpc_call_stack *owning_call) {
-  gpr_atm_rel_store(&holder->subchannel_call, 0);
-  holder->pick_subchannel = pick_subchannel;
-  holder->pick_subchannel_arg = pick_subchannel_arg;
-  gpr_mu_init(&holder->mu);
-  holder->connected_subchannel = NULL;
-  holder->waiting_ops = NULL;
-  holder->waiting_ops_count = 0;
-  holder->waiting_ops_capacity = 0;
-  holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
-  holder->owning_call = owning_call;
-  holder->pollent = NULL;
-}
-
-void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx,
-                                         grpc_subchannel_call_holder *holder) {
-  grpc_subchannel_call *call = GET_CALL(holder);
-  if (call != NULL && call != CANCELLED_CALL) {
-    GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "holder");
-  }
-  GPR_ASSERT(holder->creation_phase ==
-             GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING);
-  gpr_mu_destroy(&holder->mu);
-  GPR_ASSERT(holder->waiting_ops_count == 0);
-  gpr_free(holder->waiting_ops);
-}
-
-// The logic here is fairly complicated, due to (a) the fact that we
-// need to handle the case where we receive the send op before the
-// initial metadata op, and (b) the need for efficiency, especially in
-// the streaming case.
-// TODO(ctiller): Explain this more thoroughly.
-void grpc_subchannel_call_holder_perform_op(grpc_exec_ctx *exec_ctx,
-                                            grpc_subchannel_call_holder *holder,
-                                            grpc_transport_stream_op *op) {
-  /* try to (atomically) get the call */
-  grpc_subchannel_call *call = GET_CALL(holder);
-  GPR_TIMER_BEGIN("grpc_subchannel_call_holder_perform_op", 0);
-  if (call == CANCELLED_CALL) {
-    grpc_transport_stream_op_finish_with_failure(exec_ctx, op,
-                                                 GRPC_ERROR_CANCELLED);
-    GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0);
-    return;
-  }
-  if (call != NULL) {
-    grpc_subchannel_call_process_op(exec_ctx, call, op);
-    GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0);
-    return;
-  }
-  /* we failed; lock and figure out what to do */
-  gpr_mu_lock(&holder->mu);
-retry:
-  /* need to recheck that another thread hasn't set the call */
-  call = GET_CALL(holder);
-  if (call == CANCELLED_CALL) {
-    gpr_mu_unlock(&holder->mu);
-    grpc_transport_stream_op_finish_with_failure(exec_ctx, op,
-                                                 GRPC_ERROR_CANCELLED);
-    GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0);
-    return;
-  }
-  if (call != NULL) {
-    gpr_mu_unlock(&holder->mu);
-    grpc_subchannel_call_process_op(exec_ctx, call, op);
-    GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0);
-    return;
-  }
-  /* if this is a cancellation, then we can raise our cancelled flag */
-  if (op->cancel_error != GRPC_ERROR_NONE) {
-    if (!gpr_atm_rel_cas(&holder->subchannel_call, 0,
-                         (gpr_atm)(uintptr_t)CANCELLED_CALL)) {
-      goto retry;
-    } else {
-      switch (holder->creation_phase) {
-        case GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING:
-          fail_locked(exec_ctx, holder, GRPC_ERROR_REF(op->cancel_error));
-          break;
-        case GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL:
-          holder->pick_subchannel(exec_ctx, holder->pick_subchannel_arg, NULL,
-                                  0, &holder->connected_subchannel, NULL);
-          break;
-      }
-      gpr_mu_unlock(&holder->mu);
-      grpc_transport_stream_op_finish_with_failure(exec_ctx, op,
-                                                   GRPC_ERROR_CANCELLED);
-      GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0);
-      return;
-    }
-  }
-  /* if we don't have a subchannel, try to get one */
-  if (holder->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING &&
-      holder->connected_subchannel == NULL &&
-      op->send_initial_metadata != NULL) {
-    holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL;
-    grpc_closure_init(&holder->next_step, subchannel_ready, holder);
-    GRPC_CALL_STACK_REF(holder->owning_call, "pick_subchannel");
-    if (holder->pick_subchannel(
-            exec_ctx, holder->pick_subchannel_arg, op->send_initial_metadata,
-            op->send_initial_metadata_flags, &holder->connected_subchannel,
-            &holder->next_step)) {
-      holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
-      GRPC_CALL_STACK_UNREF(exec_ctx, holder->owning_call, "pick_subchannel");
-    }
-  }
-  /* if we've got a subchannel, then let's ask it to create a call */
-  if (holder->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING &&
-      holder->connected_subchannel != NULL) {
-    grpc_subchannel_call *subchannel_call = NULL;
-    grpc_error *error = grpc_connected_subchannel_create_call(
-        exec_ctx, holder->connected_subchannel, holder->pollent,
-        &subchannel_call);
-    if (error != GRPC_ERROR_NONE) {
-      subchannel_call = CANCELLED_CALL;
-      fail_locked(exec_ctx, holder, GRPC_ERROR_REF(error));
-      grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error);
-    }
-    gpr_atm_rel_store(&holder->subchannel_call,
-                      (gpr_atm)(uintptr_t)subchannel_call);
-    retry_waiting_locked(exec_ctx, holder);
-    goto retry;
-  }
-  /* nothing to be done but wait */
-  add_waiting_locked(holder, op);
-  gpr_mu_unlock(&holder->mu);
-  GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0);
-}
-
-static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg,
-                             grpc_error *error) {
-  grpc_subchannel_call_holder *holder = arg;
-  gpr_mu_lock(&holder->mu);
-  GPR_ASSERT(holder->creation_phase ==
-             GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL);
-  holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
-  if (holder->connected_subchannel == NULL) {
-    gpr_atm_no_barrier_store(&holder->subchannel_call, 1);
-    fail_locked(exec_ctx, holder,
-                GRPC_ERROR_CREATE_REFERENCING("Failed to create subchannel",
-                                              &error, 1));
-  } else if (1 == gpr_atm_acq_load(&holder->subchannel_call)) {
-    /* already cancelled before subchannel became ready */
-    fail_locked(exec_ctx, holder,
-                GRPC_ERROR_CREATE_REFERENCING(
-                    "Cancelled before creating subchannel", &error, 1));
-  } else {
-    grpc_subchannel_call *subchannel_call = NULL;
-    grpc_error *new_error = grpc_connected_subchannel_create_call(
-        exec_ctx, holder->connected_subchannel, holder->pollent,
-        &subchannel_call);
-    if (new_error != GRPC_ERROR_NONE) {
-      new_error = grpc_error_add_child(new_error, error);
-      subchannel_call = CANCELLED_CALL;
-      fail_locked(exec_ctx, holder, new_error);
-    }
-    gpr_atm_rel_store(&holder->subchannel_call,
-                      (gpr_atm)(uintptr_t)subchannel_call);
-    retry_waiting_locked(exec_ctx, holder);
-  }
-  gpr_mu_unlock(&holder->mu);
-  GRPC_CALL_STACK_UNREF(exec_ctx, holder->owning_call, "pick_subchannel");
-}
-
-typedef struct {
-  grpc_transport_stream_op **ops;
-  size_t nops;
-  grpc_subchannel_call *call;
-} retry_ops_args;
-
-static void retry_waiting_locked(grpc_exec_ctx *exec_ctx,
-                                 grpc_subchannel_call_holder *holder) {
-  if (holder->waiting_ops_count == 0) {
-    return;
-  }
-
-  retry_ops_args *a = gpr_malloc(sizeof(*a));
-  a->ops = holder->waiting_ops;
-  a->nops = holder->waiting_ops_count;
-  a->call = GET_CALL(holder);
-  if (a->call == CANCELLED_CALL) {
-    gpr_free(a);
-    fail_locked(exec_ctx, holder, GRPC_ERROR_CANCELLED);
-    return;
-  }
-  holder->waiting_ops = NULL;
-  holder->waiting_ops_count = 0;
-  holder->waiting_ops_capacity = 0;
-  GRPC_SUBCHANNEL_CALL_REF(a->call, "retry_ops");
-  grpc_exec_ctx_sched(exec_ctx, grpc_closure_create(retry_ops, a),
-                      GRPC_ERROR_NONE, NULL);
-}
-
-static void retry_ops(grpc_exec_ctx *exec_ctx, void *args, grpc_error *error) {
-  retry_ops_args *a = args;
-  size_t i;
-  for (i = 0; i < a->nops; i++) {
-    grpc_subchannel_call_process_op(exec_ctx, a->call, a->ops[i]);
-  }
-  GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, a->call, "retry_ops");
-  gpr_free(a->ops);
-  gpr_free(a);
-}
-
-static void add_waiting_locked(grpc_subchannel_call_holder *holder,
-                               grpc_transport_stream_op *op) {
-  GPR_TIMER_BEGIN("add_waiting_locked", 0);
-  if (holder->waiting_ops_count == holder->waiting_ops_capacity) {
-    holder->waiting_ops_capacity = GPR_MAX(3, 2 * holder->waiting_ops_capacity);
-    holder->waiting_ops =
-        gpr_realloc(holder->waiting_ops, holder->waiting_ops_capacity *
-                                             sizeof(*holder->waiting_ops));
-  }
-  holder->waiting_ops[holder->waiting_ops_count++] = op;
-  GPR_TIMER_END("add_waiting_locked", 0);
-}
-
-static void fail_locked(grpc_exec_ctx *exec_ctx,
-                        grpc_subchannel_call_holder *holder,
-                        grpc_error *error) {
-  size_t i;
-  for (i = 0; i < holder->waiting_ops_count; i++) {
-    grpc_transport_stream_op_finish_with_failure(
-        exec_ctx, holder->waiting_ops[i], GRPC_ERROR_REF(error));
-  }
-  holder->waiting_ops_count = 0;
-  GRPC_ERROR_UNREF(error);
-}
-
-char *grpc_subchannel_call_holder_get_peer(
-    grpc_exec_ctx *exec_ctx, grpc_subchannel_call_holder *holder) {
-  grpc_subchannel_call *subchannel_call = GET_CALL(holder);
-
-  if (subchannel_call == NULL || subchannel_call == CANCELLED_CALL) {
-    return NULL;
-  } else {
-    return grpc_subchannel_call_get_peer(exec_ctx, subchannel_call);
-  }
-}

+ 0 - 99
src/core/ext/client_config/subchannel_call_holder.h

@@ -1,99 +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 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/lib/iomgr/polling_entity.h"
-
-/** Pick a subchannel for grpc_subchannel_call_holder;
-    Return 1 if subchannel is available immediately (in which case on_ready
-    should not be called), or 0 otherwise (in which case on_ready should be
-    called when the subchannel is available) */
-typedef int (*grpc_subchannel_call_holder_pick_subchannel)(
-    grpc_exec_ctx *exec_ctx, void *arg, grpc_metadata_batch *initial_metadata,
-    uint32_t initial_metadata_flags,
-    grpc_connected_subchannel **connected_subchannel, grpc_closure *on_ready);
-
-typedef enum {
-  GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING,
-  GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL
-} grpc_subchannel_call_holder_creation_phase;
-
-/** Wrapper for holding a pointer to grpc_subchannel_call, and the
-    associated machinery to create such a pointer.
-    Handles queueing of stream ops until a call object is ready, waiting
-    for initial metadata before trying to create a call object,
-    and handling cancellation gracefully.
-
-    The channel filter uses this as their call_data. */
-typedef struct grpc_subchannel_call_holder {
-  /** either 0 for no call, 1 for cancelled, or a pointer to a
-      grpc_subchannel_call */
-  gpr_atm subchannel_call;
-  /** Helper function to choose the subchannel on which to create
-      the call object. Channel filter delegates to the load
-      balancing policy (once it's ready). */
-  grpc_subchannel_call_holder_pick_subchannel pick_subchannel;
-  void *pick_subchannel_arg;
-
-  gpr_mu mu;
-
-  grpc_subchannel_call_holder_creation_phase creation_phase;
-  grpc_connected_subchannel *connected_subchannel;
-  grpc_polling_entity *pollent;
-
-  grpc_transport_stream_op **waiting_ops;
-  size_t waiting_ops_count;
-  size_t waiting_ops_capacity;
-
-  grpc_closure next_step;
-
-  grpc_call_stack *owning_call;
-} grpc_subchannel_call_holder;
-
-void grpc_subchannel_call_holder_init(
-    grpc_subchannel_call_holder *holder,
-    grpc_subchannel_call_holder_pick_subchannel pick_subchannel,
-    void *pick_subchannel_arg, grpc_call_stack *owning_call);
-void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx,
-                                         grpc_subchannel_call_holder *holder);
-
-void grpc_subchannel_call_holder_perform_op(grpc_exec_ctx *exec_ctx,
-                                            grpc_subchannel_call_holder *holder,
-                                            grpc_transport_stream_op *op);
-char *grpc_subchannel_call_holder_get_peer(grpc_exec_ctx *exec_ctx,
-                                           grpc_subchannel_call_holder *holder);
-
-#endif /* GRPC_CORE_EXT_CLIENT_CONFIG_SUBCHANNEL_CALL_HOLDER_H */

+ 21 - 21
src/core/ext/resolver/dns/native/dns_resolver.c

@@ -67,16 +67,16 @@ typedef struct {
   gpr_mu mu;
   gpr_mu mu;
   /** are we currently resolving? */
   /** are we currently resolving? */
   int resolving;
   int resolving;
-  /** which version of resolved_config have we published? */
+  /** which version of the result have we published? */
   int published_version;
   int published_version;
-  /** which version of resolved_config is current? */
+  /** which version of the result is current? */
   int resolved_version;
   int resolved_version;
   /** pending next completion, or NULL */
   /** pending next completion, or NULL */
   grpc_closure *next_completion;
   grpc_closure *next_completion;
-  /** target config address for next completion */
-  grpc_client_config **target_config;
-  /** current (fully resolved) config */
-  grpc_client_config *resolved_config;
+  /** target result address for next completion */
+  grpc_resolver_result **target_result;
+  /** current (fully resolved) result */
+  grpc_resolver_result *resolved_result;
   /** retry timer */
   /** retry timer */
   bool have_retry_timer;
   bool have_retry_timer;
   grpc_timer retry_timer;
   grpc_timer retry_timer;
@@ -97,7 +97,7 @@ static void dns_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
 static void dns_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
 static void dns_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
 static void dns_channel_saw_error(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
 static void dns_channel_saw_error(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
 static void dns_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r,
 static void dns_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r,
-                     grpc_client_config **target_config,
+                     grpc_resolver_result **target_result,
                      grpc_closure *on_complete);
                      grpc_closure *on_complete);
 
 
 static const grpc_resolver_vtable dns_resolver_vtable = {
 static const grpc_resolver_vtable dns_resolver_vtable = {
@@ -110,7 +110,7 @@ static void dns_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver) {
     grpc_timer_cancel(exec_ctx, &r->retry_timer);
     grpc_timer_cancel(exec_ctx, &r->retry_timer);
   }
   }
   if (r->next_completion != NULL) {
   if (r->next_completion != NULL) {
-    *r->target_config = NULL;
+    *r->target_result = NULL;
     grpc_exec_ctx_sched(exec_ctx, r->next_completion,
     grpc_exec_ctx_sched(exec_ctx, r->next_completion,
                         GRPC_ERROR_CREATE("Resolver Shutdown"), NULL);
                         GRPC_ERROR_CREATE("Resolver Shutdown"), NULL);
     r->next_completion = NULL;
     r->next_completion = NULL;
@@ -130,13 +130,13 @@ static void dns_channel_saw_error(grpc_exec_ctx *exec_ctx,
 }
 }
 
 
 static void dns_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
 static void dns_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
-                     grpc_client_config **target_config,
+                     grpc_resolver_result **target_result,
                      grpc_closure *on_complete) {
                      grpc_closure *on_complete) {
   dns_resolver *r = (dns_resolver *)resolver;
   dns_resolver *r = (dns_resolver *)resolver;
   gpr_mu_lock(&r->mu);
   gpr_mu_lock(&r->mu);
   GPR_ASSERT(!r->next_completion);
   GPR_ASSERT(!r->next_completion);
   r->next_completion = on_complete;
   r->next_completion = on_complete;
-  r->target_config = target_config;
+  r->target_result = target_result;
   if (r->resolved_version == 0 && !r->resolving) {
   if (r->resolved_version == 0 && !r->resolving) {
     gpr_backoff_reset(&r->backoff_state);
     gpr_backoff_reset(&r->backoff_state);
     dns_start_resolving_locked(exec_ctx, r);
     dns_start_resolving_locked(exec_ctx, r);
@@ -165,7 +165,7 @@ static void dns_on_retry_timer(grpc_exec_ctx *exec_ctx, void *arg,
 static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
 static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
                             grpc_error *error) {
                             grpc_error *error) {
   dns_resolver *r = arg;
   dns_resolver *r = arg;
-  grpc_client_config *config = NULL;
+  grpc_resolver_result *result = NULL;
   grpc_lb_policy *lb_policy;
   grpc_lb_policy *lb_policy;
   gpr_mu_lock(&r->mu);
   gpr_mu_lock(&r->mu);
   GPR_ASSERT(r->resolving);
   GPR_ASSERT(r->resolving);
@@ -173,14 +173,14 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
   grpc_resolved_addresses *addresses = r->addresses;
   grpc_resolved_addresses *addresses = r->addresses;
   if (addresses != NULL) {
   if (addresses != NULL) {
     grpc_lb_policy_args lb_policy_args;
     grpc_lb_policy_args lb_policy_args;
-    config = grpc_client_config_create();
+    result = grpc_resolver_result_create();
     memset(&lb_policy_args, 0, sizeof(lb_policy_args));
     memset(&lb_policy_args, 0, sizeof(lb_policy_args));
     lb_policy_args.addresses = addresses;
     lb_policy_args.addresses = addresses;
     lb_policy_args.client_channel_factory = r->client_channel_factory;
     lb_policy_args.client_channel_factory = r->client_channel_factory;
     lb_policy =
     lb_policy =
         grpc_lb_policy_create(exec_ctx, r->lb_policy_name, &lb_policy_args);
         grpc_lb_policy_create(exec_ctx, r->lb_policy_name, &lb_policy_args);
     if (lb_policy != NULL) {
     if (lb_policy != NULL) {
-      grpc_client_config_set_lb_policy(config, lb_policy);
+      grpc_resolver_result_set_lb_policy(result, lb_policy);
       GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "construction");
       GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "construction");
     }
     }
     grpc_resolved_addresses_destroy(addresses);
     grpc_resolved_addresses_destroy(addresses);
@@ -203,10 +203,10 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
     grpc_timer_init(exec_ctx, &r->retry_timer, next_try, dns_on_retry_timer, r,
     grpc_timer_init(exec_ctx, &r->retry_timer, next_try, dns_on_retry_timer, r,
                     now);
                     now);
   }
   }
-  if (r->resolved_config) {
-    grpc_client_config_unref(exec_ctx, r->resolved_config);
+  if (r->resolved_result) {
+    grpc_resolver_result_unref(exec_ctx, r->resolved_result);
   }
   }
-  r->resolved_config = config;
+  r->resolved_result = result;
   r->resolved_version++;
   r->resolved_version++;
   dns_maybe_finish_next_locked(exec_ctx, r);
   dns_maybe_finish_next_locked(exec_ctx, r);
   gpr_mu_unlock(&r->mu);
   gpr_mu_unlock(&r->mu);
@@ -228,9 +228,9 @@ static void dns_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
                                          dns_resolver *r) {
                                          dns_resolver *r) {
   if (r->next_completion != NULL &&
   if (r->next_completion != NULL &&
       r->resolved_version != r->published_version) {
       r->resolved_version != r->published_version) {
-    *r->target_config = r->resolved_config;
-    if (r->resolved_config) {
-      grpc_client_config_ref(r->resolved_config);
+    *r->target_result = r->resolved_result;
+    if (r->resolved_result) {
+      grpc_resolver_result_ref(r->resolved_result);
     }
     }
     grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL);
     grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL);
     r->next_completion = NULL;
     r->next_completion = NULL;
@@ -241,8 +241,8 @@ static void dns_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
 static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
 static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
   dns_resolver *r = (dns_resolver *)gr;
   dns_resolver *r = (dns_resolver *)gr;
   gpr_mu_destroy(&r->mu);
   gpr_mu_destroy(&r->mu);
-  if (r->resolved_config) {
-    grpc_client_config_unref(exec_ctx, r->resolved_config);
+  if (r->resolved_result) {
+    grpc_resolver_result_unref(exec_ctx, r->resolved_result);
   }
   }
   grpc_client_channel_factory_unref(exec_ctx, r->client_channel_factory);
   grpc_client_channel_factory_unref(exec_ctx, r->client_channel_factory);
   gpr_free(r->name);
   gpr_free(r->name);

+ 9 - 9
src/core/ext/resolver/sockaddr/sockaddr_resolver.c

@@ -66,8 +66,8 @@ typedef struct {
   int published;
   int published;
   /** pending next completion, or NULL */
   /** pending next completion, or NULL */
   grpc_closure *next_completion;
   grpc_closure *next_completion;
-  /** target config address for next completion */
-  grpc_client_config **target_config;
+  /** target result address for next completion */
+  grpc_resolver_result **target_result;
 } sockaddr_resolver;
 } sockaddr_resolver;
 
 
 static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
 static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
@@ -79,7 +79,7 @@ static void sockaddr_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
 static void sockaddr_channel_saw_error(grpc_exec_ctx *exec_ctx,
 static void sockaddr_channel_saw_error(grpc_exec_ctx *exec_ctx,
                                        grpc_resolver *r);
                                        grpc_resolver *r);
 static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r,
 static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r,
-                          grpc_client_config **target_config,
+                          grpc_resolver_result **target_result,
                           grpc_closure *on_complete);
                           grpc_closure *on_complete);
 
 
 static const grpc_resolver_vtable sockaddr_resolver_vtable = {
 static const grpc_resolver_vtable sockaddr_resolver_vtable = {
@@ -91,7 +91,7 @@ static void sockaddr_shutdown(grpc_exec_ctx *exec_ctx,
   sockaddr_resolver *r = (sockaddr_resolver *)resolver;
   sockaddr_resolver *r = (sockaddr_resolver *)resolver;
   gpr_mu_lock(&r->mu);
   gpr_mu_lock(&r->mu);
   if (r->next_completion != NULL) {
   if (r->next_completion != NULL) {
-    *r->target_config = NULL;
+    *r->target_result = NULL;
     grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL);
     grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL);
     r->next_completion = NULL;
     r->next_completion = NULL;
   }
   }
@@ -108,13 +108,13 @@ static void sockaddr_channel_saw_error(grpc_exec_ctx *exec_ctx,
 }
 }
 
 
 static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
 static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
-                          grpc_client_config **target_config,
+                          grpc_resolver_result **target_result,
                           grpc_closure *on_complete) {
                           grpc_closure *on_complete) {
   sockaddr_resolver *r = (sockaddr_resolver *)resolver;
   sockaddr_resolver *r = (sockaddr_resolver *)resolver;
   gpr_mu_lock(&r->mu);
   gpr_mu_lock(&r->mu);
   GPR_ASSERT(!r->next_completion);
   GPR_ASSERT(!r->next_completion);
   r->next_completion = on_complete;
   r->next_completion = on_complete;
-  r->target_config = target_config;
+  r->target_result = target_result;
   sockaddr_maybe_finish_next_locked(exec_ctx, r);
   sockaddr_maybe_finish_next_locked(exec_ctx, r);
   gpr_mu_unlock(&r->mu);
   gpr_mu_unlock(&r->mu);
 }
 }
@@ -122,17 +122,17 @@ static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
 static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
 static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
                                               sockaddr_resolver *r) {
                                               sockaddr_resolver *r) {
   if (r->next_completion != NULL && !r->published) {
   if (r->next_completion != NULL && !r->published) {
-    grpc_client_config *cfg = grpc_client_config_create();
+    grpc_resolver_result *result = grpc_resolver_result_create();
     grpc_lb_policy_args lb_policy_args;
     grpc_lb_policy_args lb_policy_args;
     memset(&lb_policy_args, 0, sizeof(lb_policy_args));
     memset(&lb_policy_args, 0, sizeof(lb_policy_args));
     lb_policy_args.addresses = r->addresses;
     lb_policy_args.addresses = r->addresses;
     lb_policy_args.client_channel_factory = r->client_channel_factory;
     lb_policy_args.client_channel_factory = r->client_channel_factory;
     grpc_lb_policy *lb_policy =
     grpc_lb_policy *lb_policy =
         grpc_lb_policy_create(exec_ctx, r->lb_policy_name, &lb_policy_args);
         grpc_lb_policy_create(exec_ctx, r->lb_policy_name, &lb_policy_args);
-    grpc_client_config_set_lb_policy(cfg, lb_policy);
+    grpc_resolver_result_set_lb_policy(result, lb_policy);
     GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "sockaddr");
     GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "sockaddr");
     r->published = 1;
     r->published = 1;
-    *r->target_config = cfg;
+    *r->target_result = result;
     grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL);
     grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL);
     r->next_completion = NULL;
     r->next_completion = NULL;
   }
   }

+ 170 - 12
src/core/lib/channel/http_client_filter.c

@@ -43,6 +43,9 @@
 #define EXPECTED_CONTENT_TYPE "application/grpc"
 #define EXPECTED_CONTENT_TYPE "application/grpc"
 #define EXPECTED_CONTENT_TYPE_LENGTH sizeof(EXPECTED_CONTENT_TYPE) - 1
 #define EXPECTED_CONTENT_TYPE_LENGTH sizeof(EXPECTED_CONTENT_TYPE) - 1
 
 
+/* default maximum size of payload eligable for GET request */
+static const size_t kMaxPayloadSizeForGet = 2048;
+
 typedef struct call_data {
 typedef struct call_data {
   grpc_linked_mdelem method;
   grpc_linked_mdelem method;
   grpc_linked_mdelem scheme;
   grpc_linked_mdelem scheme;
@@ -50,20 +53,39 @@ typedef struct call_data {
   grpc_linked_mdelem te_trailers;
   grpc_linked_mdelem te_trailers;
   grpc_linked_mdelem content_type;
   grpc_linked_mdelem content_type;
   grpc_linked_mdelem user_agent;
   grpc_linked_mdelem user_agent;
+  grpc_linked_mdelem payload_bin;
 
 
   grpc_metadata_batch *recv_initial_metadata;
   grpc_metadata_batch *recv_initial_metadata;
+  uint8_t *payload_bytes;
+
+  /* Vars to read data off of send_message */
+  grpc_transport_stream_op send_op;
+  uint32_t send_length;
+  uint32_t send_flags;
+  gpr_slice incoming_slice;
+  grpc_slice_buffer_stream replacement_stream;
+  gpr_slice_buffer slices;
+  /* flag that indicates that all slices of send_messages aren't availble */
+  bool send_message_blocked;
 
 
   /** Closure to call when finished with the hc_on_recv hook */
   /** Closure to call when finished with the hc_on_recv hook */
   grpc_closure *on_done_recv;
   grpc_closure *on_done_recv;
+  grpc_closure *on_complete;
+  grpc_closure *post_send;
+
   /** Receive closures are chained: we inject this closure as the on_done_recv
   /** Receive closures are chained: we inject this closure as the on_done_recv
       up-call on transport_op, and remember to call our on_done_recv member
       up-call on transport_op, and remember to call our on_done_recv member
       after handling it. */
       after handling it. */
   grpc_closure hc_on_recv;
   grpc_closure hc_on_recv;
+  grpc_closure hc_on_complete;
+  grpc_closure got_slice;
+  grpc_closure send_done;
 } call_data;
 } call_data;
 
 
 typedef struct channel_data {
 typedef struct channel_data {
   grpc_mdelem *static_scheme;
   grpc_mdelem *static_scheme;
   grpc_mdelem *user_agent;
   grpc_mdelem *user_agent;
+  size_t max_payload_size_for_get;
 } channel_data;
 } channel_data;
 
 
 typedef struct {
 typedef struct {
@@ -119,6 +141,24 @@ static void hc_on_recv(grpc_exec_ctx *exec_ctx, void *user_data,
   calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, error);
   calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, error);
 }
 }
 
 
+static void hc_on_complete(grpc_exec_ctx *exec_ctx, void *user_data,
+                           grpc_error *error) {
+  grpc_call_element *elem = user_data;
+  call_data *calld = elem->call_data;
+  if (calld->payload_bytes) {
+    gpr_free(calld->payload_bytes);
+    calld->payload_bytes = NULL;
+  }
+  calld->on_complete->cb(exec_ctx, calld->on_complete->cb_arg, error);
+}
+
+static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
+  grpc_call_element *elem = elemp;
+  call_data *calld = elem->call_data;
+  gpr_slice_buffer_reset_and_unref(&calld->slices);
+  calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, error);
+}
+
 static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) {
 static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) {
   /* eat the things we'd like to set ourselves */
   /* eat the things we'd like to set ourselves */
   if (md->key == GRPC_MDSTR_METHOD) return NULL;
   if (md->key == GRPC_MDSTR_METHOD) return NULL;
@@ -129,22 +169,105 @@ static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) {
   return md;
   return md;
 }
 }
 
 
-static void hc_mutate_op(grpc_call_element *elem,
+static void continue_send_message(grpc_exec_ctx *exec_ctx,
+                                  grpc_call_element *elem) {
+  call_data *calld = elem->call_data;
+  uint8_t *wrptr = calld->payload_bytes;
+  while (grpc_byte_stream_next(exec_ctx, calld->send_op.send_message,
+                               &calld->incoming_slice, ~(size_t)0,
+                               &calld->got_slice)) {
+    memcpy(wrptr, GPR_SLICE_START_PTR(calld->incoming_slice),
+           GPR_SLICE_LENGTH(calld->incoming_slice));
+    wrptr += GPR_SLICE_LENGTH(calld->incoming_slice);
+    gpr_slice_buffer_add(&calld->slices, calld->incoming_slice);
+    if (calld->send_length == calld->slices.length) {
+      calld->send_message_blocked = false;
+      break;
+    }
+  }
+}
+
+static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
+  grpc_call_element *elem = elemp;
+  call_data *calld = elem->call_data;
+  calld->send_message_blocked = false;
+  gpr_slice_buffer_add(&calld->slices, calld->incoming_slice);
+  if (calld->send_length == calld->slices.length) {
+    /* Pass down the original send_message op that was blocked.*/
+    grpc_slice_buffer_stream_init(&calld->replacement_stream, &calld->slices,
+                                  calld->send_flags);
+    calld->send_op.send_message = &calld->replacement_stream.base;
+    calld->post_send = calld->send_op.on_complete;
+    calld->send_op.on_complete = &calld->send_done;
+    grpc_call_next_op(exec_ctx, elem, &calld->send_op);
+  } else {
+    continue_send_message(exec_ctx, elem);
+  }
+}
+
+static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                          grpc_transport_stream_op *op) {
                          grpc_transport_stream_op *op) {
   /* grab pointers to our data from the call element */
   /* grab pointers to our data from the call element */
   call_data *calld = elem->call_data;
   call_data *calld = elem->call_data;
   channel_data *channeld = elem->channel_data;
   channel_data *channeld = elem->channel_data;
+
   if (op->send_initial_metadata != NULL) {
   if (op->send_initial_metadata != NULL) {
+    /* Decide which HTTP VERB to use. We use GET if the request is marked
+    cacheable, and the operation contains both initial metadata and send
+    message, and the payload is below the size threshold, and all the data
+    for this request is immediately available. */
+    grpc_mdelem *method = GRPC_MDELEM_METHOD_POST;
+    calld->send_message_blocked = false;
+    if ((op->send_initial_metadata_flags &
+         GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) &&
+        op->send_message != NULL &&
+        op->send_message->length < channeld->max_payload_size_for_get) {
+      method = GRPC_MDELEM_METHOD_GET;
+      calld->send_message_blocked = true;
+    } else if (op->send_initial_metadata_flags &
+               GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) {
+      method = GRPC_MDELEM_METHOD_PUT;
+    }
+
+    /* Attempt to read the data from send_message and create a header field. */
+    if (method == GRPC_MDELEM_METHOD_GET) {
+      /* allocate memory to hold the entire payload */
+      calld->payload_bytes = gpr_malloc(op->send_message->length);
+      GPR_ASSERT(calld->payload_bytes);
+
+      /* read slices of send_message and copy into payload_bytes */
+      calld->send_op = *op;
+      calld->send_length = op->send_message->length;
+      calld->send_flags = op->send_message->flags;
+      continue_send_message(exec_ctx, elem);
+
+      if (calld->send_message_blocked == false) {
+        /* when all the send_message data is available, then create a MDELEM and
+        append to headers */
+        grpc_mdelem *payload_bin = grpc_mdelem_from_metadata_strings(
+            GRPC_MDSTR_GRPC_PAYLOAD_BIN,
+            grpc_mdstr_from_buffer(calld->payload_bytes,
+                                   op->send_message->length));
+        grpc_metadata_batch_add_tail(op->send_initial_metadata,
+                                     &calld->payload_bin, payload_bin);
+        calld->on_complete = op->on_complete;
+        op->on_complete = &calld->hc_on_complete;
+        op->send_message = NULL;
+      } else {
+        /* Not all data is available. Fall back to POST. */
+        gpr_log(GPR_DEBUG,
+                "Request is marked Cacheable but not all data is available.\
+                            Falling back to POST");
+        method = GRPC_MDELEM_METHOD_POST;
+      }
+    }
+
     grpc_metadata_batch_filter(op->send_initial_metadata, client_strip_filter,
     grpc_metadata_batch_filter(op->send_initial_metadata, client_strip_filter,
                                elem);
                                elem);
     /* Send : prefixed headers, which have to be before any application
     /* Send : prefixed headers, which have to be before any application
        layer headers. */
        layer headers. */
-    grpc_metadata_batch_add_head(
-        op->send_initial_metadata, &calld->method,
-        op->send_initial_metadata_flags &
-                GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
-            ? GRPC_MDELEM_METHOD_PUT
-            : GRPC_MDELEM_METHOD_POST);
+    grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->method,
+                                 method);
     grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->scheme,
     grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->scheme,
                                  channeld->static_scheme);
                                  channeld->static_scheme);
     grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->te_trailers,
     grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->te_trailers,
@@ -169,9 +292,16 @@ static void hc_start_transport_op(grpc_exec_ctx *exec_ctx,
                                   grpc_transport_stream_op *op) {
                                   grpc_transport_stream_op *op) {
   GPR_TIMER_BEGIN("hc_start_transport_op", 0);
   GPR_TIMER_BEGIN("hc_start_transport_op", 0);
   GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
   GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
-  hc_mutate_op(elem, op);
+  hc_mutate_op(exec_ctx, elem, op);
   GPR_TIMER_END("hc_start_transport_op", 0);
   GPR_TIMER_END("hc_start_transport_op", 0);
-  grpc_call_next_op(exec_ctx, elem, op);
+  call_data *calld = elem->call_data;
+  if (op->send_message != NULL && calld->send_message_blocked) {
+    /* Don't forward the op. send_message contains slices that aren't ready
+    yet. The call will be forwarded by the op_complete of slice read call.
+    */
+  } else {
+    grpc_call_next_op(exec_ctx, elem, op);
+  }
 }
 }
 
 
 /* Constructor for call_data */
 /* Constructor for call_data */
@@ -180,14 +310,23 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
                                   grpc_call_element_args *args) {
                                   grpc_call_element_args *args) {
   call_data *calld = elem->call_data;
   call_data *calld = elem->call_data;
   calld->on_done_recv = NULL;
   calld->on_done_recv = NULL;
+  calld->on_complete = NULL;
+  calld->payload_bytes = NULL;
+  gpr_slice_buffer_init(&calld->slices);
   grpc_closure_init(&calld->hc_on_recv, hc_on_recv, elem);
   grpc_closure_init(&calld->hc_on_recv, hc_on_recv, elem);
+  grpc_closure_init(&calld->hc_on_complete, hc_on_complete, elem);
+  grpc_closure_init(&calld->got_slice, got_slice, elem);
+  grpc_closure_init(&calld->send_done, send_done, elem);
   return GRPC_ERROR_NONE;
   return GRPC_ERROR_NONE;
 }
 }
 
 
 /* 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_final_info *final_info,
                               const grpc_call_final_info *final_info,
-                              void *ignored) {}
+                              void *ignored) {
+  call_data *calld = elem->call_data;
+  gpr_slice_buffer_destroy(&calld->slices);
+}
 
 
 static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) {
 static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) {
   unsigned i;
   unsigned i;
@@ -210,6 +349,22 @@ static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) {
   return GRPC_MDELEM_SCHEME_HTTP;
   return GRPC_MDELEM_SCHEME_HTTP;
 }
 }
 
 
+static size_t max_payload_size_from_args(const grpc_channel_args *args) {
+  if (args != NULL) {
+    for (size_t i = 0; i < args->num_args; ++i) {
+      if (0 == strcmp(args->args[i].key, GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET)) {
+        if (args->args[i].type != GRPC_ARG_INTEGER) {
+          gpr_log(GPR_ERROR, "%s: must be an integer",
+                  GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET);
+        } else {
+          return (size_t)args->args[i].value.integer;
+        }
+      }
+    }
+  }
+  return kMaxPayloadSizeForGet;
+}
+
 static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args,
 static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args,
                                         const char *transport_name) {
                                         const char *transport_name) {
   gpr_strvec v;
   gpr_strvec v;
@@ -233,8 +388,9 @@ static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args,
     }
     }
   }
   }
 
 
-  gpr_asprintf(&tmp, "%sgrpc-c/%s (%s; %s)", is_first ? "" : " ",
-               grpc_version_string(), GPR_PLATFORM_STRING, transport_name);
+  gpr_asprintf(&tmp, "%sgrpc-c/%s (%s; %s; %s)", is_first ? "" : " ",
+               grpc_version_string(), GPR_PLATFORM_STRING, transport_name,
+               grpc_g_stands_for());
   is_first = 0;
   is_first = 0;
   gpr_strvec_add(&v, tmp);
   gpr_strvec_add(&v, tmp);
 
 
@@ -267,6 +423,8 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
   GPR_ASSERT(!args->is_last);
   GPR_ASSERT(!args->is_last);
   GPR_ASSERT(args->optional_transport != NULL);
   GPR_ASSERT(args->optional_transport != NULL);
   chand->static_scheme = scheme_from_args(args->channel_args);
   chand->static_scheme = scheme_from_args(args->channel_args);
+  chand->max_payload_size_for_get =
+      max_payload_size_from_args(args->channel_args);
   chand->user_agent = grpc_mdelem_from_metadata_strings(
   chand->user_agent = grpc_mdelem_from_metadata_strings(
       GRPC_MDSTR_USER_AGENT,
       GRPC_MDSTR_USER_AGENT,
       user_agent_from_args(args->channel_args,
       user_agent_from_args(args->channel_args,

+ 3 - 0
src/core/lib/channel/http_client_filter.h

@@ -41,4 +41,7 @@ extern const grpc_channel_filter grpc_http_client_filter;
 /* Channel arg to override the http2 :scheme header */
 /* Channel arg to override the http2 :scheme header */
 #define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme"
 #define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme"
 
 
+/* Channel arg to determine maximum size of payload eligable for GET request */
+#define GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET "grpc.max_payload_size_for_get"
+
 #endif /* GRPC_CORE_LIB_CHANNEL_HTTP_CLIENT_FILTER_H */
 #endif /* GRPC_CORE_LIB_CHANNEL_HTTP_CLIENT_FILTER_H */

+ 77 - 2
src/core/lib/channel/http_server_filter.c

@@ -49,17 +49,32 @@ typedef struct call_data {
   uint8_t seen_scheme;
   uint8_t seen_scheme;
   uint8_t seen_te_trailers;
   uint8_t seen_te_trailers;
   uint8_t seen_authority;
   uint8_t seen_authority;
+  uint8_t seen_payload_bin;
   grpc_linked_mdelem status;
   grpc_linked_mdelem status;
   grpc_linked_mdelem content_type;
   grpc_linked_mdelem content_type;
 
 
+  /* flag to ensure payload_bin is delivered only once */
+  uint8_t payload_bin_delivered;
+
   grpc_metadata_batch *recv_initial_metadata;
   grpc_metadata_batch *recv_initial_metadata;
   bool *recv_idempotent_request;
   bool *recv_idempotent_request;
+  bool *recv_cacheable_request;
   /** Closure to call when finished with the hs_on_recv hook */
   /** Closure to call when finished with the hs_on_recv hook */
   grpc_closure *on_done_recv;
   grpc_closure *on_done_recv;
+  /** Closure to call when we retrieve read message from the payload-bin header
+   */
+  grpc_closure *recv_message_ready;
+  grpc_closure *on_complete;
+  grpc_byte_stream **pp_recv_message;
+  gpr_slice_buffer read_slice_buffer;
+  grpc_slice_buffer_stream read_stream;
+
   /** Receive closures are chained: we inject this closure as the on_done_recv
   /** Receive closures are chained: we inject this closure as the on_done_recv
       up-call on transport_op, and remember to call our on_done_recv member
       up-call on transport_op, and remember to call our on_done_recv member
       after handling it. */
       after handling it. */
   grpc_closure hs_on_recv;
   grpc_closure hs_on_recv;
+  grpc_closure hs_on_complete;
+  grpc_closure hs_recv_message_ready;
 } call_data;
 } call_data;
 
 
 typedef struct channel_data { uint8_t unused; } channel_data;
 typedef struct channel_data { uint8_t unused; } channel_data;
@@ -76,16 +91,20 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
 
 
   /* Check if it is one of the headers we care about. */
   /* Check if it is one of the headers we care about. */
   if (md == GRPC_MDELEM_TE_TRAILERS || md == GRPC_MDELEM_METHOD_POST ||
   if (md == GRPC_MDELEM_TE_TRAILERS || md == GRPC_MDELEM_METHOD_POST ||
-      md == GRPC_MDELEM_METHOD_PUT || md == GRPC_MDELEM_SCHEME_HTTP ||
-      md == GRPC_MDELEM_SCHEME_HTTPS ||
+      md == GRPC_MDELEM_METHOD_PUT || md == GRPC_MDELEM_METHOD_GET ||
+      md == GRPC_MDELEM_SCHEME_HTTP || md == GRPC_MDELEM_SCHEME_HTTPS ||
       md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) {
       md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) {
     /* swallow it */
     /* swallow it */
     if (md == GRPC_MDELEM_METHOD_POST) {
     if (md == GRPC_MDELEM_METHOD_POST) {
       calld->seen_method = 1;
       calld->seen_method = 1;
       *calld->recv_idempotent_request = false;
       *calld->recv_idempotent_request = false;
+      *calld->recv_cacheable_request = false;
     } else if (md == GRPC_MDELEM_METHOD_PUT) {
     } else if (md == GRPC_MDELEM_METHOD_PUT) {
       calld->seen_method = 1;
       calld->seen_method = 1;
       *calld->recv_idempotent_request = true;
       *calld->recv_idempotent_request = true;
+    } else if (md == GRPC_MDELEM_METHOD_GET) {
+      calld->seen_method = 1;
+      *calld->recv_cacheable_request = true;
     } else if (md->key == GRPC_MDSTR_SCHEME) {
     } else if (md->key == GRPC_MDSTR_SCHEME) {
       calld->seen_scheme = 1;
       calld->seen_scheme = 1;
     } else if (md == GRPC_MDELEM_TE_TRAILERS) {
     } else if (md == GRPC_MDELEM_TE_TRAILERS) {
@@ -137,6 +156,16 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
         GRPC_MDSTR_AUTHORITY, GRPC_MDSTR_REF(md->value));
         GRPC_MDSTR_AUTHORITY, GRPC_MDSTR_REF(md->value));
     calld->seen_authority = 1;
     calld->seen_authority = 1;
     return authority;
     return authority;
+  } else if (md->key == GRPC_MDSTR_GRPC_PAYLOAD_BIN) {
+    /* Retrieve the payload from the value of the 'grpc-internal-payload-bin'
+       header field */
+    calld->seen_payload_bin = 1;
+    gpr_slice_buffer_init(&calld->read_slice_buffer);
+    gpr_slice_buffer_add(&calld->read_slice_buffer,
+                         gpr_slice_ref(md->value->slice));
+    grpc_slice_buffer_stream_init(&calld->read_stream,
+                                  &calld->read_slice_buffer, 0);
+    return NULL;
   } else {
   } else {
     return md;
     return md;
   }
   }
@@ -189,6 +218,36 @@ static void hs_on_recv(grpc_exec_ctx *exec_ctx, void *user_data,
   GRPC_ERROR_UNREF(err);
   GRPC_ERROR_UNREF(err);
 }
 }
 
 
+static void hs_on_complete(grpc_exec_ctx *exec_ctx, void *user_data,
+                           grpc_error *err) {
+  grpc_call_element *elem = user_data;
+  call_data *calld = elem->call_data;
+  /* Call recv_message_ready if we got the payload via the header field */
+  if (calld->seen_payload_bin && calld->recv_message_ready != NULL) {
+    *calld->pp_recv_message = calld->payload_bin_delivered
+                                  ? NULL
+                                  : (grpc_byte_stream *)&calld->read_stream;
+    calld->recv_message_ready->cb(exec_ctx, calld->recv_message_ready->cb_arg,
+                                  err);
+    calld->recv_message_ready = NULL;
+    calld->payload_bin_delivered = true;
+  }
+  calld->on_complete->cb(exec_ctx, calld->on_complete->cb_arg, err);
+}
+
+static void hs_recv_message_ready(grpc_exec_ctx *exec_ctx, void *user_data,
+                                  grpc_error *err) {
+  grpc_call_element *elem = user_data;
+  call_data *calld = elem->call_data;
+  if (calld->seen_payload_bin) {
+    /* do nothing. This is probably a GET request, and payload will be returned
+    in hs_on_complete callback. */
+  } else {
+    calld->recv_message_ready->cb(exec_ctx, calld->recv_message_ready->cb_arg,
+                                  err);
+  }
+}
+
 static void hs_mutate_op(grpc_call_element *elem,
 static void hs_mutate_op(grpc_call_element *elem,
                          grpc_transport_stream_op *op) {
                          grpc_transport_stream_op *op) {
   /* grab pointers to our data from the call element */
   /* grab pointers to our data from the call element */
@@ -206,11 +265,25 @@ static void hs_mutate_op(grpc_call_element *elem,
   if (op->recv_initial_metadata) {
   if (op->recv_initial_metadata) {
     /* substitute our callback for the higher callback */
     /* substitute our callback for the higher callback */
     GPR_ASSERT(op->recv_idempotent_request != NULL);
     GPR_ASSERT(op->recv_idempotent_request != NULL);
+    GPR_ASSERT(op->recv_cacheable_request != NULL);
     calld->recv_initial_metadata = op->recv_initial_metadata;
     calld->recv_initial_metadata = op->recv_initial_metadata;
     calld->recv_idempotent_request = op->recv_idempotent_request;
     calld->recv_idempotent_request = op->recv_idempotent_request;
+    calld->recv_cacheable_request = op->recv_cacheable_request;
     calld->on_done_recv = op->recv_initial_metadata_ready;
     calld->on_done_recv = op->recv_initial_metadata_ready;
     op->recv_initial_metadata_ready = &calld->hs_on_recv;
     op->recv_initial_metadata_ready = &calld->hs_on_recv;
   }
   }
+
+  if (op->recv_message) {
+    calld->recv_message_ready = op->recv_message_ready;
+    calld->pp_recv_message = op->recv_message;
+    if (op->recv_message_ready) {
+      op->recv_message_ready = &calld->hs_recv_message_ready;
+    }
+    if (op->on_complete) {
+      calld->on_complete = op->on_complete;
+      op->on_complete = &calld->hs_on_complete;
+    }
+  }
 }
 }
 
 
 static void hs_start_transport_op(grpc_exec_ctx *exec_ctx,
 static void hs_start_transport_op(grpc_exec_ctx *exec_ctx,
@@ -232,6 +305,8 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
   /* initialize members */
   /* initialize members */
   memset(calld, 0, sizeof(*calld));
   memset(calld, 0, sizeof(*calld));
   grpc_closure_init(&calld->hs_on_recv, hs_on_recv, elem);
   grpc_closure_init(&calld->hs_on_recv, hs_on_recv, elem);
+  grpc_closure_init(&calld->hs_on_complete, hs_on_complete, elem);
+  grpc_closure_init(&calld->hs_recv_message_ready, hs_recv_message_ready, elem);
   return GRPC_ERROR_NONE;
   return GRPC_ERROR_NONE;
 }
 }
 
 

+ 3 - 0
src/core/lib/iomgr/combiner.c

@@ -221,6 +221,9 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
       gpr_log(GPR_DEBUG, "C:%p finish old_state=%" PRIdPTR, lock, old_state));
       gpr_log(GPR_DEBUG, "C:%p finish old_state=%" PRIdPTR, lock, old_state));
   lock->time_to_execute_final_list = false;
   lock->time_to_execute_final_list = false;
   switch (old_state) {
   switch (old_state) {
+    default:
+      // we have multiple queued work items: just continue executing them
+      break;
     case 5:  // we're down to one queued item: if it's the final list we
     case 5:  // we're down to one queued item: if it's the final list we
     case 4:  // should do that
     case 4:  // should do that
       if (!grpc_closure_list_empty(lock->final_list)) {
       if (!grpc_closure_list_empty(lock->final_list)) {

+ 7 - 5
src/core/lib/iomgr/combiner.h

@@ -41,7 +41,7 @@
 #include "src/core/lib/support/mpscq.h"
 #include "src/core/lib/support/mpscq.h"
 
 
 // Provides serialized access to some resource.
 // Provides serialized access to some resource.
-// Each action queued on an aelock is executed serially in a borrowed thread.
+// Each action queued on a combiner is executed serially in a borrowed thread.
 // The actual thread executing actions may change over time (but there will only
 // The actual thread executing actions may change over time (but there will only
 // every be one at a time).
 // every be one at a time).
 
 
@@ -54,14 +54,16 @@ void grpc_combiner_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock);
 void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock,
 void grpc_combiner_execute(grpc_exec_ctx *exec_ctx, grpc_combiner *lock,
                            grpc_closure *closure, grpc_error *error);
                            grpc_closure *closure, grpc_error *error);
 // Execute \a action within the lock just prior to unlocking.
 // Execute \a action within the lock just prior to unlocking.
-// if \a hint_async_break is additionally set, the combiner is tries to trip
-// through the workqueue between finishing the primary queue of combined
-// closures and executing the finally list.
+// if \a hint_async_break is true, the combiner is tries to hand execution to
+// another thread before finishing the primary queue of combined closures and
+// executing the finally list.
+// Deprecation warning: \a hint_async_break will be removed in a future version
 // Takes a very slow and round-about path if not called from a
 // Takes a very slow and round-about path if not called from a
-// grpc_combiner_execute closure
+// grpc_combiner_execute closure.
 void grpc_combiner_execute_finally(grpc_exec_ctx *exec_ctx, grpc_combiner *lock,
 void grpc_combiner_execute_finally(grpc_exec_ctx *exec_ctx, grpc_combiner *lock,
                                    grpc_closure *closure, grpc_error *error,
                                    grpc_closure *closure, grpc_error *error,
                                    bool hint_async_break);
                                    bool hint_async_break);
+// Deprecated: force the finally list execution onto another thread
 void grpc_combiner_force_async_finally(grpc_combiner *lock);
 void grpc_combiner_force_async_finally(grpc_combiner *lock);
 
 
 bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx);
 bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx);

+ 2 - 1
src/core/lib/iomgr/error.h

@@ -47,7 +47,8 @@
 ///  if a grpc_error is passed to a grpc_closure callback function (functions
 ///  if a grpc_error is passed to a grpc_closure callback function (functions
 ///    with the signature:
 ///    with the signature:
 ///      void (*f)(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error))
 ///      void (*f)(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error))
-///    then those functions do not automatically own a ref to error
+///    then those functions do not own a ref to error (but are free to manually
+///    take a reference).
 ///  if a grpc_error is passed to *ANY OTHER FUNCTION* then that function takes
 ///  if a grpc_error is passed to *ANY OTHER FUNCTION* then that function takes
 ///    ownership of the error
 ///    ownership of the error
 /// Errors have:
 /// Errors have:

+ 5 - 1
src/core/lib/iomgr/ev_epoll_linux.c

@@ -928,7 +928,8 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
     fd->polling_island = NULL;
     fd->polling_island = NULL;
   }
   }
 
 
-  grpc_exec_ctx_sched(exec_ctx, fd->on_done_closure, error, NULL);
+  grpc_exec_ctx_sched(exec_ctx, fd->on_done_closure, GRPC_ERROR_REF(error),
+                      NULL);
 
 
   gpr_mu_unlock(&fd->mu);
   gpr_mu_unlock(&fd->mu);
   UNREF_BY(fd, 2, reason); /* Drop the reference */
   UNREF_BY(fd, 2, reason); /* Drop the reference */
@@ -940,6 +941,7 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
     PI_UNREF(exec_ctx, unref_pi, "fd_orphan");
     PI_UNREF(exec_ctx, unref_pi, "fd_orphan");
   }
   }
   GRPC_LOG_IF_ERROR("fd_orphan", GRPC_ERROR_REF(error));
   GRPC_LOG_IF_ERROR("fd_orphan", GRPC_ERROR_REF(error));
+  GRPC_ERROR_UNREF(error);
 }
 }
 
 
 static grpc_error *fd_shutdown_error(bool shutdown) {
 static grpc_error *fd_shutdown_error(bool shutdown) {
@@ -1353,8 +1355,10 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx,
   gpr_mu_unlock(&pollset->mu);
   gpr_mu_unlock(&pollset->mu);
 
 
   do {
   do {
+    GRPC_SCHEDULING_START_BLOCKING_REGION;
     ep_rv = epoll_pwait(epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, timeout_ms,
     ep_rv = epoll_pwait(epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, timeout_ms,
                         sig_mask);
                         sig_mask);
+    GRPC_SCHEDULING_END_BLOCKING_REGION;
     if (ep_rv < 0) {
     if (ep_rv < 0) {
       if (errno != EINTR) {
       if (errno != EINTR) {
         gpr_asprintf(&err_msg,
         gpr_asprintf(&err_msg,

+ 3 - 1
src/core/lib/iomgr/tcp_server_posix.c

@@ -140,15 +140,17 @@ struct grpc_tcp_server {
 };
 };
 
 
 static gpr_once check_init = GPR_ONCE_INIT;
 static gpr_once check_init = GPR_ONCE_INIT;
-static bool has_so_reuseport;
+static bool has_so_reuseport = false;
 
 
 static void init(void) {
 static void init(void) {
+#ifndef GPR_MANYLINUX1
   int s = socket(AF_INET, SOCK_STREAM, 0);
   int s = socket(AF_INET, SOCK_STREAM, 0);
   if (s >= 0) {
   if (s >= 0) {
     has_so_reuseport = GRPC_LOG_IF_ERROR("check for SO_REUSEPORT",
     has_so_reuseport = GRPC_LOG_IF_ERROR("check for SO_REUSEPORT",
                                          grpc_set_socket_reuse_port(s, 1));
                                          grpc_set_socket_reuse_port(s, 1));
     close(s);
     close(s);
   }
   }
+#endif
 }
 }
 
 
 grpc_error *grpc_tcp_server_create(grpc_closure *shutdown_complete,
 grpc_error *grpc_tcp_server_create(grpc_closure *shutdown_complete,

+ 6 - 0
src/core/lib/security/context/security_context.c

@@ -99,6 +99,9 @@ void grpc_client_security_context_destroy(void *ctx) {
   grpc_client_security_context *c = (grpc_client_security_context *)ctx;
   grpc_client_security_context *c = (grpc_client_security_context *)ctx;
   grpc_call_credentials_unref(c->creds);
   grpc_call_credentials_unref(c->creds);
   GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "client_security_context");
   GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "client_security_context");
+  if (c->extension.instance != NULL && c->extension.destroy != NULL) {
+    c->extension.destroy(c->extension.instance);
+  }
   gpr_free(ctx);
   gpr_free(ctx);
 }
 }
 
 
@@ -114,6 +117,9 @@ grpc_server_security_context *grpc_server_security_context_create(void) {
 void grpc_server_security_context_destroy(void *ctx) {
 void grpc_server_security_context_destroy(void *ctx) {
   grpc_server_security_context *c = (grpc_server_security_context *)ctx;
   grpc_server_security_context *c = (grpc_server_security_context *)ctx;
   GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "server_security_context");
   GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "server_security_context");
+  if (c->extension.instance != NULL && c->extension.destroy != NULL) {
+    c->extension.destroy(c->extension.instance);
+  }
   gpr_free(ctx);
   gpr_free(ctx);
 }
 }
 
 

+ 12 - 0
src/core/lib/security/context/security_context.h

@@ -84,6 +84,16 @@ void grpc_auth_context_unref(grpc_auth_context *policy);
 
 
 void grpc_auth_property_reset(grpc_auth_property *property);
 void grpc_auth_property_reset(grpc_auth_property *property);
 
 
+/* --- grpc_security_context_extension ---
+
+   Extension to the security context that may be set in a filter and accessed
+   later by a higher level method on a grpc_call object. */
+
+typedef struct {
+  void *instance;
+  void (*destroy)(void *);
+} grpc_security_context_extension;
+
 /* --- grpc_client_security_context ---
 /* --- grpc_client_security_context ---
 
 
    Internal client-side security context. */
    Internal client-side security context. */
@@ -91,6 +101,7 @@ void grpc_auth_property_reset(grpc_auth_property *property);
 typedef struct {
 typedef struct {
   grpc_call_credentials *creds;
   grpc_call_credentials *creds;
   grpc_auth_context *auth_context;
   grpc_auth_context *auth_context;
+  grpc_security_context_extension extension;
 } grpc_client_security_context;
 } grpc_client_security_context;
 
 
 grpc_client_security_context *grpc_client_security_context_create(void);
 grpc_client_security_context *grpc_client_security_context_create(void);
@@ -102,6 +113,7 @@ void grpc_client_security_context_destroy(void *ctx);
 
 
 typedef struct {
 typedef struct {
   grpc_auth_context *auth_context;
   grpc_auth_context *auth_context;
+  grpc_security_context_extension extension;
 } grpc_server_security_context;
 } grpc_server_security_context;
 
 
 grpc_server_security_context *grpc_server_security_context_create(void);
 grpc_server_security_context *grpc_server_security_context_create(void);

+ 7 - 4
src/core/lib/support/mpscq.c

@@ -38,7 +38,7 @@
 void gpr_mpscq_init(gpr_mpscq *q) {
 void gpr_mpscq_init(gpr_mpscq *q) {
   gpr_atm_no_barrier_store(&q->head, (gpr_atm)&q->stub);
   gpr_atm_no_barrier_store(&q->head, (gpr_atm)&q->stub);
   q->tail = &q->stub;
   q->tail = &q->stub;
-  gpr_atm_no_barrier_store(&q->stub.next, 0);
+  gpr_atm_no_barrier_store(&q->stub.next, (gpr_atm)NULL);
 }
 }
 
 
 void gpr_mpscq_destroy(gpr_mpscq *q) {
 void gpr_mpscq_destroy(gpr_mpscq *q) {
@@ -47,16 +47,17 @@ void gpr_mpscq_destroy(gpr_mpscq *q) {
 }
 }
 
 
 void gpr_mpscq_push(gpr_mpscq *q, gpr_mpscq_node *n) {
 void gpr_mpscq_push(gpr_mpscq *q, gpr_mpscq_node *n) {
-  gpr_atm_no_barrier_store(&n->next, 0);
+  gpr_atm_no_barrier_store(&n->next, (gpr_atm)NULL);
   gpr_mpscq_node *prev =
   gpr_mpscq_node *prev =
       (gpr_mpscq_node *)gpr_atm_full_xchg(&q->head, (gpr_atm)n);
       (gpr_mpscq_node *)gpr_atm_full_xchg(&q->head, (gpr_atm)n);
-  gpr_atm_rel_store(&prev->next, (gpr_atm)n);
+  gpr_atm_no_barrier_store(&prev->next, (gpr_atm)n);
 }
 }
 
 
 gpr_mpscq_node *gpr_mpscq_pop(gpr_mpscq *q) {
 gpr_mpscq_node *gpr_mpscq_pop(gpr_mpscq *q) {
   gpr_mpscq_node *tail = q->tail;
   gpr_mpscq_node *tail = q->tail;
   gpr_mpscq_node *next = (gpr_mpscq_node *)gpr_atm_acq_load(&tail->next);
   gpr_mpscq_node *next = (gpr_mpscq_node *)gpr_atm_acq_load(&tail->next);
   if (tail == &q->stub) {
   if (tail == &q->stub) {
+    // indicates the list is actually (ephemerally) empty
     if (next == NULL) return NULL;
     if (next == NULL) return NULL;
     q->tail = next;
     q->tail = next;
     tail = next;
     tail = next;
@@ -68,7 +69,8 @@ gpr_mpscq_node *gpr_mpscq_pop(gpr_mpscq *q) {
   }
   }
   gpr_mpscq_node *head = (gpr_mpscq_node *)gpr_atm_acq_load(&q->head);
   gpr_mpscq_node *head = (gpr_mpscq_node *)gpr_atm_acq_load(&q->head);
   if (tail != head) {
   if (tail != head) {
-    return 0;
+    // indicates a retry is in order: we're still adding
+    return NULL;
   }
   }
   gpr_mpscq_push(q, &q->stub);
   gpr_mpscq_push(q, &q->stub);
   next = (gpr_mpscq_node *)gpr_atm_acq_load(&tail->next);
   next = (gpr_mpscq_node *)gpr_atm_acq_load(&tail->next);
@@ -76,5 +78,6 @@ gpr_mpscq_node *gpr_mpscq_pop(gpr_mpscq *q) {
     q->tail = next;
     q->tail = next;
     return tail;
     return tail;
   }
   }
+  // indicates a retry is in order: we're still adding
   return NULL;
   return NULL;
 }
 }

+ 2 - 2
src/core/lib/support/mpscq.h

@@ -41,8 +41,8 @@
 // implementation from Dmitry Vyukov here:
 // implementation from Dmitry Vyukov here:
 // http://www.1024cores.net/home/lock-free-algorithms/queues/intrusive-mpsc-node-based-queue
 // http://www.1024cores.net/home/lock-free-algorithms/queues/intrusive-mpsc-node-based-queue
 
 
-// List node (include this in a data structure and dangle the rest of the
-// interesting bits off the end)
+// List node (include this in a data structure at the top, and add application
+// fields after it - to simulate inheritance)
 typedef struct gpr_mpscq_node { gpr_atm next; } gpr_mpscq_node;
 typedef struct gpr_mpscq_node { gpr_atm next; } gpr_mpscq_node;
 
 
 // Actual queue type
 // Actual queue type

+ 8 - 3
src/core/lib/surface/server.c

@@ -149,6 +149,7 @@ struct call_data {
 
 
   grpc_metadata_batch *recv_initial_metadata;
   grpc_metadata_batch *recv_initial_metadata;
   bool recv_idempotent_request;
   bool recv_idempotent_request;
+  bool recv_cacheable_request;
   grpc_metadata_array initial_metadata;
   grpc_metadata_array initial_metadata;
 
 
   request_matcher *request_matcher;
   request_matcher *request_matcher;
@@ -501,9 +502,12 @@ static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
             &rc->data.batch.details->method_capacity, calld->path);
             &rc->data.batch.details->method_capacity, calld->path);
       rc->data.batch.details->deadline = calld->deadline;
       rc->data.batch.details->deadline = calld->deadline;
       rc->data.batch.details->flags =
       rc->data.batch.details->flags =
-          0 | (calld->recv_idempotent_request
-                   ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
-                   : 0);
+          (calld->recv_idempotent_request
+               ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
+               : 0) |
+          (calld->recv_cacheable_request
+               ? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST
+               : 0);
       break;
       break;
     case REGISTERED_CALL:
     case REGISTERED_CALL:
       *rc->data.registered.deadline = calld->deadline;
       *rc->data.registered.deadline = calld->deadline;
@@ -783,6 +787,7 @@ static void server_mutate_op(grpc_call_element *elem,
     calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready;
     calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready;
     op->recv_initial_metadata_ready = &calld->server_on_recv_initial_metadata;
     op->recv_initial_metadata_ready = &calld->server_on_recv_initial_metadata;
     op->recv_idempotent_request = &calld->recv_idempotent_request;
     op->recv_idempotent_request = &calld->recv_idempotent_request;
+    op->recv_cacheable_request = &calld->recv_cacheable_request;
   }
   }
 }
 }
 
 

+ 2 - 0
src/core/lib/surface/version.c

@@ -37,3 +37,5 @@
 #include <grpc/grpc.h>
 #include <grpc/grpc.h>
 
 
 const char *grpc_version_string(void) { return "1.1.0-dev"; }
 const char *grpc_version_string(void) { return "1.1.0-dev"; }
+
+const char *grpc_g_stands_for(void) { return "good"; }

+ 8 - 7
src/core/lib/transport/static_metadata.c

@@ -51,15 +51,15 @@ uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
 
 const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2] =
 const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2] =
-    {11, 33, 10, 33, 12, 33, 12, 49, 13, 33, 14, 33, 15, 33, 16, 33, 17, 33,
+    {11, 33, 10, 33, 12, 33, 12, 50, 13, 33, 14, 33, 15, 33, 16, 33, 17, 33,
      19, 33, 20, 33, 21, 33, 22, 33, 23, 33, 24, 33, 25, 33, 26, 33, 27, 33,
      19, 33, 20, 33, 21, 33, 22, 33, 23, 33, 24, 33, 25, 33, 26, 33, 27, 33,
      28, 18, 28, 33, 29, 33, 30, 33, 34, 33, 35, 33, 36, 33, 37, 33, 40, 31,
      28, 18, 28, 33, 29, 33, 30, 33, 34, 33, 35, 33, 36, 33, 37, 33, 40, 31,
-     40, 32, 40, 48, 40, 53, 40, 54, 40, 55, 40, 56, 42, 31, 42, 48, 42, 53,
-     45, 0,  45, 1,  45, 2,  50, 33, 57, 33, 58, 33, 59, 33, 60, 33, 61, 33,
-     62, 33, 63, 33, 64, 33, 65, 33, 66, 33, 67, 33, 68, 38, 68, 70, 68, 73,
-     69, 81, 69, 82, 71, 33, 72, 33, 74, 33, 75, 33, 76, 33, 77, 33, 78, 39,
-     78, 51, 78, 52, 79, 33, 80, 33, 83, 3,  83, 4,  83, 5,  83, 6,  83, 7,
-     83, 8,  83, 9,  84, 33, 85, 86, 87, 33, 88, 33, 89, 33, 90, 33, 91, 33};
+     40, 32, 40, 49, 40, 54, 40, 55, 40, 56, 40, 57, 42, 31, 42, 49, 42, 54,
+     46, 0,  46, 1,  46, 2,  51, 33, 58, 33, 59, 33, 60, 33, 61, 33, 62, 33,
+     63, 33, 64, 33, 65, 33, 66, 33, 67, 33, 68, 33, 69, 38, 69, 71, 69, 74,
+     70, 82, 70, 83, 72, 33, 73, 33, 75, 33, 76, 33, 77, 33, 78, 33, 79, 39,
+     79, 52, 79, 53, 80, 33, 81, 33, 84, 3,  84, 4,  84, 5,  84, 6,  84, 7,
+     84, 8,  84, 9,  85, 33, 86, 87, 88, 33, 89, 33, 90, 33, 91, 33, 92, 33};
 
 
 const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = {
 const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = {
     "0",
     "0",
@@ -107,6 +107,7 @@ const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = {
     "grpc-encoding",
     "grpc-encoding",
     "grpc-internal-encoding-request",
     "grpc-internal-encoding-request",
     "grpc-message",
     "grpc-message",
+    "grpc-payload-bin",
     "grpc-status",
     "grpc-status",
     "grpc-timeout",
     "grpc-timeout",
     "grpc-tracing-bin",
     "grpc-tracing-bin",

+ 50 - 48
src/core/lib/transport/static_metadata.h

@@ -44,7 +44,7 @@
 
 
 #include "src/core/lib/transport/metadata.h"
 #include "src/core/lib/transport/metadata.h"
 
 
-#define GRPC_STATIC_MDSTR_COUNT 92
+#define GRPC_STATIC_MDSTR_COUNT 93
 extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
 extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
 /* "0" */
 /* "0" */
 #define GRPC_MDSTR_0 (&grpc_static_mdstr_table[0])
 #define GRPC_MDSTR_0 (&grpc_static_mdstr_table[0])
@@ -136,101 +136,103 @@ extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
 #define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (&grpc_static_mdstr_table[43])
 #define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (&grpc_static_mdstr_table[43])
 /* "grpc-message" */
 /* "grpc-message" */
 #define GRPC_MDSTR_GRPC_MESSAGE (&grpc_static_mdstr_table[44])
 #define GRPC_MDSTR_GRPC_MESSAGE (&grpc_static_mdstr_table[44])
+/* "grpc-payload-bin" */
+#define GRPC_MDSTR_GRPC_PAYLOAD_BIN (&grpc_static_mdstr_table[45])
 /* "grpc-status" */
 /* "grpc-status" */
-#define GRPC_MDSTR_GRPC_STATUS (&grpc_static_mdstr_table[45])
+#define GRPC_MDSTR_GRPC_STATUS (&grpc_static_mdstr_table[46])
 /* "grpc-timeout" */
 /* "grpc-timeout" */
-#define GRPC_MDSTR_GRPC_TIMEOUT (&grpc_static_mdstr_table[46])
+#define GRPC_MDSTR_GRPC_TIMEOUT (&grpc_static_mdstr_table[47])
 /* "grpc-tracing-bin" */
 /* "grpc-tracing-bin" */
-#define GRPC_MDSTR_GRPC_TRACING_BIN (&grpc_static_mdstr_table[47])
+#define GRPC_MDSTR_GRPC_TRACING_BIN (&grpc_static_mdstr_table[48])
 /* "gzip" */
 /* "gzip" */
-#define GRPC_MDSTR_GZIP (&grpc_static_mdstr_table[48])
+#define GRPC_MDSTR_GZIP (&grpc_static_mdstr_table[49])
 /* "gzip, deflate" */
 /* "gzip, deflate" */
-#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (&grpc_static_mdstr_table[49])
+#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (&grpc_static_mdstr_table[50])
 /* "host" */
 /* "host" */
-#define GRPC_MDSTR_HOST (&grpc_static_mdstr_table[50])
+#define GRPC_MDSTR_HOST (&grpc_static_mdstr_table[51])
 /* "http" */
 /* "http" */
-#define GRPC_MDSTR_HTTP (&grpc_static_mdstr_table[51])
+#define GRPC_MDSTR_HTTP (&grpc_static_mdstr_table[52])
 /* "https" */
 /* "https" */
-#define GRPC_MDSTR_HTTPS (&grpc_static_mdstr_table[52])
+#define GRPC_MDSTR_HTTPS (&grpc_static_mdstr_table[53])
 /* "identity" */
 /* "identity" */
-#define GRPC_MDSTR_IDENTITY (&grpc_static_mdstr_table[53])
+#define GRPC_MDSTR_IDENTITY (&grpc_static_mdstr_table[54])
 /* "identity,deflate" */
 /* "identity,deflate" */
-#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (&grpc_static_mdstr_table[54])
+#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (&grpc_static_mdstr_table[55])
 /* "identity,deflate,gzip" */
 /* "identity,deflate,gzip" */
 #define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
 #define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
-  (&grpc_static_mdstr_table[55])
+  (&grpc_static_mdstr_table[56])
 /* "identity,gzip" */
 /* "identity,gzip" */
-#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (&grpc_static_mdstr_table[56])
+#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (&grpc_static_mdstr_table[57])
 /* "if-match" */
 /* "if-match" */
-#define GRPC_MDSTR_IF_MATCH (&grpc_static_mdstr_table[57])
+#define GRPC_MDSTR_IF_MATCH (&grpc_static_mdstr_table[58])
 /* "if-modified-since" */
 /* "if-modified-since" */
-#define GRPC_MDSTR_IF_MODIFIED_SINCE (&grpc_static_mdstr_table[58])
+#define GRPC_MDSTR_IF_MODIFIED_SINCE (&grpc_static_mdstr_table[59])
 /* "if-none-match" */
 /* "if-none-match" */
-#define GRPC_MDSTR_IF_NONE_MATCH (&grpc_static_mdstr_table[59])
+#define GRPC_MDSTR_IF_NONE_MATCH (&grpc_static_mdstr_table[60])
 /* "if-range" */
 /* "if-range" */
-#define GRPC_MDSTR_IF_RANGE (&grpc_static_mdstr_table[60])
+#define GRPC_MDSTR_IF_RANGE (&grpc_static_mdstr_table[61])
 /* "if-unmodified-since" */
 /* "if-unmodified-since" */
-#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (&grpc_static_mdstr_table[61])
+#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (&grpc_static_mdstr_table[62])
 /* "last-modified" */
 /* "last-modified" */
-#define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[62])
+#define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[63])
 /* "link" */
 /* "link" */
-#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[63])
+#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[64])
 /* "load-reporting-initial" */
 /* "load-reporting-initial" */
-#define GRPC_MDSTR_LOAD_REPORTING_INITIAL (&grpc_static_mdstr_table[64])
+#define GRPC_MDSTR_LOAD_REPORTING_INITIAL (&grpc_static_mdstr_table[65])
 /* "load-reporting-trailing" */
 /* "load-reporting-trailing" */
-#define GRPC_MDSTR_LOAD_REPORTING_TRAILING (&grpc_static_mdstr_table[65])
+#define GRPC_MDSTR_LOAD_REPORTING_TRAILING (&grpc_static_mdstr_table[66])
 /* "location" */
 /* "location" */
-#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[66])
+#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[67])
 /* "max-forwards" */
 /* "max-forwards" */
-#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[67])
+#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[68])
 /* ":method" */
 /* ":method" */
-#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[68])
+#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[69])
 /* ":path" */
 /* ":path" */
-#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[69])
+#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[70])
 /* "POST" */
 /* "POST" */
-#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[70])
+#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[71])
 /* "proxy-authenticate" */
 /* "proxy-authenticate" */
-#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[71])
+#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[72])
 /* "proxy-authorization" */
 /* "proxy-authorization" */
-#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[72])
+#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[73])
 /* "PUT" */
 /* "PUT" */
-#define GRPC_MDSTR_PUT (&grpc_static_mdstr_table[73])
+#define GRPC_MDSTR_PUT (&grpc_static_mdstr_table[74])
 /* "range" */
 /* "range" */
-#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[74])
+#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[75])
 /* "referer" */
 /* "referer" */
-#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[75])
+#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[76])
 /* "refresh" */
 /* "refresh" */
-#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[76])
+#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[77])
 /* "retry-after" */
 /* "retry-after" */
-#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[77])
+#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[78])
 /* ":scheme" */
 /* ":scheme" */
-#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[78])
+#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[79])
 /* "server" */
 /* "server" */
-#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[79])
+#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[80])
 /* "set-cookie" */
 /* "set-cookie" */
-#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[80])
+#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[81])
 /* "/" */
 /* "/" */
-#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[81])
+#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[82])
 /* "/index.html" */
 /* "/index.html" */
-#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[82])
+#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[83])
 /* ":status" */
 /* ":status" */
-#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[83])
+#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[84])
 /* "strict-transport-security" */
 /* "strict-transport-security" */
-#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[84])
+#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[85])
 /* "te" */
 /* "te" */
-#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[85])
+#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[86])
 /* "trailers" */
 /* "trailers" */
-#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[86])
+#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[87])
 /* "transfer-encoding" */
 /* "transfer-encoding" */
-#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[87])
+#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[88])
 /* "user-agent" */
 /* "user-agent" */
-#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[88])
+#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[89])
 /* "vary" */
 /* "vary" */
-#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[89])
+#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[90])
 /* "via" */
 /* "via" */
-#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[90])
+#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[91])
 /* "www-authenticate" */
 /* "www-authenticate" */
-#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[91])
+#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[92])
 
 
 #define GRPC_STATIC_MDELEM_COUNT 81
 #define GRPC_STATIC_MDELEM_COUNT 81
 extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
 extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];

+ 1 - 0
src/core/lib/transport/transport.h

@@ -129,6 +129,7 @@ typedef struct grpc_transport_stream_op {
   /** Receive initial metadata from the stream, into provided metadata batch. */
   /** Receive initial metadata from the stream, into provided metadata batch. */
   grpc_metadata_batch *recv_initial_metadata;
   grpc_metadata_batch *recv_initial_metadata;
   bool *recv_idempotent_request;
   bool *recv_idempotent_request;
+  bool *recv_cacheable_request;
   /** Should be enqueued when initial metadata is ready to be processed. */
   /** Should be enqueued when initial metadata is ready to be processed. */
   grpc_closure *recv_initial_metadata_ready;
   grpc_closure *recv_initial_metadata_ready;
 
 

+ 5 - 2
src/cpp/common/channel_filter.h

@@ -35,7 +35,6 @@
 #define GRPCXX_CHANNEL_FILTER_H
 #define GRPCXX_CHANNEL_FILTER_H
 
 
 #include <grpc++/impl/codegen/config.h>
 #include <grpc++/impl/codegen/config.h>
-#include <grpc/census.h>
 #include <grpc/grpc.h>
 #include <grpc/grpc.h>
 #include <grpc/impl/codegen/alloc.h>
 #include <grpc/impl/codegen/alloc.h>
 
 
@@ -43,7 +42,6 @@
 #include <vector>
 #include <vector>
 
 
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/surface/channel_init.h"
 #include "src/core/lib/surface/channel_init.h"
 #include "src/core/lib/transport/metadata_batch.h"
 #include "src/core/lib/transport/metadata_batch.h"
 
 
@@ -56,6 +54,11 @@
 ///       "name-of-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr);
 ///       "name-of-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr);
 /// \endcode
 /// \endcode
 
 
+/// Forward declaration to avoid including the file
+/// "src/core/lib/security/context/security_context.h"
+struct grpc_client_security_context;
+struct grpc_server_security_context;
+
 namespace grpc {
 namespace grpc {
 
 
 /// A C++ wrapper for the \c grpc_metadata_batch struct.
 /// A C++ wrapper for the \c grpc_metadata_batch struct.

+ 6 - 9
src/cpp/server/server_builder.cc

@@ -35,10 +35,9 @@
 
 
 #include <grpc++/impl/service_type.h>
 #include <grpc++/impl/service_type.h>
 #include <grpc++/server.h>
 #include <grpc++/server.h>
-#include <grpc/support/cpu.h>
 #include <grpc/support/log.h>
 #include <grpc/support/log.h>
+#include <grpc/support/useful.h>
 
 
-#include "include/grpc/support/useful.h"
 #include "src/cpp/server/thread_pool_interface.h"
 #include "src/cpp/server/thread_pool_interface.h"
 
 
 namespace grpc {
 namespace grpc {
@@ -154,14 +153,12 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
     (*option)->UpdateArguments(&args);
     (*option)->UpdateArguments(&args);
     (*option)->UpdatePlugins(&plugins_);
     (*option)->UpdatePlugins(&plugins_);
   }
   }
-  if (!thread_pool) {
-    for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) {
-      if ((*plugin)->has_sync_methods()) {
-        thread_pool.reset(CreateDefaultThreadPool());
-        has_sync_methods = true;
-        break;
-      }
+  for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) {
+    if (!thread_pool && (*plugin)->has_sync_methods()) {
+      thread_pool.reset(CreateDefaultThreadPool());
+      has_sync_methods = true;
     }
     }
+    (*plugin)->UpdateChannelArguments(&args);
   }
   }
   if (max_message_size_ > 0) {
   if (max_message_size_ > 0) {
     args.SetInt(GRPC_ARG_MAX_MESSAGE_LENGTH, max_message_size_);
     args.SetInt(GRPC_ARG_MAX_MESSAGE_LENGTH, max_message_size_);

+ 2 - 2
src/cpp/util/byte_buffer.cc

@@ -104,8 +104,8 @@ ByteBuffer& ByteBuffer::operator=(const ByteBuffer& buf) {
 
 
 void ByteBuffer::Swap(ByteBuffer* other) {
 void ByteBuffer::Swap(ByteBuffer* other) {
   grpc_byte_buffer* tmp = other->buffer_;
   grpc_byte_buffer* tmp = other->buffer_;
-  other->buffer_ = this->buffer_;
-  this->buffer_ = tmp;
+  other->buffer_ = buffer_;
+  buffer_ = tmp;
 }
 }
 
 
 }  // namespace grpc
 }  // namespace grpc

+ 3 - 4
src/objective-c/!ProtoCompiler-gRPCPlugin.podspec

@@ -36,8 +36,8 @@ Pod::Spec.new do |s|
   # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
   # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
   # before them.
   # before them.
   s.name     = '!ProtoCompiler-gRPCPlugin'
   s.name     = '!ProtoCompiler-gRPCPlugin'
-  v = '1.0.0-pre1'
-  s.version  = "#{v}.2" # .2 to depend on protoc 3.0.0
+  v = '1.0.0'
+  s.version  = v
   s.summary  = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
   s.summary  = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
   s.description = <<-DESC
   s.description = <<-DESC
     This podspec only downloads the gRPC protoc plugin so that local pods generating protos can use
     This podspec only downloads the gRPC protoc plugin so that local pods generating protos can use
@@ -82,10 +82,9 @@ Pod::Spec.new do |s|
   s.authors  = { 'The gRPC contributors' => 'grpc-packages@google.com' }
   s.authors  = { 'The gRPC contributors' => 'grpc-packages@google.com' }
 
 
   repo = 'grpc/grpc'
   repo = 'grpc/grpc'
-  release = "objective-c-v#{v}"
   file = "grpc_objective_c_plugin-#{v}-macos-x86_64.zip"
   file = "grpc_objective_c_plugin-#{v}-macos-x86_64.zip"
   s.source = {
   s.source = {
-    :http => "https://github.com/#{repo}/releases/download/#{release}/#{file}",
+    :http => "https://github.com/#{repo}/releases/download/v#{v}/#{file}",
     # TODO(jcanizales): Add sha1 or sha256
     # TODO(jcanizales): Add sha1 or sha256
     # :sha1 => '??',
     # :sha1 => '??',
   }
   }

+ 262 - 252
src/objective-c/BoringSSL.podspec

@@ -31,7 +31,7 @@
 
 
 Pod::Spec.new do |s|
 Pod::Spec.new do |s|
   s.name     = 'BoringSSL'
   s.name     = 'BoringSSL'
-  version = '5.0'
+  version = '6.0'
   s.version  = version
   s.version  = version
   s.summary  = 'BoringSSL is a fork of OpenSSL that is designed to meet Google’s needs.'
   s.summary  = 'BoringSSL is a fork of OpenSSL that is designed to meet Google’s needs.'
   # Adapted from the homepage:
   # Adapted from the homepage:
@@ -70,7 +70,7 @@ Pod::Spec.new do |s|
   s.source = {
   s.source = {
     :git => 'https://boringssl.googlesource.com/boringssl',
     :git => 'https://boringssl.googlesource.com/boringssl',
     :tag => "version_for_cocoapods_#{version}",
     :tag => "version_for_cocoapods_#{version}",
-    # :commit => '8d343b44bbab829d1a28fdef650ca95f7db4412e',
+    # :commit => '4ac2dc4c0d48ca45da4f66c40e60d6b425fa94a3',
   }
   }
 
 
   name = 'openssl'
   name = 'openssl'
@@ -388,42 +388,42 @@ Pod::Spec.new do |s|
           0x28340c19,
           0x28340c19,
           0x283480ac,
           0x283480ac,
           0x283500ea,
           0x283500ea,
-          0x2c3227cb,
-          0x2c32a7d9,
-          0x2c3327eb,
-          0x2c33a7fd,
-          0x2c342811,
-          0x2c34a823,
-          0x2c35283e,
-          0x2c35a850,
-          0x2c362863,
+          0x2c322843,
+          0x2c32a851,
+          0x2c332863,
+          0x2c33a875,
+          0x2c342889,
+          0x2c34a89b,
+          0x2c3528b6,
+          0x2c35a8c8,
+          0x2c3628db,
           0x2c36832d,
           0x2c36832d,
-          0x2c372870,
-          0x2c37a882,
-          0x2c382895,
-          0x2c38a8ac,
-          0x2c3928ba,
-          0x2c39a8ca,
-          0x2c3a28dc,
-          0x2c3aa8f0,
-          0x2c3b2901,
-          0x2c3ba920,
-          0x2c3c2934,
-          0x2c3ca94a,
-          0x2c3d2963,
-          0x2c3da980,
-          0x2c3e2991,
-          0x2c3ea99f,
-          0x2c3f29b7,
-          0x2c3fa9cf,
-          0x2c4029dc,
+          0x2c3728e8,
+          0x2c37a8fa,
+          0x2c38290d,
+          0x2c38a924,
+          0x2c392932,
+          0x2c39a942,
+          0x2c3a2954,
+          0x2c3aa968,
+          0x2c3b2979,
+          0x2c3ba998,
+          0x2c3c29ac,
+          0x2c3ca9c2,
+          0x2c3d29db,
+          0x2c3da9f8,
+          0x2c3e2a09,
+          0x2c3eaa17,
+          0x2c3f2a2f,
+          0x2c3faa47,
+          0x2c402a54,
           0x2c4090e7,
           0x2c4090e7,
-          0x2c4129ed,
-          0x2c41aa00,
+          0x2c412a65,
+          0x2c41aa78,
           0x2c4210c0,
           0x2c4210c0,
-          0x2c42aa11,
+          0x2c42aa89,
           0x2c430720,
           0x2c430720,
-          0x2c43a912,
+          0x2c43a98a,
           0x30320000,
           0x30320000,
           0x30328015,
           0x30328015,
           0x3033001f,
           0x3033001f,
@@ -576,169 +576,174 @@ Pod::Spec.new do |s|
           0x403b9861,
           0x403b9861,
           0x403c0064,
           0x403c0064,
           0x403c8083,
           0x403c8083,
-          0x403d186d,
-          0x403d9883,
-          0x403e1892,
-          0x403e98a5,
-          0x403f18bf,
-          0x403f98cd,
-          0x404018e2,
-          0x404098f6,
-          0x40411913,
-          0x4041992e,
-          0x40421947,
-          0x4042995a,
-          0x4043196e,
-          0x40439986,
-          0x4044199d,
+          0x403d1890,
+          0x403d98a6,
+          0x403e18b5,
+          0x403e98c8,
+          0x403f18e2,
+          0x403f98f0,
+          0x40401905,
+          0x40409919,
+          0x40411936,
+          0x40419951,
+          0x4042196a,
+          0x4042997d,
+          0x40431991,
+          0x404399a9,
+          0x404419c0,
           0x404480ac,
           0x404480ac,
-          0x404519b2,
-          0x404599c4,
-          0x404619e8,
-          0x40469a08,
-          0x40471a16,
-          0x40479a3d,
-          0x40481a52,
-          0x40489a6b,
-          0x40491a82,
-          0x40499a9c,
-          0x404a1ab3,
-          0x404a9ad1,
-          0x404b1ae9,
-          0x404b9b00,
-          0x404c1b16,
-          0x404c9b28,
-          0x404d1b49,
-          0x404d9b6b,
-          0x404e1b7f,
-          0x404e9b8c,
-          0x404f1ba3,
-          0x404f9bb3,
-          0x40501bdd,
-          0x40509bf1,
-          0x40511c0c,
-          0x40519c1c,
-          0x40521c33,
-          0x40529c45,
-          0x40531c5d,
-          0x40539c70,
-          0x40541c85,
-          0x40549ca8,
-          0x40551cb6,
-          0x40559cd3,
-          0x40561ce0,
-          0x40569cf9,
-          0x40571d11,
-          0x40579d24,
-          0x40581d39,
-          0x40589d4b,
-          0x40591d7a,
-          0x40599d93,
-          0x405a1da7,
-          0x405a9db7,
-          0x405b1dcf,
-          0x405b9de0,
-          0x405c1df3,
-          0x405c9e04,
-          0x405d1e11,
-          0x405d9e28,
-          0x405e1e48,
+          0x404519d5,
+          0x404599e7,
+          0x40461a0b,
+          0x40469a2b,
+          0x40471a39,
+          0x40479a60,
+          0x40481a89,
+          0x40489aa2,
+          0x40491ab9,
+          0x40499ad3,
+          0x404a1aea,
+          0x404a9b08,
+          0x404b1b20,
+          0x404b9b37,
+          0x404c1b4d,
+          0x404c9b5f,
+          0x404d1b80,
+          0x404d9ba2,
+          0x404e1bb6,
+          0x404e9bc3,
+          0x404f1bf0,
+          0x404f9c19,
+          0x40501c43,
+          0x40509c57,
+          0x40511c72,
+          0x40519c82,
+          0x40521c99,
+          0x40529cbd,
+          0x40531cd5,
+          0x40539ce8,
+          0x40541cfd,
+          0x40549d20,
+          0x40551d2e,
+          0x40559d4b,
+          0x40561d58,
+          0x40569d71,
+          0x40571d89,
+          0x40579d9c,
+          0x40581db1,
+          0x40589dc3,
+          0x40591df2,
+          0x40599e0b,
+          0x405a1e1f,
+          0x405a9e2f,
+          0x405b1e47,
+          0x405b9e58,
+          0x405c1e6b,
+          0x405c9e7c,
+          0x405d1e89,
+          0x405d9ea0,
+          0x405e1ec0,
           0x405e8a95,
           0x405e8a95,
-          0x405f1e69,
-          0x405f9e76,
-          0x40601e84,
-          0x40609ea6,
-          0x40611ece,
-          0x40619ee3,
-          0x40621efa,
-          0x40629f0b,
-          0x40631f1c,
-          0x40639f31,
-          0x40641f48,
-          0x40649f59,
-          0x40651f74,
-          0x40659f8b,
-          0x40661fa3,
-          0x40669fcd,
-          0x40671ff8,
-          0x4067a019,
-          0x4068202c,
-          0x4068a04d,
-          0x4069207f,
-          0x4069a0ad,
-          0x406a20ce,
-          0x406aa0ee,
-          0x406b2276,
-          0x406ba299,
-          0x406c22af,
-          0x406ca4db,
-          0x406d250a,
-          0x406da532,
-          0x406e254b,
-          0x406ea563,
-          0x406f2582,
-          0x406fa597,
-          0x407025aa,
-          0x4070a5c7,
+          0x405f1ee1,
+          0x405f9eee,
+          0x40601efc,
+          0x40609f1e,
+          0x40611f46,
+          0x40619f5b,
+          0x40621f72,
+          0x40629f83,
+          0x40631f94,
+          0x40639fa9,
+          0x40641fc0,
+          0x40649fd1,
+          0x40651fec,
+          0x4065a003,
+          0x4066201b,
+          0x4066a045,
+          0x40672070,
+          0x4067a091,
+          0x406820a4,
+          0x4068a0c5,
+          0x406920f7,
+          0x4069a125,
+          0x406a2146,
+          0x406aa166,
+          0x406b22ee,
+          0x406ba311,
+          0x406c2327,
+          0x406ca553,
+          0x406d2582,
+          0x406da5aa,
+          0x406e25c3,
+          0x406ea5db,
+          0x406f25fa,
+          0x406fa60f,
+          0x40702622,
+          0x4070a63f,
           0x40710800,
           0x40710800,
-          0x4071a5d9,
-          0x407225ec,
-          0x4072a605,
-          0x4073261d,
+          0x4071a651,
+          0x40722664,
+          0x4072a67d,
+          0x40732695,
           0x4073936d,
           0x4073936d,
-          0x40742631,
-          0x4074a64b,
-          0x4075265c,
-          0x4075a670,
-          0x4076267e,
+          0x407426a9,
+          0x4074a6c3,
+          0x407526d4,
+          0x4075a6e8,
+          0x407626f6,
           0x407691aa,
           0x407691aa,
-          0x407726a3,
-          0x4077a6c5,
-          0x407826e0,
-          0x4078a719,
-          0x40792730,
-          0x4079a746,
-          0x407a2752,
-          0x407aa765,
-          0x407b277a,
-          0x407ba78c,
-          0x407c27a1,
-          0x407ca7aa,
-          0x407d2068,
-          0x407d9bc3,
-          0x407e26f5,
-          0x407e9d5b,
-          0x407f1a2a,
-          0x41f421a1,
-          0x41f92233,
-          0x41fe2126,
-          0x41fea302,
-          0x41ff23f3,
-          0x420321ba,
-          0x420821dc,
-          0x4208a218,
-          0x4209210a,
-          0x4209a252,
-          0x420a2161,
-          0x420aa141,
-          0x420b2181,
-          0x420ba1fa,
-          0x420c240f,
-          0x420ca2cf,
-          0x420d22e9,
-          0x420da320,
-          0x4212233a,
-          0x421723d6,
-          0x4217a37c,
-          0x421c239e,
-          0x421f2359,
-          0x42212426,
-          0x422623b9,
-          0x422b24bf,
-          0x422ba488,
-          0x422c24a7,
-          0x422ca462,
-          0x422d2441,
+          0x4077271b,
+          0x4077a73d,
+          0x40782758,
+          0x4078a791,
+          0x407927a8,
+          0x4079a7be,
+          0x407a27ca,
+          0x407aa7dd,
+          0x407b27f2,
+          0x407ba804,
+          0x407c2819,
+          0x407ca822,
+          0x407d20e0,
+          0x407d9c29,
+          0x407e276d,
+          0x407e9dd3,
+          0x407f1a4d,
+          0x407f986d,
+          0x40801c00,
+          0x40809a75,
+          0x40811cab,
+          0x40819bda,
+          0x41f42219,
+          0x41f922ab,
+          0x41fe219e,
+          0x41fea37a,
+          0x41ff246b,
+          0x42032232,
+          0x42082254,
+          0x4208a290,
+          0x42092182,
+          0x4209a2ca,
+          0x420a21d9,
+          0x420aa1b9,
+          0x420b21f9,
+          0x420ba272,
+          0x420c2487,
+          0x420ca347,
+          0x420d2361,
+          0x420da398,
+          0x421223b2,
+          0x4217244e,
+          0x4217a3f4,
+          0x421c2416,
+          0x421f23d1,
+          0x4221249e,
+          0x42262431,
+          0x422b2537,
+          0x422ba500,
+          0x422c251f,
+          0x422ca4da,
+          0x422d24b9,
           0x4432072b,
           0x4432072b,
           0x4432873a,
           0x4432873a,
           0x44330746,
           0x44330746,
@@ -781,69 +786,69 @@ Pod::Spec.new do |s|
           0x4c3d136d,
           0x4c3d136d,
           0x4c3d937c,
           0x4c3d937c,
           0x4c3e1389,
           0x4c3e1389,
-          0x50322a23,
-          0x5032aa32,
-          0x50332a3d,
-          0x5033aa4d,
-          0x50342a66,
-          0x5034aa80,
-          0x50352a8e,
-          0x5035aaa4,
-          0x50362ab6,
-          0x5036aacc,
-          0x50372ae5,
-          0x5037aaf8,
-          0x50382b10,
-          0x5038ab21,
-          0x50392b36,
-          0x5039ab4a,
-          0x503a2b6a,
-          0x503aab80,
-          0x503b2b98,
-          0x503babaa,
-          0x503c2bc6,
-          0x503cabdd,
-          0x503d2bf6,
-          0x503dac0c,
-          0x503e2c19,
-          0x503eac2f,
-          0x503f2c41,
+          0x50322a9b,
+          0x5032aaaa,
+          0x50332ab5,
+          0x5033aac5,
+          0x50342ade,
+          0x5034aaf8,
+          0x50352b06,
+          0x5035ab1c,
+          0x50362b2e,
+          0x5036ab44,
+          0x50372b5d,
+          0x5037ab70,
+          0x50382b88,
+          0x5038ab99,
+          0x50392bae,
+          0x5039abc2,
+          0x503a2be2,
+          0x503aabf8,
+          0x503b2c10,
+          0x503bac22,
+          0x503c2c3e,
+          0x503cac55,
+          0x503d2c6e,
+          0x503dac84,
+          0x503e2c91,
+          0x503eaca7,
+          0x503f2cb9,
           0x503f8382,
           0x503f8382,
-          0x50402c54,
-          0x5040ac64,
-          0x50412c7e,
-          0x5041ac8d,
-          0x50422ca7,
-          0x5042acc4,
-          0x50432cd4,
-          0x5043ace4,
-          0x50442cf3,
+          0x50402ccc,
+          0x5040acdc,
+          0x50412cf6,
+          0x5041ad05,
+          0x50422d1f,
+          0x5042ad3c,
+          0x50432d4c,
+          0x5043ad5c,
+          0x50442d6b,
           0x5044843f,
           0x5044843f,
-          0x50452d07,
-          0x5045ad25,
-          0x50462d38,
-          0x5046ad4e,
-          0x50472d60,
-          0x5047ad75,
-          0x50482d9b,
-          0x5048ada9,
-          0x50492dbc,
-          0x5049add1,
-          0x504a2de7,
-          0x504aadf7,
-          0x504b2e17,
-          0x504bae2a,
-          0x504c2e4d,
-          0x504cae7b,
-          0x504d2e8d,
-          0x504daeaa,
-          0x504e2ec5,
-          0x504eaee1,
-          0x504f2ef3,
-          0x504faf0a,
-          0x50502f19,
+          0x50452d7f,
+          0x5045ad9d,
+          0x50462db0,
+          0x5046adc6,
+          0x50472dd8,
+          0x5047aded,
+          0x50482e13,
+          0x5048ae21,
+          0x50492e34,
+          0x5049ae49,
+          0x504a2e5f,
+          0x504aae6f,
+          0x504b2e8f,
+          0x504baea2,
+          0x504c2ec5,
+          0x504caef3,
+          0x504d2f05,
+          0x504daf22,
+          0x504e2f3d,
+          0x504eaf59,
+          0x504f2f6b,
+          0x504faf82,
+          0x50502f91,
           0x505086ef,
           0x505086ef,
-          0x50512f2c,
+          0x50512fa4,
           0x58320ec9,
           0x58320ec9,
           0x68320e8b,
           0x68320e8b,
           0x68328c25,
           0x68328c25,
@@ -1204,6 +1209,7 @@ Pod::Spec.new do |s|
           "BAD_SSL_FILETYPE\\0"
           "BAD_SSL_FILETYPE\\0"
           "BAD_WRITE_RETRY\\0"
           "BAD_WRITE_RETRY\\0"
           "BIO_NOT_SET\\0"
           "BIO_NOT_SET\\0"
+          "BUFFERED_MESSAGES_ON_CIPHER_CHANGE\\0"
           "CA_DN_LENGTH_MISMATCH\\0"
           "CA_DN_LENGTH_MISMATCH\\0"
           "CA_DN_TOO_LONG\\0"
           "CA_DN_TOO_LONG\\0"
           "CCS_RECEIVED_EARLY\\0"
           "CCS_RECEIVED_EARLY\\0"
@@ -1226,6 +1232,7 @@ Pod::Spec.new do |s|
           "DIGEST_CHECK_FAILED\\0"
           "DIGEST_CHECK_FAILED\\0"
           "DOWNGRADE_DETECTED\\0"
           "DOWNGRADE_DETECTED\\0"
           "DTLS_MESSAGE_TOO_BIG\\0"
           "DTLS_MESSAGE_TOO_BIG\\0"
+          "DUPLICATE_EXTENSION\\0"
           "ECC_CERT_NOT_FOR_SIGNING\\0"
           "ECC_CERT_NOT_FOR_SIGNING\\0"
           "EMS_STATE_INCONSISTENT\\0"
           "EMS_STATE_INCONSISTENT\\0"
           "ENCRYPTED_LENGTH_TOO_LONG\\0"
           "ENCRYPTED_LENGTH_TOO_LONG\\0"
@@ -1240,7 +1247,9 @@ Pod::Spec.new do |s|
           "HTTPS_PROXY_REQUEST\\0"
           "HTTPS_PROXY_REQUEST\\0"
           "HTTP_REQUEST\\0"
           "HTTP_REQUEST\\0"
           "INAPPROPRIATE_FALLBACK\\0"
           "INAPPROPRIATE_FALLBACK\\0"
+          "INVALID_ALPN_PROTOCOL\\0"
           "INVALID_COMMAND\\0"
           "INVALID_COMMAND\\0"
+          "INVALID_COMPRESSION_LIST\\0"
           "INVALID_MESSAGE\\0"
           "INVALID_MESSAGE\\0"
           "INVALID_OUTER_RECORD_TYPE\\0"
           "INVALID_OUTER_RECORD_TYPE\\0"
           "INVALID_SSL_SESSION\\0"
           "INVALID_SSL_SESSION\\0"
@@ -1248,6 +1257,7 @@ Pod::Spec.new do |s|
           "LENGTH_MISMATCH\\0"
           "LENGTH_MISMATCH\\0"
           "LIBRARY_HAS_NO_CIPHERS\\0"
           "LIBRARY_HAS_NO_CIPHERS\\0"
           "MISSING_EXTENSION\\0"
           "MISSING_EXTENSION\\0"
+          "MISSING_KEY_SHARE\\0"
           "MISSING_RSA_CERTIFICATE\\0"
           "MISSING_RSA_CERTIFICATE\\0"
           "MISSING_TMP_DH_KEY\\0"
           "MISSING_TMP_DH_KEY\\0"
           "MISSING_TMP_ECDH_KEY\\0"
           "MISSING_TMP_ECDH_KEY\\0"

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

@@ -49,7 +49,7 @@ NS_ASSUME_NONNULL_BEGIN
 
 
 // TODO(jcanizales): Generate the version in a standalone header, from templates. Like
 // TODO(jcanizales): Generate the version in a standalone header, from templates. Like
 // templates/src/core/surface/version.c.template .
 // templates/src/core/surface/version.c.template .
-#define GRPC_OBJC_VERSION_STRING @"1.0.0-pre1"
+#define GRPC_OBJC_VERSION_STRING @"1.0.0"
 
 
 static NSMutableDictionary *kHostCache;
 static NSMutableDictionary *kHostCache;
 
 

+ 8 - 5
src/objective-c/README.md

@@ -48,7 +48,7 @@ Pod::Spec.new do |s|
   src = '.'
   src = '.'
 
 
   # We'll use protoc with the gRPC plugin.
   # We'll use protoc with the gRPC plugin.
-  s.dependency '!ProtoCompiler-gRPCPlugin', '~> 1.0.0-pre1.2'
+  s.dependency '!ProtoCompiler-gRPCPlugin', '~> 1.0'
 
 
   # Pods directory corresponding to this app's Podfile, relative to the location of this podspec.
   # Pods directory corresponding to this app's Podfile, relative to the location of this podspec.
   pods_root = '<path to your Podfile>/Pods'
   pods_root = '<path to your Podfile>/Pods'
@@ -82,10 +82,6 @@ Pod::Spec.new do |s|
     ms.requires_arc = false
     ms.requires_arc = false
     # The generated files depend on the protobuf runtime.
     # The generated files depend on the protobuf runtime.
     ms.dependency 'Protobuf'
     ms.dependency 'Protobuf'
-    # This is needed by all pods that depend on Protobuf:
-    ms.pod_target_xcconfig = {
-      'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
-    }
   end
   end
 
 
   # The --objcgrpc_out plugin generates a pair of .pbrpc.h/.pbrpc.m files for each .proto file with
   # The --objcgrpc_out plugin generates a pair of .pbrpc.h/.pbrpc.m files for each .proto file with
@@ -98,6 +94,13 @@ Pod::Spec.new do |s|
     ss.dependency 'gRPC-ProtoRPC'
     ss.dependency 'gRPC-ProtoRPC'
     ss.dependency "#{s.name}/Messages"
     ss.dependency "#{s.name}/Messages"
   end
   end
+
+  s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on Protobuf:
+    'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
+  }
 end
 end
 ```
 ```
 
 

+ 3 - 5
src/objective-c/RxLibrary/transformations/GRXMappingWriter.m

@@ -33,10 +33,6 @@
 
 
 #import "GRXMappingWriter.h"
 #import "GRXMappingWriter.h"
 
 
-static id (^kIdentity)(id value) = ^id(id value) {
-  return value;
-};
-
 @interface GRXForwardingWriter () <GRXWriteable>
 @interface GRXForwardingWriter () <GRXWriteable>
 @end
 @end
 
 
@@ -51,7 +47,9 @@ static id (^kIdentity)(id value) = ^id(id value) {
 // Designated initializer
 // Designated initializer
 - (instancetype)initWithWriter:(GRXWriter *)writer map:(id (^)(id value))map {
 - (instancetype)initWithWriter:(GRXWriter *)writer map:(id (^)(id value))map {
   if ((self = [super initWithWriter:writer])) {
   if ((self = [super initWithWriter:writer])) {
-    _map = map ?: kIdentity;
+    _map = map ?: ^id(id value) {
+      return value;
+    };
   }
   }
   return self;
   return self;
 }
 }

+ 8 - 5
src/objective-c/examples/RemoteTestClient/RemoteTest.podspec

@@ -11,7 +11,7 @@ Pod::Spec.new do |s|
   s.osx.deployment_target = '10.9'
   s.osx.deployment_target = '10.9'
 
 
   # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
   # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
-  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2"
+  s.dependency "!ProtoCompiler-gRPCPlugin"
 
 
   repo_root = '../../../..'
   repo_root = '../../../..'
   bin_dir = "#{repo_root}/bins/$CONFIG"
   bin_dir = "#{repo_root}/bins/$CONFIG"
@@ -35,10 +35,6 @@ Pod::Spec.new do |s|
     ms.header_mappings_dir = '.'
     ms.header_mappings_dir = '.'
     ms.requires_arc = false
     ms.requires_arc = false
     ms.dependency 'Protobuf'
     ms.dependency 'Protobuf'
-    # This is needed by all pods that depend on Protobuf:
-    ms.pod_target_xcconfig = {
-      'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
-    }
   end
   end
 
 
   s.subspec 'Services' do |ss|
   s.subspec 'Services' do |ss|
@@ -48,4 +44,11 @@ Pod::Spec.new do |s|
     ss.dependency 'gRPC-ProtoRPC'
     ss.dependency 'gRPC-ProtoRPC'
     ss.dependency "#{s.name}/Messages"
     ss.dependency "#{s.name}/Messages"
   end
   end
+
+  s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on Protobuf:
+    'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
+  }
 end
 end

+ 8 - 5
src/objective-c/tests/RemoteTestClient/RemoteTest.podspec

@@ -11,7 +11,7 @@ Pod::Spec.new do |s|
   s.osx.deployment_target = '10.9'
   s.osx.deployment_target = '10.9'
 
 
   # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
   # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
-  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2"
+  s.dependency "!ProtoCompiler-gRPCPlugin"
 
 
   repo_root = '../../../..'
   repo_root = '../../../..'
   bin_dir = "#{repo_root}/bins/$CONFIG"
   bin_dir = "#{repo_root}/bins/$CONFIG"
@@ -35,10 +35,6 @@ Pod::Spec.new do |s|
     ms.header_mappings_dir = "."
     ms.header_mappings_dir = "."
     ms.requires_arc = false
     ms.requires_arc = false
     ms.dependency "Protobuf"
     ms.dependency "Protobuf"
-    # This is needed by all pods that depend on Protobuf:
-    ms.pod_target_xcconfig = {
-      'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
-    }
   end
   end
 
 
   s.subspec "Services" do |ss|
   s.subspec "Services" do |ss|
@@ -48,4 +44,11 @@ Pod::Spec.new do |s|
     ss.dependency "gRPC-ProtoRPC"
     ss.dependency "gRPC-ProtoRPC"
     ss.dependency "#{s.name}/Messages"
     ss.dependency "#{s.name}/Messages"
   end
   end
+
+  s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on Protobuf:
+    'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
+  }
 end
 end

+ 1 - 1
src/php/composer.json

@@ -5,7 +5,7 @@
   "keywords": ["rpc"],
   "keywords": ["rpc"],
   "homepage": "http://grpc.io",
   "homepage": "http://grpc.io",
   "license": "BSD-3-Clause",
   "license": "BSD-3-Clause",
-  "version": "1.0.0",
+  "version": "1.1.0",
   "require": {
   "require": {
     "php": ">=5.5.0",
     "php": ">=5.5.0",
     "stanley-cheung/protobuf-php": "v0.6"
     "stanley-cheung/protobuf-php": "v0.6"

+ 3 - 0
src/php/ext/grpc/call.c

@@ -164,6 +164,9 @@ bool create_metadata_array(zval *array, grpc_metadata_array *metadata) {
     if (key_type1 != HASH_KEY_IS_STRING) {
     if (key_type1 != HASH_KEY_IS_STRING) {
       return false;
       return false;
     }
     }
+    if (!grpc_header_key_is_legal(key1, strlen(key1))) {
+      return false;
+    }
     inner_array_hash = Z_ARRVAL_P(inner_array);
     inner_array_hash = Z_ARRVAL_P(inner_array);
     PHP_GRPC_HASH_FOREACH_VAL_START(inner_array_hash, value)
     PHP_GRPC_HASH_FOREACH_VAL_START(inner_array_hash, value)
       if (Z_TYPE_P(value) != IS_STRING) {
       if (Z_TYPE_P(value) != IS_STRING) {

+ 6 - 14
src/php/ext/grpc/call_credentials.c

@@ -192,24 +192,16 @@ void plugin_get_metadata(void *ptr, grpc_auth_metadata_context context,
   /* call the user callback function */
   /* call the user callback function */
   zend_call_function(state->fci, state->fci_cache TSRMLS_CC);
   zend_call_function(state->fci, state->fci_cache TSRMLS_CC);
 
 
-  if (Z_TYPE_P(retval) != IS_ARRAY) {
-    zend_throw_exception(spl_ce_InvalidArgumentException,
-                         "plugin callback must return metadata array",
-                         1 TSRMLS_CC);
-    return;
-  }
-
+  grpc_status_code code = GRPC_STATUS_OK;
   grpc_metadata_array metadata;
   grpc_metadata_array metadata;
-  if (!create_metadata_array(retval, &metadata)) {
-    zend_throw_exception(spl_ce_InvalidArgumentException,
-                         "invalid metadata", 1 TSRMLS_CC);
+
+  if (Z_TYPE_P(retval) != IS_ARRAY) {
+    code = GRPC_STATUS_INVALID_ARGUMENT;
+  } else if (!create_metadata_array(retval, &metadata)) {
     grpc_metadata_array_destroy(&metadata);
     grpc_metadata_array_destroy(&metadata);
-    return;
+    code = GRPC_STATUS_INVALID_ARGUMENT;
   }
   }
 
 
-  /* TODO: handle error */
-  grpc_status_code code = GRPC_STATUS_OK;
-
   /* Pass control back to core */
   /* Pass control back to core */
   cb(user_data, metadata.metadata, metadata.count, code, NULL);
   cb(user_data, metadata.metadata, metadata.count, code, NULL);
 }
 }

+ 24 - 13
src/php/lib/Grpc/AbstractCall.php

@@ -34,8 +34,15 @@
 
 
 namespace Grpc;
 namespace Grpc;
 
 
+/**
+ * Class AbstractCall
+ * @package Grpc
+ */
 abstract class AbstractCall
 abstract class AbstractCall
 {
 {
+    /**
+     * @var Call
+     */
     protected $call;
     protected $call;
     protected $deserialize;
     protected $deserialize;
     protected $metadata;
     protected $metadata;
@@ -51,13 +58,15 @@ abstract class AbstractCall
      *                              the response
      *                              the response
      * @param array    $options     Call options (optional)
      * @param array    $options     Call options (optional)
      */
      */
-    public function __construct(Channel $channel,
-                                $method,
-                                $deserialize,
-                                $options = [])
-    {
-        if (isset($options['timeout']) &&
-            is_numeric($timeout = $options['timeout'])) {
+    public function __construct(
+        Channel $channel,
+        $method,
+        $deserialize,
+        $options = []
+    ) {
+        if (array_key_exists('timeout', $options) &&
+            is_numeric($timeout = $options['timeout'])
+        ) {
             $now = Timeval::now();
             $now = Timeval::now();
             $delta = new Timeval($timeout);
             $delta = new Timeval($timeout);
             $deadline = $now->add($delta);
             $deadline = $now->add($delta);
@@ -68,17 +77,19 @@ abstract class AbstractCall
         $this->deserialize = $deserialize;
         $this->deserialize = $deserialize;
         $this->metadata = null;
         $this->metadata = null;
         $this->trailing_metadata = null;
         $this->trailing_metadata = null;
-        if (isset($options['call_credentials_callback']) &&
+        if (array_key_exists('call_credentials_callback', $options) &&
             is_callable($call_credentials_callback =
             is_callable($call_credentials_callback =
-                        $options['call_credentials_callback'])) {
+                $options['call_credentials_callback'])
+        ) {
             $call_credentials = CallCredentials::createFromPlugin(
             $call_credentials = CallCredentials::createFromPlugin(
-                $call_credentials_callback);
+                $call_credentials_callback
+            );
             $this->call->setCredentials($call_credentials);
             $this->call->setCredentials($call_credentials);
         }
         }
     }
     }
 
 
     /**
     /**
-     * @return The metadata sent by the server.
+     * @return mixed The metadata sent by the server.
      */
      */
     public function getMetadata()
     public function getMetadata()
     {
     {
@@ -86,7 +97,7 @@ abstract class AbstractCall
     }
     }
 
 
     /**
     /**
-     * @return The trailing metadata sent by the server.
+     * @return mixed The trailing metadata sent by the server.
      */
      */
     public function getTrailingMetadata()
     public function getTrailingMetadata()
     {
     {
@@ -114,7 +125,7 @@ abstract class AbstractCall
      *
      *
      * @param string $value The binary value to deserialize
      * @param string $value The binary value to deserialize
      *
      *
-     * @return The deserialized value
+     * @return mixed The deserialized value
      */
      */
     protected function deserializeResponse($value)
     protected function deserializeResponse($value)
     {
     {

+ 5 - 5
src/php/lib/Grpc/BidiStreamingCall.php

@@ -45,7 +45,7 @@ class BidiStreamingCall extends AbstractCall
      *
      *
      * @param array $metadata Metadata to send with the call, if applicable
      * @param array $metadata Metadata to send with the call, if applicable
      */
      */
-    public function start($metadata = [])
+    public function start(array $metadata = [])
     {
     {
         $this->call->startBatch([
         $this->call->startBatch([
             OP_SEND_INITIAL_METADATA => $metadata,
             OP_SEND_INITIAL_METADATA => $metadata,
@@ -55,7 +55,7 @@ class BidiStreamingCall extends AbstractCall
     /**
     /**
      * Reads the next value from the server.
      * Reads the next value from the server.
      *
      *
-     * @return The next value from the server, or null if there is none
+     * @return mixed The next value from the server, or null if there is none
      */
      */
     public function read()
     public function read()
     {
     {
@@ -82,7 +82,7 @@ class BidiStreamingCall extends AbstractCall
     public function write($data, $options = [])
     public function write($data, $options = [])
     {
     {
         $message_array = ['message' => $data->serialize()];
         $message_array = ['message' => $data->serialize()];
-        if (isset($options['flags'])) {
+        if (array_key_exists('flags', $options)) {
             $message_array['flags'] = $options['flags'];
             $message_array['flags'] = $options['flags'];
         }
         }
         $this->call->startBatch([
         $this->call->startBatch([
@@ -103,8 +103,8 @@ class BidiStreamingCall extends AbstractCall
     /**
     /**
      * Wait for the server to send the status, and return it.
      * Wait for the server to send the status, and return it.
      *
      *
-     * @return object The status object, with integer $code, string $details,
-     *                and array $metadata members
+     * @return \stdClass The status object, with integer $code, string $details,
+     *                   and array $metadata members
      */
      */
     public function getStatus()
     public function getStatus()
     {
     {

+ 3 - 3
src/php/lib/Grpc/ClientStreamingCall.php

@@ -60,10 +60,10 @@ class ClientStreamingCall extends AbstractCall
      * @param array      $options an array of options, possible keys:
      * @param array      $options an array of options, possible keys:
      *                            'flags' => a number
      *                            'flags' => a number
      */
      */
-    public function write($data, $options = [])
+    public function write($data, array $options = [])
     {
     {
         $message_array = ['message' => $data->serialize()];
         $message_array = ['message' => $data->serialize()];
-        if (isset($options['flags'])) {
+        if (array_key_exists('flags', $options)) {
             $message_array['flags'] = $options['flags'];
             $message_array['flags'] = $options['flags'];
         }
         }
         $this->call->startBatch([
         $this->call->startBatch([
@@ -74,7 +74,7 @@ class ClientStreamingCall extends AbstractCall
     /**
     /**
      * Wait for the server to respond with data and a status.
      * Wait for the server to respond with data and a status.
      *
      *
-     * @return [response data, status]
+     * @return array [response data, status]
      */
      */
     public function wait()
     public function wait()
     {
     {

+ 6 - 6
src/php/lib/Grpc/ServerStreamingCall.php

@@ -36,14 +36,14 @@ namespace Grpc;
 
 
 /**
 /**
  * Represents an active call that sends a single message and then gets a stream
  * Represents an active call that sends a single message and then gets a stream
- * of reponses.
+ * of responses.
  */
  */
 class ServerStreamingCall extends AbstractCall
 class ServerStreamingCall extends AbstractCall
 {
 {
     /**
     /**
      * Start the call.
      * Start the call.
      *
      *
-     * @param $data The data to send
+     * @param mixed $data     The data to send
      * @param array $metadata Metadata to send with the call, if applicable
      * @param array $metadata Metadata to send with the call, if applicable
      * @param array $options  an array of options, possible keys:
      * @param array $options  an array of options, possible keys:
      *                        'flags' => a number
      *                        'flags' => a number
@@ -51,7 +51,7 @@ class ServerStreamingCall extends AbstractCall
     public function start($data, $metadata = [], $options = [])
     public function start($data, $metadata = [], $options = [])
     {
     {
         $message_array = ['message' => $data->serialize()];
         $message_array = ['message' => $data->serialize()];
-        if (isset($options['flags'])) {
+        if (array_key_exists('flags', $options)) {
             $message_array['flags'] = $options['flags'];
             $message_array['flags'] = $options['flags'];
         }
         }
         $event = $this->call->startBatch([
         $event = $this->call->startBatch([
@@ -64,7 +64,7 @@ class ServerStreamingCall extends AbstractCall
     }
     }
 
 
     /**
     /**
-     * @return An iterator of response values
+     * @return mixed An iterator of response values
      */
      */
     public function responses()
     public function responses()
     {
     {
@@ -82,8 +82,8 @@ class ServerStreamingCall extends AbstractCall
     /**
     /**
      * Wait for the server to send the status, and return it.
      * Wait for the server to send the status, and return it.
      *
      *
-     * @return object The status object, with integer $code, string $details,
-     *                and array $metadata members
+     * @return \stdClass The status object, with integer $code, string $details,
+     *                   and array $metadata members
      */
      */
     public function getStatus()
     public function getStatus()
     {
     {

+ 2 - 2
src/php/lib/Grpc/UnaryCall.php

@@ -43,7 +43,7 @@ class UnaryCall extends AbstractCall
     /**
     /**
      * Start the call.
      * Start the call.
      *
      *
-     * @param $data The data to send
+     * @param mixed $data     The data to send
      * @param array $metadata Metadata to send with the call, if applicable
      * @param array $metadata Metadata to send with the call, if applicable
      * @param array $options  an array of options, possible keys:
      * @param array $options  an array of options, possible keys:
      *                        'flags' => a number
      *                        'flags' => a number
@@ -66,7 +66,7 @@ class UnaryCall extends AbstractCall
     /**
     /**
      * Wait for the server to respond with data and a status.
      * Wait for the server to respond with data and a status.
      *
      *
-     * @return [response data, status]
+     * @return array [response data, status]
      */
      */
     public function wait()
     public function wait()
     {
     {

+ 23 - 14
src/php/tests/interop/interop_client.php

@@ -54,6 +54,15 @@ function hardAssert($value, $error_message)
     }
     }
 }
 }
 
 
+function hardAssertIfStatusOk($status)
+{
+    if ($status->code !== Grpc\STATUS_OK) {
+        echo "Call did not complete successfully. Status object:\n";
+        var_dump($status);
+        exit(1);
+    }
+}
+
 /**
 /**
  * Run the empty_unary test.
  * Run the empty_unary test.
  *
  *
@@ -62,7 +71,7 @@ function hardAssert($value, $error_message)
 function emptyUnary($stub)
 function emptyUnary($stub)
 {
 {
     list($result, $status) = $stub->EmptyCall(new grpc\testing\EmptyMessage())->wait();
     list($result, $status) = $stub->EmptyCall(new grpc\testing\EmptyMessage())->wait();
-    hardAssert($status->code === Grpc\STATUS_OK, 'Call did not complete successfully');
+    hardAssertIfStatusOk($status);
     hardAssert($result !== null, 'Call completed with a null response');
     hardAssert($result !== null, 'Call completed with a null response');
 }
 }
 
 
@@ -105,7 +114,7 @@ function performLargeUnary($stub, $fillUsername = false, $fillOauthScope = false
     }
     }
 
 
     list($result, $status) = $stub->UnaryCall($request, [], $options)->wait();
     list($result, $status) = $stub->UnaryCall($request, [], $options)->wait();
-    hardAssert($status->code === Grpc\STATUS_OK, 'Call did not complete successfully');
+    hardAssertIfStatusOk($status);
     hardAssert($result !== null, 'Call returned a null response');
     hardAssert($result !== null, 'Call returned a null response');
     $payload = $result->getPayload();
     $payload = $result->getPayload();
     hardAssert($payload->getType() === grpc\testing\PayloadType::COMPRESSABLE,
     hardAssert($payload->getType() === grpc\testing\PayloadType::COMPRESSABLE,
@@ -197,7 +206,12 @@ function updateAuthMetadataCallback($context)
     $methodName = $context->method_name;
     $methodName = $context->method_name;
     $auth_credentials = ApplicationDefaultCredentials::getCredentials();
     $auth_credentials = ApplicationDefaultCredentials::getCredentials();
 
 
-    return $auth_credentials->updateMetadata($metadata = [], $authUri);
+    $metadata = [];
+    $result = $auth_credentials->updateMetadata([], $authUri);
+    foreach ($result as $key => $value) {
+      $metadata[strtolower($key)] = $value;
+    }
+    return $metadata;
 }
 }
 
 
 /**
 /**
@@ -242,7 +256,7 @@ function clientStreaming($stub)
         $call->write($request);
         $call->write($request);
     }
     }
     list($result, $status) = $call->wait();
     list($result, $status) = $call->wait();
-    hardAssert($status->code === Grpc\STATUS_OK, 'Call did not complete successfully');
+    hardAssertIfStatusOk($status);
     hardAssert($result->getAggregatedPayloadSize() === 74922,
     hardAssert($result->getAggregatedPayloadSize() === 74922,
               'aggregated_payload_size was incorrect');
               'aggregated_payload_size was incorrect');
 }
 }
@@ -275,8 +289,7 @@ function serverStreaming($stub)
                 'Response '.$i.' had the wrong length');
                 'Response '.$i.' had the wrong length');
         $i += 1;
         $i += 1;
     }
     }
-    hardAssert($call->getStatus()->code === Grpc\STATUS_OK,
-             'Call did not complete successfully');
+    hardAssertIfStatusOk($call->getStatus());
 }
 }
 
 
 /**
 /**
@@ -312,8 +325,7 @@ function pingPong($stub)
     }
     }
     $call->writesDone();
     $call->writesDone();
     hardAssert($call->read() === null, 'Server returned too many responses');
     hardAssert($call->read() === null, 'Server returned too many responses');
-    hardAssert($call->getStatus()->code === Grpc\STATUS_OK,
-              'Call did not complete successfully');
+    hardAssertIfStatusOk($call->getStatus());
 }
 }
 
 
 /**
 /**
@@ -326,8 +338,7 @@ function emptyStream($stub)
     $call = $stub->FullDuplexCall();
     $call = $stub->FullDuplexCall();
     $call->writesDone();
     $call->writesDone();
     hardAssert($call->read() === null, 'Server returned too many responses');
     hardAssert($call->read() === null, 'Server returned too many responses');
-    hardAssert($call->getStatus()->code === Grpc\STATUS_OK,
-             'Call did not complete successfully');
+    hardAssertIfStatusOk($call->getStatus());
 }
 }
 
 
 /**
 /**
@@ -419,8 +430,7 @@ function customMetadata($stub)
                'Incorrect initial metadata value');
                'Incorrect initial metadata value');
 
 
     list($result, $status) = $call->wait();
     list($result, $status) = $call->wait();
-    hardAssert($status->code === Grpc\STATUS_OK,
-               'Call did not complete successfully');
+    hardAssertIfStatusOk($status);
 
 
     $trailing_metadata = $call->getTrailingMetadata();
     $trailing_metadata = $call->getTrailingMetadata();
     hardAssert(array_key_exists($ECHO_TRAILING_KEY, $trailing_metadata),
     hardAssert(array_key_exists($ECHO_TRAILING_KEY, $trailing_metadata),
@@ -435,8 +445,7 @@ function customMetadata($stub)
     $streaming_call->write($streaming_request);
     $streaming_call->write($streaming_request);
     $streaming_call->writesDone();
     $streaming_call->writesDone();
 
 
-    hardAssert($streaming_call->getStatus()->code === Grpc\STATUS_OK,
-               'Call did not complete successfully');
+    hardAssertIfStatusOk($streaming_call->getStatus());
 
 
     $streaming_trailing_metadata = $streaming_call->getTrailingMetadata();
     $streaming_trailing_metadata = $streaming_call->getTrailingMetadata();
     hardAssert(array_key_exists($ECHO_TRAILING_KEY,
     hardAssert(array_key_exists($ECHO_TRAILING_KEY,

+ 65 - 0
src/php/tests/unit_tests/CallCredentials2Test.php

@@ -132,4 +132,69 @@ class CallCredentials2Test extends PHPUnit_Framework_TestCase
         unset($call);
         unset($call);
         unset($server_call);
         unset($server_call);
     }
     }
+
+    public function invalidKeyCallbackFunc($context)
+    {
+        $this->assertTrue(is_string($context->service_url));
+        $this->assertTrue(is_string($context->method_name));
+
+        return ['K1' => ['v1']];
+    }
+
+    public function testCallbackWithInvalidKey()
+    {
+        $deadline = Grpc\Timeval::infFuture();
+        $status_text = 'xyz';
+        $call = new Grpc\Call($this->channel,
+                              '/abc/dummy_method',
+                              $deadline,
+                              $this->host_override);
+
+        $call_credentials = Grpc\CallCredentials::createFromPlugin(
+            array($this, 'invalidKeyCallbackFunc'));
+        $call->setCredentials($call_credentials);
+
+        $event = $call->startBatch([
+            Grpc\OP_SEND_INITIAL_METADATA => [],
+            Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
+            Grpc\OP_RECV_STATUS_ON_CLIENT => true,
+        ]);
+
+        $this->assertTrue($event->send_metadata);
+        $this->assertTrue($event->send_close);
+        $this->assertTrue($event->status->code == Grpc\STATUS_UNAUTHENTICATED);
+    }
+
+    public function invalidReturnCallbackFunc($context)
+    {
+        $this->assertTrue(is_string($context->service_url));
+        $this->assertTrue(is_string($context->method_name));
+
+        return "a string";
+    }
+
+    public function testCallbackWithInvalidReturnValue()
+    {
+        $deadline = Grpc\Timeval::infFuture();
+        $status_text = 'xyz';
+        $call = new Grpc\Call($this->channel,
+                              '/abc/dummy_method',
+                              $deadline,
+                              $this->host_override);
+
+        $call_credentials = Grpc\CallCredentials::createFromPlugin(
+            array($this, 'invalidReturnCallbackFunc'));
+        $call->setCredentials($call_credentials);
+
+        $event = $call->startBatch([
+            Grpc\OP_SEND_INITIAL_METADATA => [],
+            Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
+            Grpc\OP_RECV_STATUS_ON_CLIENT => true,
+        ]);
+
+        $this->assertTrue($event->send_metadata);
+        $this->assertTrue($event->send_close);
+        $this->assertTrue($event->status->code == Grpc\STATUS_UNAUTHENTICATED);
+    }
+
 }
 }

+ 0 - 135
src/php/tests/unit_tests/CallCredentials3Test.php

@@ -1,135 +0,0 @@
-<?php
-/*
- *
- * 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.
- *
- */
-
-class CallCredentials3Test extends PHPUnit_Framework_TestCase
-{
-    public function setUp()
-    {
-        $this->credentials = Grpc\ChannelCredentials::createSsl(
-            file_get_contents(dirname(__FILE__).'/../data/ca.pem'));
-        $server_credentials = Grpc\ServerCredentials::createSsl(
-            null,
-            file_get_contents(dirname(__FILE__).'/../data/server1.key'),
-            file_get_contents(dirname(__FILE__).'/../data/server1.pem'));
-        $this->server = new Grpc\Server();
-        $this->port = $this->server->addSecureHttp2Port('0.0.0.0:0',
-                                              $server_credentials);
-        $this->server->start();
-        $this->host_override = 'foo.test.google.fr';
-        $this->channel = new Grpc\Channel(
-            'localhost:'.$this->port,
-            [
-            'grpc.ssl_target_name_override' => $this->host_override,
-            'grpc.default_authority' => $this->host_override,
-            'credentials' => $this->credentials,
-            ]
-        );
-    }
-
-    public function tearDown()
-    {
-        unset($this->channel);
-        unset($this->server);
-    }
-
-    public function callbackFunc($context)
-    {
-        $this->assertTrue(is_string($context->service_url));
-        $this->assertTrue(is_string($context->method_name));
-
-        return ['k1' => ['v1'], 'k2' => ['v2']];
-    }
-
-    public function testCreateFromPlugin()
-    {
-        $deadline = Grpc\Timeval::infFuture();
-        $status_text = 'xyz';
-        $call = new Grpc\Call($this->channel,
-                              '/abc/dummy_method',
-                              $deadline,
-                              $this->host_override);
-
-        $call_credentials = Grpc\CallCredentials::createFromPlugin(
-            [$this, 'callbackFunc']);
-        $call->setCredentials($call_credentials);
-
-        $event = $call->startBatch([
-            Grpc\OP_SEND_INITIAL_METADATA => [],
-            Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
-        ]);
-
-        $this->assertTrue($event->send_metadata);
-        $this->assertTrue($event->send_close);
-
-        $event = $this->server->requestCall();
-
-        $this->assertTrue(is_array($event->metadata));
-        $metadata = $event->metadata;
-        $this->assertTrue(array_key_exists('k1', $metadata));
-        $this->assertTrue(array_key_exists('k2', $metadata));
-        $this->assertSame($metadata['k1'], ['v1']);
-        $this->assertSame($metadata['k2'], ['v2']);
-
-        $this->assertSame('/abc/dummy_method', $event->method);
-        $server_call = $event->call;
-
-        $event = $server_call->startBatch([
-            Grpc\OP_SEND_INITIAL_METADATA => [],
-            Grpc\OP_SEND_STATUS_FROM_SERVER => [
-                'metadata' => [],
-                'code' => Grpc\STATUS_OK,
-                'details' => $status_text,
-            ],
-            Grpc\OP_RECV_CLOSE_ON_SERVER => true,
-        ]);
-
-        $this->assertTrue($event->send_metadata);
-        $this->assertTrue($event->send_status);
-        $this->assertFalse($event->cancelled);
-
-        $event = $call->startBatch([
-            Grpc\OP_RECV_INITIAL_METADATA => true,
-            Grpc\OP_RECV_STATUS_ON_CLIENT => true,
-        ]);
-
-        $this->assertSame([], $event->metadata);
-        $status = $event->status;
-        $this->assertSame([], $status->metadata);
-        $this->assertSame(Grpc\STATUS_OK, $status->code);
-        $this->assertSame($status_text, $status->details);
-
-        unset($call);
-        unset($server_call);
-    }
-}

+ 23 - 1
src/php/tests/unit_tests/CallTest.php

@@ -113,7 +113,7 @@ class CallTest extends PHPUnit_Framework_TestCase
     /**
     /**
      * @expectedException InvalidArgumentException
      * @expectedException InvalidArgumentException
      */
      */
-    public function testInvalidMetadataKey()
+    public function testInvalidStartBatchKey()
     {
     {
         $batch = [
         $batch = [
             'invalid' => ['key1' => 'value1'],
             'invalid' => ['key1' => 'value1'],
@@ -121,6 +121,28 @@ class CallTest extends PHPUnit_Framework_TestCase
         $result = $this->call->startBatch($batch);
         $result = $this->call->startBatch($batch);
     }
     }
 
 
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testInvalidMetadataStrKey()
+    {
+        $batch = [
+            Grpc\OP_SEND_INITIAL_METADATA => ['Key' => ['value1', 'value2']],
+        ];
+        $result = $this->call->startBatch($batch);
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testInvalidMetadataIntKey()
+    {
+        $batch = [
+            Grpc\OP_SEND_INITIAL_METADATA => [1 => ['value1', 'value2']],
+        ];
+        $result = $this->call->startBatch($batch);
+    }
+
     /**
     /**
      * @expectedException InvalidArgumentException
      * @expectedException InvalidArgumentException
      */
      */

+ 0 - 0
src/proto/census/trace_context.options


+ 48 - 0
src/proto/census/trace_context.proto

@@ -0,0 +1,48 @@
+// 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.
+
+syntax = "proto3";
+
+package google.trace;
+
+// A TraceId uniquely represents a single Trace. It is a 128-bit nonce.
+message TraceId {
+  fixed64 hi = 1;
+  fixed64 lo = 2;
+}
+
+// Tracing information that is propagated with RPC's.
+message TraceContext {
+  // Trace identifer. Must be present.
+  TraceId trace_id = 1;
+  // ID of parent (client) span. Must be present.
+  fixed64 span_id = 2;
+  // true if this trace is sampled.
+  bool is_sampled = 3;
+}

+ 29 - 33
src/python/grpcio/_unixccompiler_patch.py → src/python/grpcio/_spawn_patch.py

@@ -27,51 +27,47 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
-"""Covers inadequacies in distutils."""
+"""Patches the spawn() command for windows compilers.
+
+Windows has an 8191 character command line limit, but some compilers
+support an @command_file directive where command_file is a file
+containing the full command line.
+"""
 
 
 from distutils import ccompiler
 from distutils import ccompiler
-from distutils import errors
-from distutils import unixccompiler
 import os
 import os
 import os.path
 import os.path
-import shlex
 import shutil
 import shutil
 import sys
 import sys
 import tempfile
 import tempfile
 
 
-def _unix_commandfile_spawn(self, command):
-  """Wrapper around distutils.util.spawn that attempts to use command files.
+MAX_COMMAND_LENGTH = 8191
 
 
-  Meant to replace the CCompiler method `spawn` on UnixCCompiler and its
-  derivatives (e.g. the MinGW32 compiler).
+_classic_spawn = ccompiler.CCompiler.spawn
 
 
-  Some commands like `gcc` (and friends like `clang`) support command files to
-  work around shell command length limits.
-  """
-  # Sometimes distutils embeds the executables as full strings including some
-  # hard-coded flags rather than as lists.
-  command = list(shlex.split(command[0])) + list(command[1:])
-  command_base = os.path.basename(command[0].strip())
-  if command_base == 'ccache':
-    command_base = command[:2]
-    command_args = command[2:]
-  elif command_base.startswith('ccache') or command_base in ['gcc', 'clang', 'clang++', 'g++']:
-    command_base = command[:1]
-    command_args = command[1:]
+def _commandfile_spawn(self, command):
+  command_length = sum([len(arg) for arg in command])
+  if os.name == 'nt' and command_length > MAX_COMMAND_LENGTH:
+    # Even if this command doesn't support the @command_file, it will
+    # fail as is so we try blindly
+    print('Command line length exceeded, using command file')
+    print(' '.join(command))
+    temporary_directory = tempfile.mkdtemp()
+    command_filename = os.path.abspath(
+    os.path.join(temporary_directory, 'command'))
+    with open(command_filename, 'w') as command_file:
+      escaped_args = ['"' + arg.replace('\\', '\\\\') + '"' for arg in command[1:]]
+      command_file.write(' '.join(escaped_args))
+    modified_command = command[:1] + ['@{}'.format(command_filename)]
+    try:
+      _classic_spawn(self, modified_command)
+    finally:
+      shutil.rmtree(temporary_directory)
   else:
   else:
-    return ccompiler.CCompiler.spawn(self, command)
-  temporary_directory = tempfile.mkdtemp()
-  command_filename = os.path.abspath(os.path.join(temporary_directory, 'command'))
-  with open(command_filename, 'w') as command_file:
-    escaped_args = [arg.replace('\\', '\\\\') for arg in command_args]
-    command_file.write(' '.join(escaped_args))
-  modified_command = command_base + ['@{}'.format(command_filename)]
-  result = ccompiler.CCompiler.spawn(self, modified_command)
-  shutil.rmtree(temporary_directory)
-  return result
+    _classic_spawn(self, command)
 
 
 
 
-def monkeypatch_unix_compiler():
+def monkeypatch_spawn():
   """Monkeypatching is dumb, but it's either that or we become maintainers of
   """Monkeypatching is dumb, but it's either that or we become maintainers of
      something much, much bigger."""
      something much, much bigger."""
-  unixccompiler.UnixCCompiler.spawn = _unix_commandfile_spawn
+  ccompiler.CCompiler.spawn = _commandfile_spawn

+ 2 - 2
src/python/grpcio/grpc_core_dependencies.py

@@ -222,7 +222,6 @@ CORE_SOURCE_FILES = [
   'src/core/ext/client_config/channel_connectivity.c',
   'src/core/ext/client_config/channel_connectivity.c',
   'src/core/ext/client_config/client_channel.c',
   'src/core/ext/client_config/client_channel.c',
   'src/core/ext/client_config/client_channel_factory.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/client_config_plugin.c',
   'src/core/ext/client_config/connector.c',
   'src/core/ext/client_config/connector.c',
   'src/core/ext/client_config/default_initial_connect_string.c',
   'src/core/ext/client_config/default_initial_connect_string.c',
@@ -234,8 +233,8 @@ CORE_SOURCE_FILES = [
   'src/core/ext/client_config/resolver.c',
   'src/core/ext/client_config/resolver.c',
   'src/core/ext/client_config/resolver_factory.c',
   'src/core/ext/client_config/resolver_factory.c',
   'src/core/ext/client_config/resolver_registry.c',
   'src/core/ext/client_config/resolver_registry.c',
+  'src/core/ext/client_config/resolver_result.c',
   'src/core/ext/client_config/subchannel.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/subchannel_index.c',
   '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',
@@ -257,6 +256,7 @@ CORE_SOURCE_FILES = [
   'src/core/ext/census/base_resources.c',
   'src/core/ext/census/base_resources.c',
   'src/core/ext/census/context.c',
   'src/core/ext/census/context.c',
   'src/core/ext/census/gen/census.pb.c',
   'src/core/ext/census/gen/census.pb.c',
+  'src/core/ext/census/gen/trace_context.pb.c',
   'src/core/ext/census/grpc_context.c',
   'src/core/ext/census/grpc_context.c',
   'src/core/ext/census/grpc_filter.c',
   'src/core/ext/census/grpc_filter.c',
   'src/core/ext/census/grpc_plugin.c',
   'src/core/ext/census/grpc_plugin.c',

+ 2 - 2
src/python/grpcio_health_checking/setup.py

@@ -46,12 +46,12 @@ PACKAGE_DIRECTORIES = {
 }
 }
 
 
 SETUP_REQUIRES = (
 SETUP_REQUIRES = (
-    'grpcio-tools>=0.15.0',
+    'grpcio-tools>={version}'.format(version=grpc_version.VERSION),
 )
 )
 
 
 INSTALL_REQUIRES = (
 INSTALL_REQUIRES = (
     'protobuf>=3.0.0',
     'protobuf>=3.0.0',
-    'grpcio>=0.15.0',
+    'grpcio>={version}'.format(version=grpc_version.VERSION),
 )
 )
 
 
 COMMAND_CLASS = {
 COMMAND_CLASS = {

+ 3 - 7
src/python/grpcio_tests/setup.py

@@ -60,17 +60,14 @@ INSTALL_REQUIRES = (
     'coverage>=4.0',
     'coverage>=4.0',
     'enum34>=1.0.4',
     'enum34>=1.0.4',
     'futures>=2.2.0',
     'futures>=2.2.0',
-    'grpcio>=0.14.0',
-    'grpcio-health-checking>=0.14.0',
+    'grpcio>={version}'.format(version=grpc_version.VERSION),
+    'grpcio-tools>={version}'.format(version=grpc_version.VERSION),
+    'grpcio-health-checking>={version}'.format(version=grpc_version.VERSION),
     'oauth2client>=1.4.7',
     'oauth2client>=1.4.7',
     'protobuf>=3.0.0',
     'protobuf>=3.0.0',
     'six>=1.10',
     'six>=1.10',
 )
 )
 
 
-SETUP_REQUIRES = (
-    'grpcio-tools>=0.14.0',
-)
-
 COMMAND_CLASS = {
 COMMAND_CLASS = {
     # Run `preprocess` *before* doing any packaging!
     # Run `preprocess` *before* doing any packaging!
     'preprocess': commands.GatherProto,
     'preprocess': commands.GatherProto,
@@ -115,7 +112,6 @@ setuptools.setup(
   package_dir=PACKAGE_DIRECTORIES,
   package_dir=PACKAGE_DIRECTORIES,
   package_data=PACKAGE_DATA,
   package_data=PACKAGE_DATA,
   install_requires=INSTALL_REQUIRES,
   install_requires=INSTALL_REQUIRES,
-  setup_requires=SETUP_REQUIRES,
   cmdclass=COMMAND_CLASS,
   cmdclass=COMMAND_CLASS,
   tests_require=TESTS_REQUIRE,
   tests_require=TESTS_REQUIRE,
   test_suite=TEST_SUITE,
   test_suite=TEST_SUITE,

+ 0 - 3
src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py

@@ -114,9 +114,6 @@ class TypeSmokeTest(unittest.TestCase):
         lambda ignored_a, ignored_b: None, b'')
         lambda ignored_a, ignored_b: None, b'')
     del plugin
     del plugin
 
 
-  @unittest.skipIf(
-    platform.python_implementation() == "PyPy",
-    'TODO(issue 7672): figure out why this fails on PyPy')
   def testCallCredentialsFromPluginUpDown(self):
   def testCallCredentialsFromPluginUpDown(self):
     plugin = cygrpc.CredentialsMetadataPlugin(_metadata_plugin_callback, b'')
     plugin = cygrpc.CredentialsMetadataPlugin(_metadata_plugin_callback, b'')
     call_credentials = cygrpc.call_credentials_metadata_plugin(plugin)
     call_credentials = cygrpc.call_credentials_metadata_plugin(plugin)

+ 2 - 0
src/ruby/ext/grpc/rb_grpc_imports.generated.c

@@ -80,6 +80,7 @@ grpc_register_plugin_type grpc_register_plugin_import;
 grpc_init_type grpc_init_import;
 grpc_init_type grpc_init_import;
 grpc_shutdown_type grpc_shutdown_import;
 grpc_shutdown_type grpc_shutdown_import;
 grpc_version_string_type grpc_version_string_import;
 grpc_version_string_type grpc_version_string_import;
+grpc_g_stands_for_type grpc_g_stands_for_import;
 grpc_completion_queue_create_type grpc_completion_queue_create_import;
 grpc_completion_queue_create_type grpc_completion_queue_create_import;
 grpc_completion_queue_next_type grpc_completion_queue_next_import;
 grpc_completion_queue_next_type grpc_completion_queue_next_import;
 grpc_completion_queue_pluck_type grpc_completion_queue_pluck_import;
 grpc_completion_queue_pluck_type grpc_completion_queue_pluck_import;
@@ -348,6 +349,7 @@ void grpc_rb_load_imports(HMODULE library) {
   grpc_init_import = (grpc_init_type) GetProcAddress(library, "grpc_init");
   grpc_init_import = (grpc_init_type) GetProcAddress(library, "grpc_init");
   grpc_shutdown_import = (grpc_shutdown_type) GetProcAddress(library, "grpc_shutdown");
   grpc_shutdown_import = (grpc_shutdown_type) GetProcAddress(library, "grpc_shutdown");
   grpc_version_string_import = (grpc_version_string_type) GetProcAddress(library, "grpc_version_string");
   grpc_version_string_import = (grpc_version_string_type) GetProcAddress(library, "grpc_version_string");
+  grpc_g_stands_for_import = (grpc_g_stands_for_type) GetProcAddress(library, "grpc_g_stands_for");
   grpc_completion_queue_create_import = (grpc_completion_queue_create_type) GetProcAddress(library, "grpc_completion_queue_create");
   grpc_completion_queue_create_import = (grpc_completion_queue_create_type) GetProcAddress(library, "grpc_completion_queue_create");
   grpc_completion_queue_next_import = (grpc_completion_queue_next_type) GetProcAddress(library, "grpc_completion_queue_next");
   grpc_completion_queue_next_import = (grpc_completion_queue_next_type) GetProcAddress(library, "grpc_completion_queue_next");
   grpc_completion_queue_pluck_import = (grpc_completion_queue_pluck_type) GetProcAddress(library, "grpc_completion_queue_pluck");
   grpc_completion_queue_pluck_import = (grpc_completion_queue_pluck_type) GetProcAddress(library, "grpc_completion_queue_pluck");

+ 3 - 0
src/ruby/ext/grpc/rb_grpc_imports.generated.h

@@ -191,6 +191,9 @@ extern grpc_shutdown_type grpc_shutdown_import;
 typedef const char *(*grpc_version_string_type)(void);
 typedef const char *(*grpc_version_string_type)(void);
 extern grpc_version_string_type grpc_version_string_import;
 extern grpc_version_string_type grpc_version_string_import;
 #define grpc_version_string grpc_version_string_import
 #define grpc_version_string grpc_version_string_import
+typedef const char *(*grpc_g_stands_for_type)(void);
+extern grpc_g_stands_for_type grpc_g_stands_for_import;
+#define grpc_g_stands_for grpc_g_stands_for_import
 typedef grpc_completion_queue *(*grpc_completion_queue_create_type)(void *reserved);
 typedef grpc_completion_queue *(*grpc_completion_queue_create_type)(void *reserved);
 extern grpc_completion_queue_create_type grpc_completion_queue_create_import;
 extern grpc_completion_queue_create_type grpc_completion_queue_create_import;
 #define grpc_completion_queue_create grpc_completion_queue_create_import
 #define grpc_completion_queue_create grpc_completion_queue_create_import

+ 65 - 0
summerofcode/2016/siddharth_shukla.md

@@ -0,0 +1,65 @@
+Project Overview
+================
+The project, titled 'GRPC Python compatibility support', involved 
+collaborating with the GRPC team to improve the library compatibility 
+for the GRPC Python library.
+
+Python is, originally, a specification for a programming language. This
+specification has been implemented differently in different
+implementations of the [language specification](https://docs.python.org/3/reference/). 
+
+A small, and by no means exhaustive, list of some major python implementations
+is:
+
+- [CPython](https://www.python.org/): The reference implementation
+- [Jython](http://www.jython.org/): Python implemented in Java
+- [Python for .NET](http://pythonnet.sourceforge.net/): CPython implementation that enables .NET library usage
+- [IronPython](http://ironpython.net/): Python implemented in .NET
+- [PyPy](http://pypy.org/): Python implemented completely in Python
+- [Stackless](https://bitbucket.org/stackless-dev/stackless/wiki/Home): Replaces the dependency for the C call stack with it's own stack
+
+The development in this project revolved around
+introducing changes to the codebase that enable support for latest 
+stable as well as development releases of the reference implementation 
+(CPython) of the Python programming language namely `Python 3.4`,
+`Python 3.5`,and `Python 3.6` as well as the stable releases of the 
+PyPy implementation. Special changes were required to enable PyPy 
+support because PyPy has a non-deterministic garbage collector that does
+not rely on reference counting unlike the CPython garbage collector.
+
+The changes to the codebase involved changes to the library code as well
+as changes to the tests and scripts in the test infrastructure which
+resulted in both the library as well as the testing infrastructure being
+Python 3.x and PyPy compatible.
+
+The list of merged commits, as of 22.08.2016 23:59 CEST,  is summarized 
+here for the perusal of those interested:
+
+- [Enable py35 and py36 testing](https://github.com/grpc/grpc/commit/c478214e475e103c5cdf477f0adc18bba2c03903)
+- [Make testing toolchain python 3.x compliant](https://github.com/grpc/grpc/commit/0589e533cd65a2ca9e0e610cc1b284d016986572)
+- [Add .idea folder to .gitignore](https://github.com/grpc/grpc/commit/365ef40947e22b5438a63f123679ae9a5474c47c)
+- [Fix the ThreadPoolExecutor: max_workers can't be 0](https://github.com/grpc/grpc/commit/de84d566b8fad6808e5263a25a17fa231cb5713c)
+- [Add PyPy to testing toolchain](https://github.com/grpc/grpc/commit/2135a1b557f8b992186d5317cb767ac4dbcdfe5c)
+- [Switch init/shutdown: lib-wide -> per-object](https://github.com/grpc/grpc/commit/9eedb4ffd74aed8d246a07f8007960b2bc167f55)
+- [Skip test run if running with pypy](https://github.com/grpc/grpc/commit/f0f58e68738abbc317f7f449c5104f7fbbff26bd)
+
+The list of unmerged pull requests is as follows:
+
+- [Add PyPy 5.3.1 to dockerfile and template](https://github.com/grpc/grpc/pull/7763)
+- [remove skipIf from TypeSmokeTest (issue 7672)](https://github.com/grpc/grpc/pull/7831)
+  
+The list of tasks that have pending unsubmitted pull requests is as follows:
+
+- Modify run_tests.py to enable testing of new languages without
+  affecting old branches.
+
+
+Project Details
+===============
+- Title: GRPC Python compatibility support
+- Student: [Siddharth Shukla](https://github.com/thunderboltsid)
+- Mentors: [Nathaniel Manista](https://github.com/nathanielmanistaatgoogle), [Masood Malekghassemi](https://github.com/soltanmm)
+- Duration: May 23 - August 23
+- Hat tip: [Ken Payson](https://github.com/kpayson64), [Jan Tattermusch](https://github.com/jtattermusch), [Nicolas Noble](https://github.com/nicolasnoble)
+
+

+ 2 - 0
templates/BUILD.template

@@ -38,6 +38,8 @@
   
   
   licenses(["notice"])  # 3-clause BSD
   licenses(["notice"])  # 3-clause BSD
   
   
+  exports_files(["LICENSE"])
+  
   package(default_visibility = ["//visibility:public"])
   package(default_visibility = ["//visibility:public"])
   
   
   <%!
   <%!

+ 1 - 1
templates/Makefile.template

@@ -380,7 +380,7 @@
   OPENSSL_ALPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.2 openssl
   OPENSSL_ALPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.2 openssl
   OPENSSL_NPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.1 openssl
   OPENSSL_NPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.1 openssl
   ZLIB_CHECK_CMD = $(PKG_CONFIG) --exists zlib
   ZLIB_CHECK_CMD = $(PKG_CONFIG) --exists zlib
-  PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0-alpha-3 protobuf
+  PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0 protobuf
   else # HAS_PKG_CONFIG
   else # HAS_PKG_CONFIG
 
 
   ifeq ($(SYSTEM),MINGW32)
   ifeq ($(SYSTEM),MINGW32)

+ 3 - 3
templates/gRPC-Core.podspec.template

@@ -62,7 +62,7 @@
   %>
   %>
   Pod::Spec.new do |s|
   Pod::Spec.new do |s|
     s.name     = 'gRPC-Core'
     s.name     = 'gRPC-Core'
-    version = '1.0.0-pre1'
+    version = '1.0.0'
     s.version  = version
     s.version  = version
     s.summary  = 'Core cross-platform gRPC library, written in C'
     s.summary  = 'Core cross-platform gRPC library, written in C'
     s.homepage = 'http://www.grpc.io'
     s.homepage = 'http://www.grpc.io'
@@ -71,7 +71,7 @@
 
 
     s.source = {
     s.source = {
       :git => 'https://github.com/grpc/grpc.git',
       :git => 'https://github.com/grpc/grpc.git',
-      :tag => "objective-c-v#{version}",
+      :tag => "v#{version}",
       # TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules.
       # TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules.
       :submodules => true,
       :submodules => true,
     }
     }
@@ -149,7 +149,7 @@
       ss.header_mappings_dir = '.'
       ss.header_mappings_dir = '.'
       ss.libraries = 'z'
       ss.libraries = 'z'
       ss.dependency "#{s.name}/Interface", version
       ss.dependency "#{s.name}/Interface", version
-      ss.dependency 'BoringSSL', '~> 5.0'
+      ss.dependency 'BoringSSL', '~> 6.0'
 
 
       # To save you from scrolling, this is the last part of the podspec.
       # To save you from scrolling, this is the last part of the podspec.
       ss.source_files = ${ruby_multiline_list(grpc_private_files(libs), 22)}
       ss.source_files = ${ruby_multiline_list(grpc_private_files(libs), 22)}

Some files were not shown because too many files changed in this diff