瀏覽代碼

Merge branch 'master' into svc_cfg2

Yash Tibrewal 6 年之前
父節點
當前提交
b476a30e69
共有 100 個文件被更改,包括 1325 次插入495 次删除
  1. 3 1
      BUILD
  2. 14 1
      BUILD.gn
  3. 34 1
      CMakeLists.txt
  4. 12 1
      CONTRIBUTING.md
  5. 41 11
      Makefile
  6. 13 15
      build.yaml
  7. 6 1
      config.m4
  8. 6 1
      config.w32
  9. 8 0
      gRPC-C++.podspec
  10. 16 14
      gRPC-Core.podspec
  11. 10 1
      grpc.gemspec
  12. 21 1
      grpc.gyp
  13. 2 1
      include/grpc/impl/codegen/grpc_types.h
  14. 10 1
      package.xml
  15. 13 19
      src/core/ext/filters/client_channel/client_channel.cc
  16. 3 3
      src/core/ext/filters/client_channel/health/health_check_client.cc
  17. 2 2
      src/core/ext/filters/client_channel/health/health_check_client.h
  18. 1 1
      src/core/ext/filters/client_channel/subchannel.cc
  19. 2 2
      src/core/ext/filters/client_channel/subchannel.h
  20. 4 3
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  21. 1 1
      src/core/ext/transport/chttp2/transport/incoming_metadata.cc
  22. 3 2
      src/core/ext/transport/chttp2/transport/incoming_metadata.h
  23. 1 1
      src/core/ext/transport/chttp2/transport/internal.h
  24. 7 6
      src/core/ext/transport/cronet/transport/cronet_transport.cc
  25. 9 9
      src/core/ext/transport/inproc/inproc_transport.cc
  26. 2 2
      src/core/lib/channel/channel_stack.h
  27. 0 152
      src/core/lib/gpr/arena.cc
  28. 13 7
      src/core/lib/gpr/arena.h
  29. 90 0
      src/core/lib/gprpp/arena.cc
  30. 99 0
      src/core/lib/gprpp/arena.h
  31. 1 1
      src/core/lib/iomgr/internal_errqueue.cc
  32. 1 1
      src/core/lib/iomgr/timer_generic.cc
  33. 6 7
      src/core/lib/security/context/security_context.cc
  34. 3 4
      src/core/lib/security/context/security_context.h
  35. 21 21
      src/core/lib/surface/call.cc
  36. 2 1
      src/core/lib/surface/call.h
  37. 0 1
      src/core/lib/surface/call_details.cc
  38. 7 7
      src/core/lib/surface/completion_queue.cc
  39. 3 2
      src/core/lib/surface/server.cc
  40. 2 1
      src/core/lib/transport/transport.cc
  41. 3 2
      src/core/lib/transport/transport.h
  42. 1 1
      src/core/lib/transport/transport_impl.h
  43. 0 1
      src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs
  44. 31 16
      src/objective-c/GRPCClient/GRPCCall.h
  45. 120 13
      src/objective-c/GRPCClient/GRPCCall.m
  46. 21 0
      src/objective-c/GRPCClient/GRPCCallOptions.h
  47. 16 0
      src/objective-c/GRPCClient/GRPCCallOptions.m
  48. 27 0
      src/objective-c/ProtoRPC/ProtoRPC.h
  49. 27 2
      src/objective-c/ProtoRPC/ProtoRPC.m
  50. 295 3
      src/objective-c/tests/APIv2Tests/APIv2Tests.m
  51. 96 11
      src/objective-c/tests/InteropTests.m
  52. 3 3
      src/objective-c/tests/UnitTests/UnitTests.m
  53. 6 1
      src/python/grpcio/grpc_core_dependencies.py
  54. 1 1
      src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
  55. 2 10
      templates/gRPC-Core.podspec.template
  56. 0 1
      templates/tools/dockerfile/debian_jessie_header.include
  57. 1 1
      test/core/bad_client/bad_client.cc
  58. 0 5
      test/core/bad_connection/close_fd_test.cc
  59. 11 9
      test/core/gpr/arena_test.cc
  60. 1 0
      test/core/util/BUILD
  61. 2 1
      test/core/util/fuzzer_corpus_test.cc
  62. 1 0
      test/cpp/codegen/BUILD
  63. 3 1
      test/cpp/codegen/golden_file_test.cc
  64. 2 0
      test/cpp/end2end/BUILD
  65. 2 1
      test/cpp/end2end/client_crash_test_server.cc
  66. 2 8
      test/cpp/end2end/server_crash_test_client.cc
  67. 12 10
      test/cpp/microbenchmarks/bm_arena.cc
  68. 5 5
      test/cpp/microbenchmarks/bm_call_create.cc
  69. 6 5
      test/cpp/microbenchmarks/bm_chttp2_hpack.cc
  70. 5 5
      test/cpp/microbenchmarks/bm_chttp2_transport.cc
  71. 1 1
      test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
  72. 1 1
      test/cpp/naming/resolver_component_test.cc
  73. 12 2
      test/cpp/qps/client_callback.cc
  74. 0 1
      tools/dockerfile/grpc_clang_format/Dockerfile
  75. 0 1
      tools/dockerfile/grpc_clang_tidy/Dockerfile
  76. 0 1
      tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile
  77. 0 1
      tools/dockerfile/interoptest/grpc_interop_java/Dockerfile
  78. 0 1
      tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile
  79. 0 1
      tools/dockerfile/interoptest/grpc_interop_node/Dockerfile
  80. 0 1
      tools/dockerfile/interoptest/grpc_interop_nodepurejs/Dockerfile
  81. 0 1
      tools/dockerfile/interoptest/grpc_interop_php/Dockerfile
  82. 0 1
      tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile
  83. 0 1
      tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile
  84. 0 1
      tools/dockerfile/test/cxx_jessie_x64/Dockerfile
  85. 0 1
      tools/dockerfile/test/fuzzer/Dockerfile
  86. 0 1
      tools/dockerfile/test/node_jessie_x64/Dockerfile
  87. 0 1
      tools/dockerfile/test/php7_jessie_x64/Dockerfile
  88. 0 1
      tools/dockerfile/test/php_jessie_x64/Dockerfile
  89. 0 1
      tools/dockerfile/test/python_jessie_x64/Dockerfile
  90. 0 1
      tools/dockerfile/test/ruby_jessie_x64/Dockerfile
  91. 4 0
      tools/doxygen/Doxyfile.c++.internal
  92. 10 1
      tools/doxygen/Doxyfile.core.internal
  93. 2 0
      tools/internal_ci/linux/grpc_publish_packages.cfg
  94. 13 0
      tools/internal_ci/linux/grpc_publish_packages.sh
  95. 5 2
      tools/interop_matrix/client_matrix.py
  96. 1 1
      tools/interop_matrix/testcases/csharp__master
  97. 23 0
      tools/interop_matrix/testcases/csharp__v1.18.0
  98. 19 19
      tools/interop_matrix/testcases/csharpcoreclr__master
  99. 22 0
      tools/interop_matrix/testcases/csharpcoreclr__v1.18.0
  100. 18 29
      tools/run_tests/generated/sources_and_headers.json

+ 3 - 1
BUILD

@@ -541,7 +541,6 @@ grpc_cc_library(
     name = "gpr_base",
     name = "gpr_base",
     srcs = [
     srcs = [
         "src/core/lib/gpr/alloc.cc",
         "src/core/lib/gpr/alloc.cc",
-        "src/core/lib/gpr/arena.cc",
         "src/core/lib/gpr/atm.cc",
         "src/core/lib/gpr/atm.cc",
         "src/core/lib/gpr/cpu_iphone.cc",
         "src/core/lib/gpr/cpu_iphone.cc",
         "src/core/lib/gpr/cpu_linux.cc",
         "src/core/lib/gpr/cpu_linux.cc",
@@ -574,6 +573,7 @@ grpc_cc_library(
         "src/core/lib/gpr/tmpfile_posix.cc",
         "src/core/lib/gpr/tmpfile_posix.cc",
         "src/core/lib/gpr/tmpfile_windows.cc",
         "src/core/lib/gpr/tmpfile_windows.cc",
         "src/core/lib/gpr/wrap_memcpy.cc",
         "src/core/lib/gpr/wrap_memcpy.cc",
+        "src/core/lib/gprpp/arena.cc",
         "src/core/lib/gprpp/fork.cc",
         "src/core/lib/gprpp/fork.cc",
         "src/core/lib/gprpp/thd_posix.cc",
         "src/core/lib/gprpp/thd_posix.cc",
         "src/core/lib/gprpp/thd_windows.cc",
         "src/core/lib/gprpp/thd_windows.cc",
@@ -598,6 +598,8 @@ grpc_cc_library(
         "src/core/lib/gpr/tmpfile.h",
         "src/core/lib/gpr/tmpfile.h",
         "src/core/lib/gpr/useful.h",
         "src/core/lib/gpr/useful.h",
         "src/core/lib/gprpp/abstract.h",
         "src/core/lib/gprpp/abstract.h",
+        "src/core/lib/gprpp/arena.h",
+        "src/core/lib/gprpp/atomic.h",
         "src/core/lib/gprpp/fork.h",
         "src/core/lib/gprpp/fork.h",
         "src/core/lib/gprpp/manual_constructor.h",
         "src/core/lib/gprpp/manual_constructor.h",
         "src/core/lib/gprpp/map.h",
         "src/core/lib/gprpp/map.h",

+ 14 - 1
BUILD.gn

@@ -131,7 +131,6 @@ config("grpc_config") {
         "include/grpc/support/time.h",
         "include/grpc/support/time.h",
         "src/core/lib/gpr/alloc.cc",
         "src/core/lib/gpr/alloc.cc",
         "src/core/lib/gpr/alloc.h",
         "src/core/lib/gpr/alloc.h",
-        "src/core/lib/gpr/arena.cc",
         "src/core/lib/gpr/arena.h",
         "src/core/lib/gpr/arena.h",
         "src/core/lib/gpr/atm.cc",
         "src/core/lib/gpr/atm.cc",
         "src/core/lib/gpr/cpu_iphone.cc",
         "src/core/lib/gpr/cpu_iphone.cc",
@@ -180,6 +179,8 @@ config("grpc_config") {
         "src/core/lib/gpr/useful.h",
         "src/core/lib/gpr/useful.h",
         "src/core/lib/gpr/wrap_memcpy.cc",
         "src/core/lib/gpr/wrap_memcpy.cc",
         "src/core/lib/gprpp/abstract.h",
         "src/core/lib/gprpp/abstract.h",
+        "src/core/lib/gprpp/arena.cc",
+        "src/core/lib/gprpp/arena.h",
         "src/core/lib/gprpp/atomic.h",
         "src/core/lib/gprpp/atomic.h",
         "src/core/lib/gprpp/fork.cc",
         "src/core/lib/gprpp/fork.cc",
         "src/core/lib/gprpp/fork.h",
         "src/core/lib/gprpp/fork.h",
@@ -481,18 +482,24 @@ config("grpc_config") {
         "src/core/lib/iomgr/buffer_list.h",
         "src/core/lib/iomgr/buffer_list.h",
         "src/core/lib/iomgr/call_combiner.cc",
         "src/core/lib/iomgr/call_combiner.cc",
         "src/core/lib/iomgr/call_combiner.h",
         "src/core/lib/iomgr/call_combiner.h",
+        "src/core/lib/iomgr/cfstream_handle.cc",
+        "src/core/lib/iomgr/cfstream_handle.h",
         "src/core/lib/iomgr/closure.h",
         "src/core/lib/iomgr/closure.h",
         "src/core/lib/iomgr/combiner.cc",
         "src/core/lib/iomgr/combiner.cc",
         "src/core/lib/iomgr/combiner.h",
         "src/core/lib/iomgr/combiner.h",
         "src/core/lib/iomgr/dynamic_annotations.h",
         "src/core/lib/iomgr/dynamic_annotations.h",
         "src/core/lib/iomgr/endpoint.cc",
         "src/core/lib/iomgr/endpoint.cc",
         "src/core/lib/iomgr/endpoint.h",
         "src/core/lib/iomgr/endpoint.h",
+        "src/core/lib/iomgr/endpoint_cfstream.cc",
+        "src/core/lib/iomgr/endpoint_cfstream.h",
         "src/core/lib/iomgr/endpoint_pair.h",
         "src/core/lib/iomgr/endpoint_pair.h",
         "src/core/lib/iomgr/endpoint_pair_posix.cc",
         "src/core/lib/iomgr/endpoint_pair_posix.cc",
         "src/core/lib/iomgr/endpoint_pair_uv.cc",
         "src/core/lib/iomgr/endpoint_pair_uv.cc",
         "src/core/lib/iomgr/endpoint_pair_windows.cc",
         "src/core/lib/iomgr/endpoint_pair_windows.cc",
         "src/core/lib/iomgr/error.cc",
         "src/core/lib/iomgr/error.cc",
         "src/core/lib/iomgr/error.h",
         "src/core/lib/iomgr/error.h",
+        "src/core/lib/iomgr/error_cfstream.cc",
+        "src/core/lib/iomgr/error_cfstream.h",
         "src/core/lib/iomgr/error_internal.h",
         "src/core/lib/iomgr/error_internal.h",
         "src/core/lib/iomgr/ev_epoll1_linux.cc",
         "src/core/lib/iomgr/ev_epoll1_linux.cc",
         "src/core/lib/iomgr/ev_epoll1_linux.h",
         "src/core/lib/iomgr/ev_epoll1_linux.h",
@@ -528,6 +535,7 @@ config("grpc_config") {
         "src/core/lib/iomgr/iomgr_internal.h",
         "src/core/lib/iomgr/iomgr_internal.h",
         "src/core/lib/iomgr/iomgr_posix.cc",
         "src/core/lib/iomgr/iomgr_posix.cc",
         "src/core/lib/iomgr/iomgr_posix.h",
         "src/core/lib/iomgr/iomgr_posix.h",
+        "src/core/lib/iomgr/iomgr_posix_cfstream.cc",
         "src/core/lib/iomgr/iomgr_uv.cc",
         "src/core/lib/iomgr/iomgr_uv.cc",
         "src/core/lib/iomgr/iomgr_windows.cc",
         "src/core/lib/iomgr/iomgr_windows.cc",
         "src/core/lib/iomgr/is_epollexclusive_available.cc",
         "src/core/lib/iomgr/is_epollexclusive_available.cc",
@@ -583,6 +591,7 @@ config("grpc_config") {
         "src/core/lib/iomgr/sys_epoll_wrapper.h",
         "src/core/lib/iomgr/sys_epoll_wrapper.h",
         "src/core/lib/iomgr/tcp_client.cc",
         "src/core/lib/iomgr/tcp_client.cc",
         "src/core/lib/iomgr/tcp_client.h",
         "src/core/lib/iomgr/tcp_client.h",
+        "src/core/lib/iomgr/tcp_client_cfstream.cc",
         "src/core/lib/iomgr/tcp_client_custom.cc",
         "src/core/lib/iomgr/tcp_client_custom.cc",
         "src/core/lib/iomgr/tcp_client_posix.cc",
         "src/core/lib/iomgr/tcp_client_posix.cc",
         "src/core/lib/iomgr/tcp_client_posix.h",
         "src/core/lib/iomgr/tcp_client_posix.h",
@@ -1157,6 +1166,7 @@ config("grpc_config") {
         "src/core/lib/gpr/tmpfile.h",
         "src/core/lib/gpr/tmpfile.h",
         "src/core/lib/gpr/useful.h",
         "src/core/lib/gpr/useful.h",
         "src/core/lib/gprpp/abstract.h",
         "src/core/lib/gprpp/abstract.h",
+        "src/core/lib/gprpp/arena.h",
         "src/core/lib/gprpp/atomic.h",
         "src/core/lib/gprpp/atomic.h",
         "src/core/lib/gprpp/debug_location.h",
         "src/core/lib/gprpp/debug_location.h",
         "src/core/lib/gprpp/fork.h",
         "src/core/lib/gprpp/fork.h",
@@ -1177,12 +1187,15 @@ config("grpc_config") {
         "src/core/lib/iomgr/block_annotate.h",
         "src/core/lib/iomgr/block_annotate.h",
         "src/core/lib/iomgr/buffer_list.h",
         "src/core/lib/iomgr/buffer_list.h",
         "src/core/lib/iomgr/call_combiner.h",
         "src/core/lib/iomgr/call_combiner.h",
+        "src/core/lib/iomgr/cfstream_handle.h",
         "src/core/lib/iomgr/closure.h",
         "src/core/lib/iomgr/closure.h",
         "src/core/lib/iomgr/combiner.h",
         "src/core/lib/iomgr/combiner.h",
         "src/core/lib/iomgr/dynamic_annotations.h",
         "src/core/lib/iomgr/dynamic_annotations.h",
         "src/core/lib/iomgr/endpoint.h",
         "src/core/lib/iomgr/endpoint.h",
+        "src/core/lib/iomgr/endpoint_cfstream.h",
         "src/core/lib/iomgr/endpoint_pair.h",
         "src/core/lib/iomgr/endpoint_pair.h",
         "src/core/lib/iomgr/error.h",
         "src/core/lib/iomgr/error.h",
+        "src/core/lib/iomgr/error_cfstream.h",
         "src/core/lib/iomgr/error_internal.h",
         "src/core/lib/iomgr/error_internal.h",
         "src/core/lib/iomgr/ev_epoll1_linux.h",
         "src/core/lib/iomgr/ev_epoll1_linux.h",
         "src/core/lib/iomgr/ev_epollex_linux.h",
         "src/core/lib/iomgr/ev_epollex_linux.h",

+ 34 - 1
CMakeLists.txt

@@ -839,7 +839,6 @@ endif (gRPC_BUILD_TESTS)
 
 
 add_library(gpr
 add_library(gpr
   src/core/lib/gpr/alloc.cc
   src/core/lib/gpr/alloc.cc
-  src/core/lib/gpr/arena.cc
   src/core/lib/gpr/atm.cc
   src/core/lib/gpr/atm.cc
   src/core/lib/gpr/cpu_iphone.cc
   src/core/lib/gpr/cpu_iphone.cc
   src/core/lib/gpr/cpu_linux.cc
   src/core/lib/gpr/cpu_linux.cc
@@ -872,6 +871,7 @@ add_library(gpr
   src/core/lib/gpr/tmpfile_posix.cc
   src/core/lib/gpr/tmpfile_posix.cc
   src/core/lib/gpr/tmpfile_windows.cc
   src/core/lib/gpr/tmpfile_windows.cc
   src/core/lib/gpr/wrap_memcpy.cc
   src/core/lib/gpr/wrap_memcpy.cc
+  src/core/lib/gprpp/arena.cc
   src/core/lib/gprpp/fork.cc
   src/core/lib/gprpp/fork.cc
   src/core/lib/gprpp/thd_posix.cc
   src/core/lib/gprpp/thd_posix.cc
   src/core/lib/gprpp/thd_windows.cc
   src/core/lib/gprpp/thd_windows.cc
@@ -997,12 +997,15 @@ add_library(grpc
   src/core/lib/http/parser.cc
   src/core/lib/http/parser.cc
   src/core/lib/iomgr/buffer_list.cc
   src/core/lib/iomgr/buffer_list.cc
   src/core/lib/iomgr/call_combiner.cc
   src/core/lib/iomgr/call_combiner.cc
+  src/core/lib/iomgr/cfstream_handle.cc
   src/core/lib/iomgr/combiner.cc
   src/core/lib/iomgr/combiner.cc
   src/core/lib/iomgr/endpoint.cc
   src/core/lib/iomgr/endpoint.cc
+  src/core/lib/iomgr/endpoint_cfstream.cc
   src/core/lib/iomgr/endpoint_pair_posix.cc
   src/core/lib/iomgr/endpoint_pair_posix.cc
   src/core/lib/iomgr/endpoint_pair_uv.cc
   src/core/lib/iomgr/endpoint_pair_uv.cc
   src/core/lib/iomgr/endpoint_pair_windows.cc
   src/core/lib/iomgr/endpoint_pair_windows.cc
   src/core/lib/iomgr/error.cc
   src/core/lib/iomgr/error.cc
+  src/core/lib/iomgr/error_cfstream.cc
   src/core/lib/iomgr/ev_epoll1_linux.cc
   src/core/lib/iomgr/ev_epoll1_linux.cc
   src/core/lib/iomgr/ev_epollex_linux.cc
   src/core/lib/iomgr/ev_epollex_linux.cc
   src/core/lib/iomgr/ev_poll_posix.cc
   src/core/lib/iomgr/ev_poll_posix.cc
@@ -1023,6 +1026,7 @@ add_library(grpc
   src/core/lib/iomgr/iomgr_custom.cc
   src/core/lib/iomgr/iomgr_custom.cc
   src/core/lib/iomgr/iomgr_internal.cc
   src/core/lib/iomgr/iomgr_internal.cc
   src/core/lib/iomgr/iomgr_posix.cc
   src/core/lib/iomgr/iomgr_posix.cc
+  src/core/lib/iomgr/iomgr_posix_cfstream.cc
   src/core/lib/iomgr/iomgr_uv.cc
   src/core/lib/iomgr/iomgr_uv.cc
   src/core/lib/iomgr/iomgr_windows.cc
   src/core/lib/iomgr/iomgr_windows.cc
   src/core/lib/iomgr/is_epollexclusive_available.cc
   src/core/lib/iomgr/is_epollexclusive_available.cc
@@ -1051,6 +1055,7 @@ add_library(grpc
   src/core/lib/iomgr/socket_utils_windows.cc
   src/core/lib/iomgr/socket_utils_windows.cc
   src/core/lib/iomgr/socket_windows.cc
   src/core/lib/iomgr/socket_windows.cc
   src/core/lib/iomgr/tcp_client.cc
   src/core/lib/iomgr/tcp_client.cc
+  src/core/lib/iomgr/tcp_client_cfstream.cc
   src/core/lib/iomgr/tcp_client_custom.cc
   src/core/lib/iomgr/tcp_client_custom.cc
   src/core/lib/iomgr/tcp_client_posix.cc
   src/core/lib/iomgr/tcp_client_posix.cc
   src/core/lib/iomgr/tcp_client_windows.cc
   src/core/lib/iomgr/tcp_client_windows.cc
@@ -1424,12 +1429,15 @@ add_library(grpc_cronet
   src/core/lib/http/parser.cc
   src/core/lib/http/parser.cc
   src/core/lib/iomgr/buffer_list.cc
   src/core/lib/iomgr/buffer_list.cc
   src/core/lib/iomgr/call_combiner.cc
   src/core/lib/iomgr/call_combiner.cc
+  src/core/lib/iomgr/cfstream_handle.cc
   src/core/lib/iomgr/combiner.cc
   src/core/lib/iomgr/combiner.cc
   src/core/lib/iomgr/endpoint.cc
   src/core/lib/iomgr/endpoint.cc
+  src/core/lib/iomgr/endpoint_cfstream.cc
   src/core/lib/iomgr/endpoint_pair_posix.cc
   src/core/lib/iomgr/endpoint_pair_posix.cc
   src/core/lib/iomgr/endpoint_pair_uv.cc
   src/core/lib/iomgr/endpoint_pair_uv.cc
   src/core/lib/iomgr/endpoint_pair_windows.cc
   src/core/lib/iomgr/endpoint_pair_windows.cc
   src/core/lib/iomgr/error.cc
   src/core/lib/iomgr/error.cc
+  src/core/lib/iomgr/error_cfstream.cc
   src/core/lib/iomgr/ev_epoll1_linux.cc
   src/core/lib/iomgr/ev_epoll1_linux.cc
   src/core/lib/iomgr/ev_epollex_linux.cc
   src/core/lib/iomgr/ev_epollex_linux.cc
   src/core/lib/iomgr/ev_poll_posix.cc
   src/core/lib/iomgr/ev_poll_posix.cc
@@ -1450,6 +1458,7 @@ add_library(grpc_cronet
   src/core/lib/iomgr/iomgr_custom.cc
   src/core/lib/iomgr/iomgr_custom.cc
   src/core/lib/iomgr/iomgr_internal.cc
   src/core/lib/iomgr/iomgr_internal.cc
   src/core/lib/iomgr/iomgr_posix.cc
   src/core/lib/iomgr/iomgr_posix.cc
+  src/core/lib/iomgr/iomgr_posix_cfstream.cc
   src/core/lib/iomgr/iomgr_uv.cc
   src/core/lib/iomgr/iomgr_uv.cc
   src/core/lib/iomgr/iomgr_windows.cc
   src/core/lib/iomgr/iomgr_windows.cc
   src/core/lib/iomgr/is_epollexclusive_available.cc
   src/core/lib/iomgr/is_epollexclusive_available.cc
@@ -1478,6 +1487,7 @@ add_library(grpc_cronet
   src/core/lib/iomgr/socket_utils_windows.cc
   src/core/lib/iomgr/socket_utils_windows.cc
   src/core/lib/iomgr/socket_windows.cc
   src/core/lib/iomgr/socket_windows.cc
   src/core/lib/iomgr/tcp_client.cc
   src/core/lib/iomgr/tcp_client.cc
+  src/core/lib/iomgr/tcp_client_cfstream.cc
   src/core/lib/iomgr/tcp_client_custom.cc
   src/core/lib/iomgr/tcp_client_custom.cc
   src/core/lib/iomgr/tcp_client_posix.cc
   src/core/lib/iomgr/tcp_client_posix.cc
   src/core/lib/iomgr/tcp_client_windows.cc
   src/core/lib/iomgr/tcp_client_windows.cc
@@ -1836,12 +1846,15 @@ add_library(grpc_test_util
   src/core/lib/http/parser.cc
   src/core/lib/http/parser.cc
   src/core/lib/iomgr/buffer_list.cc
   src/core/lib/iomgr/buffer_list.cc
   src/core/lib/iomgr/call_combiner.cc
   src/core/lib/iomgr/call_combiner.cc
+  src/core/lib/iomgr/cfstream_handle.cc
   src/core/lib/iomgr/combiner.cc
   src/core/lib/iomgr/combiner.cc
   src/core/lib/iomgr/endpoint.cc
   src/core/lib/iomgr/endpoint.cc
+  src/core/lib/iomgr/endpoint_cfstream.cc
   src/core/lib/iomgr/endpoint_pair_posix.cc
   src/core/lib/iomgr/endpoint_pair_posix.cc
   src/core/lib/iomgr/endpoint_pair_uv.cc
   src/core/lib/iomgr/endpoint_pair_uv.cc
   src/core/lib/iomgr/endpoint_pair_windows.cc
   src/core/lib/iomgr/endpoint_pair_windows.cc
   src/core/lib/iomgr/error.cc
   src/core/lib/iomgr/error.cc
+  src/core/lib/iomgr/error_cfstream.cc
   src/core/lib/iomgr/ev_epoll1_linux.cc
   src/core/lib/iomgr/ev_epoll1_linux.cc
   src/core/lib/iomgr/ev_epollex_linux.cc
   src/core/lib/iomgr/ev_epollex_linux.cc
   src/core/lib/iomgr/ev_poll_posix.cc
   src/core/lib/iomgr/ev_poll_posix.cc
@@ -1862,6 +1875,7 @@ add_library(grpc_test_util
   src/core/lib/iomgr/iomgr_custom.cc
   src/core/lib/iomgr/iomgr_custom.cc
   src/core/lib/iomgr/iomgr_internal.cc
   src/core/lib/iomgr/iomgr_internal.cc
   src/core/lib/iomgr/iomgr_posix.cc
   src/core/lib/iomgr/iomgr_posix.cc
+  src/core/lib/iomgr/iomgr_posix_cfstream.cc
   src/core/lib/iomgr/iomgr_uv.cc
   src/core/lib/iomgr/iomgr_uv.cc
   src/core/lib/iomgr/iomgr_windows.cc
   src/core/lib/iomgr/iomgr_windows.cc
   src/core/lib/iomgr/is_epollexclusive_available.cc
   src/core/lib/iomgr/is_epollexclusive_available.cc
@@ -1890,6 +1904,7 @@ add_library(grpc_test_util
   src/core/lib/iomgr/socket_utils_windows.cc
   src/core/lib/iomgr/socket_utils_windows.cc
   src/core/lib/iomgr/socket_windows.cc
   src/core/lib/iomgr/socket_windows.cc
   src/core/lib/iomgr/tcp_client.cc
   src/core/lib/iomgr/tcp_client.cc
+  src/core/lib/iomgr/tcp_client_cfstream.cc
   src/core/lib/iomgr/tcp_client_custom.cc
   src/core/lib/iomgr/tcp_client_custom.cc
   src/core/lib/iomgr/tcp_client_posix.cc
   src/core/lib/iomgr/tcp_client_posix.cc
   src/core/lib/iomgr/tcp_client_windows.cc
   src/core/lib/iomgr/tcp_client_windows.cc
@@ -2161,12 +2176,15 @@ add_library(grpc_test_util_unsecure
   src/core/lib/http/parser.cc
   src/core/lib/http/parser.cc
   src/core/lib/iomgr/buffer_list.cc
   src/core/lib/iomgr/buffer_list.cc
   src/core/lib/iomgr/call_combiner.cc
   src/core/lib/iomgr/call_combiner.cc
+  src/core/lib/iomgr/cfstream_handle.cc
   src/core/lib/iomgr/combiner.cc
   src/core/lib/iomgr/combiner.cc
   src/core/lib/iomgr/endpoint.cc
   src/core/lib/iomgr/endpoint.cc
+  src/core/lib/iomgr/endpoint_cfstream.cc
   src/core/lib/iomgr/endpoint_pair_posix.cc
   src/core/lib/iomgr/endpoint_pair_posix.cc
   src/core/lib/iomgr/endpoint_pair_uv.cc
   src/core/lib/iomgr/endpoint_pair_uv.cc
   src/core/lib/iomgr/endpoint_pair_windows.cc
   src/core/lib/iomgr/endpoint_pair_windows.cc
   src/core/lib/iomgr/error.cc
   src/core/lib/iomgr/error.cc
+  src/core/lib/iomgr/error_cfstream.cc
   src/core/lib/iomgr/ev_epoll1_linux.cc
   src/core/lib/iomgr/ev_epoll1_linux.cc
   src/core/lib/iomgr/ev_epollex_linux.cc
   src/core/lib/iomgr/ev_epollex_linux.cc
   src/core/lib/iomgr/ev_poll_posix.cc
   src/core/lib/iomgr/ev_poll_posix.cc
@@ -2187,6 +2205,7 @@ add_library(grpc_test_util_unsecure
   src/core/lib/iomgr/iomgr_custom.cc
   src/core/lib/iomgr/iomgr_custom.cc
   src/core/lib/iomgr/iomgr_internal.cc
   src/core/lib/iomgr/iomgr_internal.cc
   src/core/lib/iomgr/iomgr_posix.cc
   src/core/lib/iomgr/iomgr_posix.cc
+  src/core/lib/iomgr/iomgr_posix_cfstream.cc
   src/core/lib/iomgr/iomgr_uv.cc
   src/core/lib/iomgr/iomgr_uv.cc
   src/core/lib/iomgr/iomgr_windows.cc
   src/core/lib/iomgr/iomgr_windows.cc
   src/core/lib/iomgr/is_epollexclusive_available.cc
   src/core/lib/iomgr/is_epollexclusive_available.cc
@@ -2215,6 +2234,7 @@ add_library(grpc_test_util_unsecure
   src/core/lib/iomgr/socket_utils_windows.cc
   src/core/lib/iomgr/socket_utils_windows.cc
   src/core/lib/iomgr/socket_windows.cc
   src/core/lib/iomgr/socket_windows.cc
   src/core/lib/iomgr/tcp_client.cc
   src/core/lib/iomgr/tcp_client.cc
+  src/core/lib/iomgr/tcp_client_cfstream.cc
   src/core/lib/iomgr/tcp_client_custom.cc
   src/core/lib/iomgr/tcp_client_custom.cc
   src/core/lib/iomgr/tcp_client_posix.cc
   src/core/lib/iomgr/tcp_client_posix.cc
   src/core/lib/iomgr/tcp_client_windows.cc
   src/core/lib/iomgr/tcp_client_windows.cc
@@ -2462,12 +2482,15 @@ add_library(grpc_unsecure
   src/core/lib/http/parser.cc
   src/core/lib/http/parser.cc
   src/core/lib/iomgr/buffer_list.cc
   src/core/lib/iomgr/buffer_list.cc
   src/core/lib/iomgr/call_combiner.cc
   src/core/lib/iomgr/call_combiner.cc
+  src/core/lib/iomgr/cfstream_handle.cc
   src/core/lib/iomgr/combiner.cc
   src/core/lib/iomgr/combiner.cc
   src/core/lib/iomgr/endpoint.cc
   src/core/lib/iomgr/endpoint.cc
+  src/core/lib/iomgr/endpoint_cfstream.cc
   src/core/lib/iomgr/endpoint_pair_posix.cc
   src/core/lib/iomgr/endpoint_pair_posix.cc
   src/core/lib/iomgr/endpoint_pair_uv.cc
   src/core/lib/iomgr/endpoint_pair_uv.cc
   src/core/lib/iomgr/endpoint_pair_windows.cc
   src/core/lib/iomgr/endpoint_pair_windows.cc
   src/core/lib/iomgr/error.cc
   src/core/lib/iomgr/error.cc
+  src/core/lib/iomgr/error_cfstream.cc
   src/core/lib/iomgr/ev_epoll1_linux.cc
   src/core/lib/iomgr/ev_epoll1_linux.cc
   src/core/lib/iomgr/ev_epollex_linux.cc
   src/core/lib/iomgr/ev_epollex_linux.cc
   src/core/lib/iomgr/ev_poll_posix.cc
   src/core/lib/iomgr/ev_poll_posix.cc
@@ -2488,6 +2511,7 @@ add_library(grpc_unsecure
   src/core/lib/iomgr/iomgr_custom.cc
   src/core/lib/iomgr/iomgr_custom.cc
   src/core/lib/iomgr/iomgr_internal.cc
   src/core/lib/iomgr/iomgr_internal.cc
   src/core/lib/iomgr/iomgr_posix.cc
   src/core/lib/iomgr/iomgr_posix.cc
+  src/core/lib/iomgr/iomgr_posix_cfstream.cc
   src/core/lib/iomgr/iomgr_uv.cc
   src/core/lib/iomgr/iomgr_uv.cc
   src/core/lib/iomgr/iomgr_windows.cc
   src/core/lib/iomgr/iomgr_windows.cc
   src/core/lib/iomgr/is_epollexclusive_available.cc
   src/core/lib/iomgr/is_epollexclusive_available.cc
@@ -2516,6 +2540,7 @@ add_library(grpc_unsecure
   src/core/lib/iomgr/socket_utils_windows.cc
   src/core/lib/iomgr/socket_utils_windows.cc
   src/core/lib/iomgr/socket_windows.cc
   src/core/lib/iomgr/socket_windows.cc
   src/core/lib/iomgr/tcp_client.cc
   src/core/lib/iomgr/tcp_client.cc
+  src/core/lib/iomgr/tcp_client_cfstream.cc
   src/core/lib/iomgr/tcp_client_custom.cc
   src/core/lib/iomgr/tcp_client_custom.cc
   src/core/lib/iomgr/tcp_client_posix.cc
   src/core/lib/iomgr/tcp_client_posix.cc
   src/core/lib/iomgr/tcp_client_windows.cc
   src/core/lib/iomgr/tcp_client_windows.cc
@@ -3364,12 +3389,15 @@ add_library(grpc++_cronet
   src/core/lib/http/parser.cc
   src/core/lib/http/parser.cc
   src/core/lib/iomgr/buffer_list.cc
   src/core/lib/iomgr/buffer_list.cc
   src/core/lib/iomgr/call_combiner.cc
   src/core/lib/iomgr/call_combiner.cc
+  src/core/lib/iomgr/cfstream_handle.cc
   src/core/lib/iomgr/combiner.cc
   src/core/lib/iomgr/combiner.cc
   src/core/lib/iomgr/endpoint.cc
   src/core/lib/iomgr/endpoint.cc
+  src/core/lib/iomgr/endpoint_cfstream.cc
   src/core/lib/iomgr/endpoint_pair_posix.cc
   src/core/lib/iomgr/endpoint_pair_posix.cc
   src/core/lib/iomgr/endpoint_pair_uv.cc
   src/core/lib/iomgr/endpoint_pair_uv.cc
   src/core/lib/iomgr/endpoint_pair_windows.cc
   src/core/lib/iomgr/endpoint_pair_windows.cc
   src/core/lib/iomgr/error.cc
   src/core/lib/iomgr/error.cc
+  src/core/lib/iomgr/error_cfstream.cc
   src/core/lib/iomgr/ev_epoll1_linux.cc
   src/core/lib/iomgr/ev_epoll1_linux.cc
   src/core/lib/iomgr/ev_epollex_linux.cc
   src/core/lib/iomgr/ev_epollex_linux.cc
   src/core/lib/iomgr/ev_poll_posix.cc
   src/core/lib/iomgr/ev_poll_posix.cc
@@ -3390,6 +3418,7 @@ add_library(grpc++_cronet
   src/core/lib/iomgr/iomgr_custom.cc
   src/core/lib/iomgr/iomgr_custom.cc
   src/core/lib/iomgr/iomgr_internal.cc
   src/core/lib/iomgr/iomgr_internal.cc
   src/core/lib/iomgr/iomgr_posix.cc
   src/core/lib/iomgr/iomgr_posix.cc
+  src/core/lib/iomgr/iomgr_posix_cfstream.cc
   src/core/lib/iomgr/iomgr_uv.cc
   src/core/lib/iomgr/iomgr_uv.cc
   src/core/lib/iomgr/iomgr_windows.cc
   src/core/lib/iomgr/iomgr_windows.cc
   src/core/lib/iomgr/is_epollexclusive_available.cc
   src/core/lib/iomgr/is_epollexclusive_available.cc
@@ -3418,6 +3447,7 @@ add_library(grpc++_cronet
   src/core/lib/iomgr/socket_utils_windows.cc
   src/core/lib/iomgr/socket_utils_windows.cc
   src/core/lib/iomgr/socket_windows.cc
   src/core/lib/iomgr/socket_windows.cc
   src/core/lib/iomgr/tcp_client.cc
   src/core/lib/iomgr/tcp_client.cc
+  src/core/lib/iomgr/tcp_client_cfstream.cc
   src/core/lib/iomgr/tcp_client_custom.cc
   src/core/lib/iomgr/tcp_client_custom.cc
   src/core/lib/iomgr/tcp_client_posix.cc
   src/core/lib/iomgr/tcp_client_posix.cc
   src/core/lib/iomgr/tcp_client_windows.cc
   src/core/lib/iomgr/tcp_client_windows.cc
@@ -12690,6 +12720,7 @@ target_include_directories(client_crash_test_server
 target_link_libraries(client_crash_test_server
 target_link_libraries(client_crash_test_server
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc++_test_config
   grpc++_test_util
   grpc++_test_util
   grpc_test_util
   grpc_test_util
   grpc++
   grpc++
@@ -13429,6 +13460,7 @@ target_include_directories(golden_file_test
 target_link_libraries(golden_file_test
 target_link_libraries(golden_file_test
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc++_test_config
   grpc++
   grpc++
   grpc
   grpc
   gpr
   gpr
@@ -15673,6 +15705,7 @@ target_include_directories(server_crash_test_client
 target_link_libraries(server_crash_test_client
 target_link_libraries(server_crash_test_client
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc++_test_config
   grpc++_test_util
   grpc++_test_util
   grpc_test_util
   grpc_test_util
   grpc++
   grpc++

+ 12 - 1
CONTRIBUTING.md

@@ -110,5 +110,16 @@ How to get your contributions merged smoothly and quickly.
 - Exceptions to the rules can be made if there's a compelling reason for doing
 - Exceptions to the rules can be made if there's a compelling reason for doing
   so.
   so.
 
 
-
+## Obtaining Commit Access
+We grant Commit Access to contributors based on the following criteria:
+* Sustained contribution to the gRPC project.
+* Deep understanding of the areas contributed to, and good consideration of various reliability, usability and performance tradeoffs. 
+* Contributions demonstrate that obtaining Commit Access will significantly reduce friction for the contributors or others. 
+
+In addition to submitting PRs, a Contributor with Commit Access can:
+* Review PRs and merge once other checks and criteria pass.
+* Triage bugs and PRs and assign appropriate labels and reviewers. 
+
+### Obtaining Commit Access without Code Contributions 
+The [gRPC organization](https://github.com/grpc) is comprised of multiple repositories and commit access is usually restricted to one or more of these repositories. Some repositories such as the [grpc.github.io](https://github.com/grpc/grpc.github.io/) do not have code, but the same principle of sustained, high quality contributions, with a good understanding of the fundamentals, apply. 
 
 

+ 41 - 11
Makefile

@@ -3320,7 +3320,6 @@ endif
 
 
 LIBGPR_SRC = \
 LIBGPR_SRC = \
     src/core/lib/gpr/alloc.cc \
     src/core/lib/gpr/alloc.cc \
-    src/core/lib/gpr/arena.cc \
     src/core/lib/gpr/atm.cc \
     src/core/lib/gpr/atm.cc \
     src/core/lib/gpr/cpu_iphone.cc \
     src/core/lib/gpr/cpu_iphone.cc \
     src/core/lib/gpr/cpu_linux.cc \
     src/core/lib/gpr/cpu_linux.cc \
@@ -3353,6 +3352,7 @@ LIBGPR_SRC = \
     src/core/lib/gpr/tmpfile_posix.cc \
     src/core/lib/gpr/tmpfile_posix.cc \
     src/core/lib/gpr/tmpfile_windows.cc \
     src/core/lib/gpr/tmpfile_windows.cc \
     src/core/lib/gpr/wrap_memcpy.cc \
     src/core/lib/gpr/wrap_memcpy.cc \
+    src/core/lib/gprpp/arena.cc \
     src/core/lib/gprpp/fork.cc \
     src/core/lib/gprpp/fork.cc \
     src/core/lib/gprpp/thd_posix.cc \
     src/core/lib/gprpp/thd_posix.cc \
     src/core/lib/gprpp/thd_windows.cc \
     src/core/lib/gprpp/thd_windows.cc \
@@ -3457,12 +3457,15 @@ LIBGRPC_SRC = \
     src/core/lib/http/parser.cc \
     src/core/lib/http/parser.cc \
     src/core/lib/iomgr/buffer_list.cc \
     src/core/lib/iomgr/buffer_list.cc \
     src/core/lib/iomgr/call_combiner.cc \
     src/core/lib/iomgr/call_combiner.cc \
+    src/core/lib/iomgr/cfstream_handle.cc \
     src/core/lib/iomgr/combiner.cc \
     src/core/lib/iomgr/combiner.cc \
     src/core/lib/iomgr/endpoint.cc \
     src/core/lib/iomgr/endpoint.cc \
+    src/core/lib/iomgr/endpoint_cfstream.cc \
     src/core/lib/iomgr/endpoint_pair_posix.cc \
     src/core/lib/iomgr/endpoint_pair_posix.cc \
     src/core/lib/iomgr/endpoint_pair_uv.cc \
     src/core/lib/iomgr/endpoint_pair_uv.cc \
     src/core/lib/iomgr/endpoint_pair_windows.cc \
     src/core/lib/iomgr/endpoint_pair_windows.cc \
     src/core/lib/iomgr/error.cc \
     src/core/lib/iomgr/error.cc \
+    src/core/lib/iomgr/error_cfstream.cc \
     src/core/lib/iomgr/ev_epoll1_linux.cc \
     src/core/lib/iomgr/ev_epoll1_linux.cc \
     src/core/lib/iomgr/ev_epollex_linux.cc \
     src/core/lib/iomgr/ev_epollex_linux.cc \
     src/core/lib/iomgr/ev_poll_posix.cc \
     src/core/lib/iomgr/ev_poll_posix.cc \
@@ -3483,6 +3486,7 @@ LIBGRPC_SRC = \
     src/core/lib/iomgr/iomgr_custom.cc \
     src/core/lib/iomgr/iomgr_custom.cc \
     src/core/lib/iomgr/iomgr_internal.cc \
     src/core/lib/iomgr/iomgr_internal.cc \
     src/core/lib/iomgr/iomgr_posix.cc \
     src/core/lib/iomgr/iomgr_posix.cc \
+    src/core/lib/iomgr/iomgr_posix_cfstream.cc \
     src/core/lib/iomgr/iomgr_uv.cc \
     src/core/lib/iomgr/iomgr_uv.cc \
     src/core/lib/iomgr/iomgr_windows.cc \
     src/core/lib/iomgr/iomgr_windows.cc \
     src/core/lib/iomgr/is_epollexclusive_available.cc \
     src/core/lib/iomgr/is_epollexclusive_available.cc \
@@ -3511,6 +3515,7 @@ LIBGRPC_SRC = \
     src/core/lib/iomgr/socket_utils_windows.cc \
     src/core/lib/iomgr/socket_utils_windows.cc \
     src/core/lib/iomgr/socket_windows.cc \
     src/core/lib/iomgr/socket_windows.cc \
     src/core/lib/iomgr/tcp_client.cc \
     src/core/lib/iomgr/tcp_client.cc \
+    src/core/lib/iomgr/tcp_client_cfstream.cc \
     src/core/lib/iomgr/tcp_client_custom.cc \
     src/core/lib/iomgr/tcp_client_custom.cc \
     src/core/lib/iomgr/tcp_client_posix.cc \
     src/core/lib/iomgr/tcp_client_posix.cc \
     src/core/lib/iomgr/tcp_client_windows.cc \
     src/core/lib/iomgr/tcp_client_windows.cc \
@@ -3878,12 +3883,15 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/http/parser.cc \
     src/core/lib/http/parser.cc \
     src/core/lib/iomgr/buffer_list.cc \
     src/core/lib/iomgr/buffer_list.cc \
     src/core/lib/iomgr/call_combiner.cc \
     src/core/lib/iomgr/call_combiner.cc \
+    src/core/lib/iomgr/cfstream_handle.cc \
     src/core/lib/iomgr/combiner.cc \
     src/core/lib/iomgr/combiner.cc \
     src/core/lib/iomgr/endpoint.cc \
     src/core/lib/iomgr/endpoint.cc \
+    src/core/lib/iomgr/endpoint_cfstream.cc \
     src/core/lib/iomgr/endpoint_pair_posix.cc \
     src/core/lib/iomgr/endpoint_pair_posix.cc \
     src/core/lib/iomgr/endpoint_pair_uv.cc \
     src/core/lib/iomgr/endpoint_pair_uv.cc \
     src/core/lib/iomgr/endpoint_pair_windows.cc \
     src/core/lib/iomgr/endpoint_pair_windows.cc \
     src/core/lib/iomgr/error.cc \
     src/core/lib/iomgr/error.cc \
+    src/core/lib/iomgr/error_cfstream.cc \
     src/core/lib/iomgr/ev_epoll1_linux.cc \
     src/core/lib/iomgr/ev_epoll1_linux.cc \
     src/core/lib/iomgr/ev_epollex_linux.cc \
     src/core/lib/iomgr/ev_epollex_linux.cc \
     src/core/lib/iomgr/ev_poll_posix.cc \
     src/core/lib/iomgr/ev_poll_posix.cc \
@@ -3904,6 +3912,7 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/iomgr/iomgr_custom.cc \
     src/core/lib/iomgr/iomgr_custom.cc \
     src/core/lib/iomgr/iomgr_internal.cc \
     src/core/lib/iomgr/iomgr_internal.cc \
     src/core/lib/iomgr/iomgr_posix.cc \
     src/core/lib/iomgr/iomgr_posix.cc \
+    src/core/lib/iomgr/iomgr_posix_cfstream.cc \
     src/core/lib/iomgr/iomgr_uv.cc \
     src/core/lib/iomgr/iomgr_uv.cc \
     src/core/lib/iomgr/iomgr_windows.cc \
     src/core/lib/iomgr/iomgr_windows.cc \
     src/core/lib/iomgr/is_epollexclusive_available.cc \
     src/core/lib/iomgr/is_epollexclusive_available.cc \
@@ -3932,6 +3941,7 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/iomgr/socket_utils_windows.cc \
     src/core/lib/iomgr/socket_utils_windows.cc \
     src/core/lib/iomgr/socket_windows.cc \
     src/core/lib/iomgr/socket_windows.cc \
     src/core/lib/iomgr/tcp_client.cc \
     src/core/lib/iomgr/tcp_client.cc \
+    src/core/lib/iomgr/tcp_client_cfstream.cc \
     src/core/lib/iomgr/tcp_client_custom.cc \
     src/core/lib/iomgr/tcp_client_custom.cc \
     src/core/lib/iomgr/tcp_client_posix.cc \
     src/core/lib/iomgr/tcp_client_posix.cc \
     src/core/lib/iomgr/tcp_client_windows.cc \
     src/core/lib/iomgr/tcp_client_windows.cc \
@@ -4283,12 +4293,15 @@ LIBGRPC_TEST_UTIL_SRC = \
     src/core/lib/http/parser.cc \
     src/core/lib/http/parser.cc \
     src/core/lib/iomgr/buffer_list.cc \
     src/core/lib/iomgr/buffer_list.cc \
     src/core/lib/iomgr/call_combiner.cc \
     src/core/lib/iomgr/call_combiner.cc \
+    src/core/lib/iomgr/cfstream_handle.cc \
     src/core/lib/iomgr/combiner.cc \
     src/core/lib/iomgr/combiner.cc \
     src/core/lib/iomgr/endpoint.cc \
     src/core/lib/iomgr/endpoint.cc \
+    src/core/lib/iomgr/endpoint_cfstream.cc \
     src/core/lib/iomgr/endpoint_pair_posix.cc \
     src/core/lib/iomgr/endpoint_pair_posix.cc \
     src/core/lib/iomgr/endpoint_pair_uv.cc \
     src/core/lib/iomgr/endpoint_pair_uv.cc \
     src/core/lib/iomgr/endpoint_pair_windows.cc \
     src/core/lib/iomgr/endpoint_pair_windows.cc \
     src/core/lib/iomgr/error.cc \
     src/core/lib/iomgr/error.cc \
+    src/core/lib/iomgr/error_cfstream.cc \
     src/core/lib/iomgr/ev_epoll1_linux.cc \
     src/core/lib/iomgr/ev_epoll1_linux.cc \
     src/core/lib/iomgr/ev_epollex_linux.cc \
     src/core/lib/iomgr/ev_epollex_linux.cc \
     src/core/lib/iomgr/ev_poll_posix.cc \
     src/core/lib/iomgr/ev_poll_posix.cc \
@@ -4309,6 +4322,7 @@ LIBGRPC_TEST_UTIL_SRC = \
     src/core/lib/iomgr/iomgr_custom.cc \
     src/core/lib/iomgr/iomgr_custom.cc \
     src/core/lib/iomgr/iomgr_internal.cc \
     src/core/lib/iomgr/iomgr_internal.cc \
     src/core/lib/iomgr/iomgr_posix.cc \
     src/core/lib/iomgr/iomgr_posix.cc \
+    src/core/lib/iomgr/iomgr_posix_cfstream.cc \
     src/core/lib/iomgr/iomgr_uv.cc \
     src/core/lib/iomgr/iomgr_uv.cc \
     src/core/lib/iomgr/iomgr_windows.cc \
     src/core/lib/iomgr/iomgr_windows.cc \
     src/core/lib/iomgr/is_epollexclusive_available.cc \
     src/core/lib/iomgr/is_epollexclusive_available.cc \
@@ -4337,6 +4351,7 @@ LIBGRPC_TEST_UTIL_SRC = \
     src/core/lib/iomgr/socket_utils_windows.cc \
     src/core/lib/iomgr/socket_utils_windows.cc \
     src/core/lib/iomgr/socket_windows.cc \
     src/core/lib/iomgr/socket_windows.cc \
     src/core/lib/iomgr/tcp_client.cc \
     src/core/lib/iomgr/tcp_client.cc \
+    src/core/lib/iomgr/tcp_client_cfstream.cc \
     src/core/lib/iomgr/tcp_client_custom.cc \
     src/core/lib/iomgr/tcp_client_custom.cc \
     src/core/lib/iomgr/tcp_client_posix.cc \
     src/core/lib/iomgr/tcp_client_posix.cc \
     src/core/lib/iomgr/tcp_client_windows.cc \
     src/core/lib/iomgr/tcp_client_windows.cc \
@@ -4595,12 +4610,15 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
     src/core/lib/http/parser.cc \
     src/core/lib/http/parser.cc \
     src/core/lib/iomgr/buffer_list.cc \
     src/core/lib/iomgr/buffer_list.cc \
     src/core/lib/iomgr/call_combiner.cc \
     src/core/lib/iomgr/call_combiner.cc \
+    src/core/lib/iomgr/cfstream_handle.cc \
     src/core/lib/iomgr/combiner.cc \
     src/core/lib/iomgr/combiner.cc \
     src/core/lib/iomgr/endpoint.cc \
     src/core/lib/iomgr/endpoint.cc \
+    src/core/lib/iomgr/endpoint_cfstream.cc \
     src/core/lib/iomgr/endpoint_pair_posix.cc \
     src/core/lib/iomgr/endpoint_pair_posix.cc \
     src/core/lib/iomgr/endpoint_pair_uv.cc \
     src/core/lib/iomgr/endpoint_pair_uv.cc \
     src/core/lib/iomgr/endpoint_pair_windows.cc \
     src/core/lib/iomgr/endpoint_pair_windows.cc \
     src/core/lib/iomgr/error.cc \
     src/core/lib/iomgr/error.cc \
+    src/core/lib/iomgr/error_cfstream.cc \
     src/core/lib/iomgr/ev_epoll1_linux.cc \
     src/core/lib/iomgr/ev_epoll1_linux.cc \
     src/core/lib/iomgr/ev_epollex_linux.cc \
     src/core/lib/iomgr/ev_epollex_linux.cc \
     src/core/lib/iomgr/ev_poll_posix.cc \
     src/core/lib/iomgr/ev_poll_posix.cc \
@@ -4621,6 +4639,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
     src/core/lib/iomgr/iomgr_custom.cc \
     src/core/lib/iomgr/iomgr_custom.cc \
     src/core/lib/iomgr/iomgr_internal.cc \
     src/core/lib/iomgr/iomgr_internal.cc \
     src/core/lib/iomgr/iomgr_posix.cc \
     src/core/lib/iomgr/iomgr_posix.cc \
+    src/core/lib/iomgr/iomgr_posix_cfstream.cc \
     src/core/lib/iomgr/iomgr_uv.cc \
     src/core/lib/iomgr/iomgr_uv.cc \
     src/core/lib/iomgr/iomgr_windows.cc \
     src/core/lib/iomgr/iomgr_windows.cc \
     src/core/lib/iomgr/is_epollexclusive_available.cc \
     src/core/lib/iomgr/is_epollexclusive_available.cc \
@@ -4649,6 +4668,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
     src/core/lib/iomgr/socket_utils_windows.cc \
     src/core/lib/iomgr/socket_utils_windows.cc \
     src/core/lib/iomgr/socket_windows.cc \
     src/core/lib/iomgr/socket_windows.cc \
     src/core/lib/iomgr/tcp_client.cc \
     src/core/lib/iomgr/tcp_client.cc \
+    src/core/lib/iomgr/tcp_client_cfstream.cc \
     src/core/lib/iomgr/tcp_client_custom.cc \
     src/core/lib/iomgr/tcp_client_custom.cc \
     src/core/lib/iomgr/tcp_client_posix.cc \
     src/core/lib/iomgr/tcp_client_posix.cc \
     src/core/lib/iomgr/tcp_client_windows.cc \
     src/core/lib/iomgr/tcp_client_windows.cc \
@@ -4870,12 +4890,15 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/http/parser.cc \
     src/core/lib/http/parser.cc \
     src/core/lib/iomgr/buffer_list.cc \
     src/core/lib/iomgr/buffer_list.cc \
     src/core/lib/iomgr/call_combiner.cc \
     src/core/lib/iomgr/call_combiner.cc \
+    src/core/lib/iomgr/cfstream_handle.cc \
     src/core/lib/iomgr/combiner.cc \
     src/core/lib/iomgr/combiner.cc \
     src/core/lib/iomgr/endpoint.cc \
     src/core/lib/iomgr/endpoint.cc \
+    src/core/lib/iomgr/endpoint_cfstream.cc \
     src/core/lib/iomgr/endpoint_pair_posix.cc \
     src/core/lib/iomgr/endpoint_pair_posix.cc \
     src/core/lib/iomgr/endpoint_pair_uv.cc \
     src/core/lib/iomgr/endpoint_pair_uv.cc \
     src/core/lib/iomgr/endpoint_pair_windows.cc \
     src/core/lib/iomgr/endpoint_pair_windows.cc \
     src/core/lib/iomgr/error.cc \
     src/core/lib/iomgr/error.cc \
+    src/core/lib/iomgr/error_cfstream.cc \
     src/core/lib/iomgr/ev_epoll1_linux.cc \
     src/core/lib/iomgr/ev_epoll1_linux.cc \
     src/core/lib/iomgr/ev_epollex_linux.cc \
     src/core/lib/iomgr/ev_epollex_linux.cc \
     src/core/lib/iomgr/ev_poll_posix.cc \
     src/core/lib/iomgr/ev_poll_posix.cc \
@@ -4896,6 +4919,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/iomgr/iomgr_custom.cc \
     src/core/lib/iomgr/iomgr_custom.cc \
     src/core/lib/iomgr/iomgr_internal.cc \
     src/core/lib/iomgr/iomgr_internal.cc \
     src/core/lib/iomgr/iomgr_posix.cc \
     src/core/lib/iomgr/iomgr_posix.cc \
+    src/core/lib/iomgr/iomgr_posix_cfstream.cc \
     src/core/lib/iomgr/iomgr_uv.cc \
     src/core/lib/iomgr/iomgr_uv.cc \
     src/core/lib/iomgr/iomgr_windows.cc \
     src/core/lib/iomgr/iomgr_windows.cc \
     src/core/lib/iomgr/is_epollexclusive_available.cc \
     src/core/lib/iomgr/is_epollexclusive_available.cc \
@@ -4924,6 +4948,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/iomgr/socket_utils_windows.cc \
     src/core/lib/iomgr/socket_utils_windows.cc \
     src/core/lib/iomgr/socket_windows.cc \
     src/core/lib/iomgr/socket_windows.cc \
     src/core/lib/iomgr/tcp_client.cc \
     src/core/lib/iomgr/tcp_client.cc \
+    src/core/lib/iomgr/tcp_client_cfstream.cc \
     src/core/lib/iomgr/tcp_client_custom.cc \
     src/core/lib/iomgr/tcp_client_custom.cc \
     src/core/lib/iomgr/tcp_client_posix.cc \
     src/core/lib/iomgr/tcp_client_posix.cc \
     src/core/lib/iomgr/tcp_client_windows.cc \
     src/core/lib/iomgr/tcp_client_windows.cc \
@@ -5748,12 +5773,15 @@ LIBGRPC++_CRONET_SRC = \
     src/core/lib/http/parser.cc \
     src/core/lib/http/parser.cc \
     src/core/lib/iomgr/buffer_list.cc \
     src/core/lib/iomgr/buffer_list.cc \
     src/core/lib/iomgr/call_combiner.cc \
     src/core/lib/iomgr/call_combiner.cc \
+    src/core/lib/iomgr/cfstream_handle.cc \
     src/core/lib/iomgr/combiner.cc \
     src/core/lib/iomgr/combiner.cc \
     src/core/lib/iomgr/endpoint.cc \
     src/core/lib/iomgr/endpoint.cc \
+    src/core/lib/iomgr/endpoint_cfstream.cc \
     src/core/lib/iomgr/endpoint_pair_posix.cc \
     src/core/lib/iomgr/endpoint_pair_posix.cc \
     src/core/lib/iomgr/endpoint_pair_uv.cc \
     src/core/lib/iomgr/endpoint_pair_uv.cc \
     src/core/lib/iomgr/endpoint_pair_windows.cc \
     src/core/lib/iomgr/endpoint_pair_windows.cc \
     src/core/lib/iomgr/error.cc \
     src/core/lib/iomgr/error.cc \
+    src/core/lib/iomgr/error_cfstream.cc \
     src/core/lib/iomgr/ev_epoll1_linux.cc \
     src/core/lib/iomgr/ev_epoll1_linux.cc \
     src/core/lib/iomgr/ev_epollex_linux.cc \
     src/core/lib/iomgr/ev_epollex_linux.cc \
     src/core/lib/iomgr/ev_poll_posix.cc \
     src/core/lib/iomgr/ev_poll_posix.cc \
@@ -5774,6 +5802,7 @@ LIBGRPC++_CRONET_SRC = \
     src/core/lib/iomgr/iomgr_custom.cc \
     src/core/lib/iomgr/iomgr_custom.cc \
     src/core/lib/iomgr/iomgr_internal.cc \
     src/core/lib/iomgr/iomgr_internal.cc \
     src/core/lib/iomgr/iomgr_posix.cc \
     src/core/lib/iomgr/iomgr_posix.cc \
+    src/core/lib/iomgr/iomgr_posix_cfstream.cc \
     src/core/lib/iomgr/iomgr_uv.cc \
     src/core/lib/iomgr/iomgr_uv.cc \
     src/core/lib/iomgr/iomgr_windows.cc \
     src/core/lib/iomgr/iomgr_windows.cc \
     src/core/lib/iomgr/is_epollexclusive_available.cc \
     src/core/lib/iomgr/is_epollexclusive_available.cc \
@@ -5802,6 +5831,7 @@ LIBGRPC++_CRONET_SRC = \
     src/core/lib/iomgr/socket_utils_windows.cc \
     src/core/lib/iomgr/socket_utils_windows.cc \
     src/core/lib/iomgr/socket_windows.cc \
     src/core/lib/iomgr/socket_windows.cc \
     src/core/lib/iomgr/tcp_client.cc \
     src/core/lib/iomgr/tcp_client.cc \
+    src/core/lib/iomgr/tcp_client_cfstream.cc \
     src/core/lib/iomgr/tcp_client_custom.cc \
     src/core/lib/iomgr/tcp_client_custom.cc \
     src/core/lib/iomgr/tcp_client_posix.cc \
     src/core/lib/iomgr/tcp_client_posix.cc \
     src/core/lib/iomgr/tcp_client_windows.cc \
     src/core/lib/iomgr/tcp_client_windows.cc \
@@ -15637,16 +15667,16 @@ $(BINDIR)/$(CONFIG)/client_crash_test_server: protobuf_dep_error
 
 
 else
 else
 
 
-$(BINDIR)/$(CONFIG)/client_crash_test_server: $(PROTOBUF_DEP) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/client_crash_test_server: $(PROTOBUF_DEP) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_crash_test_server
+	$(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_crash_test_server
 
 
 endif
 endif
 
 
 endif
 endif
 
 
-$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_test_server.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_test_server.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 
 deps_client_crash_test_server: $(CLIENT_CRASH_TEST_SERVER_OBJS:.o=.dep)
 deps_client_crash_test_server: $(CLIENT_CRASH_TEST_SERVER_OBJS:.o=.dep)
 
 
@@ -16384,18 +16414,18 @@ $(BINDIR)/$(CONFIG)/golden_file_test: protobuf_dep_error
 
 
 else
 else
 
 
-$(BINDIR)/$(CONFIG)/golden_file_test: $(PROTOBUF_DEP) $(GOLDEN_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/golden_file_test: $(PROTOBUF_DEP) $(GOLDEN_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(GOLDEN_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/golden_file_test
+	$(Q) $(LDXX) $(LDFLAGS) $(GOLDEN_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/golden_file_test
 
 
 endif
 endif
 
 
 endif
 endif
 
 
-$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/compiler_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/compiler_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 
-$(OBJDIR)/$(CONFIG)/test/cpp/codegen/golden_file_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/codegen/golden_file_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 
 deps_golden_file_test: $(GOLDEN_FILE_TEST_OBJS:.o=.dep)
 deps_golden_file_test: $(GOLDEN_FILE_TEST_OBJS:.o=.dep)
 
 
@@ -18600,16 +18630,16 @@ $(BINDIR)/$(CONFIG)/server_crash_test_client: protobuf_dep_error
 
 
 else
 else
 
 
-$(BINDIR)/$(CONFIG)/server_crash_test_client: $(PROTOBUF_DEP) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/server_crash_test_client: $(PROTOBUF_DEP) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_crash_test_client
+	$(Q) $(LDXX) $(LDFLAGS) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_crash_test_client
 
 
 endif
 endif
 
 
 endif
 endif
 
 
-$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_test_client.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_test_client.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 
 deps_server_crash_test_client: $(SERVER_CRASH_TEST_CLIENT_OBJS:.o=.dep)
 deps_server_crash_test_client: $(SERVER_CRASH_TEST_CLIENT_OBJS:.o=.dep)
 
 

+ 13 - 15
build.yaml

@@ -114,7 +114,6 @@ filegroups:
 - name: gpr_base
 - name: gpr_base
   src:
   src:
   - src/core/lib/gpr/alloc.cc
   - src/core/lib/gpr/alloc.cc
-  - src/core/lib/gpr/arena.cc
   - src/core/lib/gpr/atm.cc
   - src/core/lib/gpr/atm.cc
   - src/core/lib/gpr/cpu_iphone.cc
   - src/core/lib/gpr/cpu_iphone.cc
   - src/core/lib/gpr/cpu_linux.cc
   - src/core/lib/gpr/cpu_linux.cc
@@ -147,6 +146,7 @@ filegroups:
   - src/core/lib/gpr/tmpfile_posix.cc
   - src/core/lib/gpr/tmpfile_posix.cc
   - src/core/lib/gpr/tmpfile_windows.cc
   - src/core/lib/gpr/tmpfile_windows.cc
   - src/core/lib/gpr/wrap_memcpy.cc
   - src/core/lib/gpr/wrap_memcpy.cc
+  - src/core/lib/gprpp/arena.cc
   - src/core/lib/gprpp/fork.cc
   - src/core/lib/gprpp/fork.cc
   - src/core/lib/gprpp/thd_posix.cc
   - src/core/lib/gprpp/thd_posix.cc
   - src/core/lib/gprpp/thd_windows.cc
   - src/core/lib/gprpp/thd_windows.cc
@@ -191,6 +191,7 @@ filegroups:
   - src/core/lib/gpr/tmpfile.h
   - src/core/lib/gpr/tmpfile.h
   - src/core/lib/gpr/useful.h
   - src/core/lib/gpr/useful.h
   - src/core/lib/gprpp/abstract.h
   - src/core/lib/gprpp/abstract.h
+  - src/core/lib/gprpp/arena.h
   - src/core/lib/gprpp/atomic.h
   - src/core/lib/gprpp/atomic.h
   - src/core/lib/gprpp/fork.h
   - src/core/lib/gprpp/fork.h
   - src/core/lib/gprpp/manual_constructor.h
   - src/core/lib/gprpp/manual_constructor.h
@@ -258,12 +259,15 @@ filegroups:
   - src/core/lib/http/parser.cc
   - src/core/lib/http/parser.cc
   - src/core/lib/iomgr/buffer_list.cc
   - src/core/lib/iomgr/buffer_list.cc
   - src/core/lib/iomgr/call_combiner.cc
   - src/core/lib/iomgr/call_combiner.cc
+  - src/core/lib/iomgr/cfstream_handle.cc
   - src/core/lib/iomgr/combiner.cc
   - src/core/lib/iomgr/combiner.cc
   - src/core/lib/iomgr/endpoint.cc
   - src/core/lib/iomgr/endpoint.cc
+  - src/core/lib/iomgr/endpoint_cfstream.cc
   - src/core/lib/iomgr/endpoint_pair_posix.cc
   - src/core/lib/iomgr/endpoint_pair_posix.cc
   - src/core/lib/iomgr/endpoint_pair_uv.cc
   - src/core/lib/iomgr/endpoint_pair_uv.cc
   - src/core/lib/iomgr/endpoint_pair_windows.cc
   - src/core/lib/iomgr/endpoint_pair_windows.cc
   - src/core/lib/iomgr/error.cc
   - src/core/lib/iomgr/error.cc
+  - src/core/lib/iomgr/error_cfstream.cc
   - src/core/lib/iomgr/ev_epoll1_linux.cc
   - src/core/lib/iomgr/ev_epoll1_linux.cc
   - src/core/lib/iomgr/ev_epollex_linux.cc
   - src/core/lib/iomgr/ev_epollex_linux.cc
   - src/core/lib/iomgr/ev_poll_posix.cc
   - src/core/lib/iomgr/ev_poll_posix.cc
@@ -284,6 +288,7 @@ filegroups:
   - src/core/lib/iomgr/iomgr_custom.cc
   - src/core/lib/iomgr/iomgr_custom.cc
   - src/core/lib/iomgr/iomgr_internal.cc
   - src/core/lib/iomgr/iomgr_internal.cc
   - src/core/lib/iomgr/iomgr_posix.cc
   - src/core/lib/iomgr/iomgr_posix.cc
+  - src/core/lib/iomgr/iomgr_posix_cfstream.cc
   - src/core/lib/iomgr/iomgr_uv.cc
   - src/core/lib/iomgr/iomgr_uv.cc
   - src/core/lib/iomgr/iomgr_windows.cc
   - src/core/lib/iomgr/iomgr_windows.cc
   - src/core/lib/iomgr/is_epollexclusive_available.cc
   - src/core/lib/iomgr/is_epollexclusive_available.cc
@@ -312,6 +317,7 @@ filegroups:
   - src/core/lib/iomgr/socket_utils_windows.cc
   - src/core/lib/iomgr/socket_utils_windows.cc
   - src/core/lib/iomgr/socket_windows.cc
   - src/core/lib/iomgr/socket_windows.cc
   - src/core/lib/iomgr/tcp_client.cc
   - src/core/lib/iomgr/tcp_client.cc
+  - src/core/lib/iomgr/tcp_client_cfstream.cc
   - src/core/lib/iomgr/tcp_client_custom.cc
   - src/core/lib/iomgr/tcp_client_custom.cc
   - src/core/lib/iomgr/tcp_client_posix.cc
   - src/core/lib/iomgr/tcp_client_posix.cc
   - src/core/lib/iomgr/tcp_client_windows.cc
   - src/core/lib/iomgr/tcp_client_windows.cc
@@ -439,12 +445,15 @@ filegroups:
   - src/core/lib/iomgr/block_annotate.h
   - src/core/lib/iomgr/block_annotate.h
   - src/core/lib/iomgr/buffer_list.h
   - src/core/lib/iomgr/buffer_list.h
   - src/core/lib/iomgr/call_combiner.h
   - src/core/lib/iomgr/call_combiner.h
+  - src/core/lib/iomgr/cfstream_handle.h
   - src/core/lib/iomgr/closure.h
   - src/core/lib/iomgr/closure.h
   - src/core/lib/iomgr/combiner.h
   - src/core/lib/iomgr/combiner.h
   - src/core/lib/iomgr/dynamic_annotations.h
   - src/core/lib/iomgr/dynamic_annotations.h
   - src/core/lib/iomgr/endpoint.h
   - src/core/lib/iomgr/endpoint.h
+  - src/core/lib/iomgr/endpoint_cfstream.h
   - src/core/lib/iomgr/endpoint_pair.h
   - src/core/lib/iomgr/endpoint_pair.h
   - src/core/lib/iomgr/error.h
   - src/core/lib/iomgr/error.h
+  - src/core/lib/iomgr/error_cfstream.h
   - src/core/lib/iomgr/error_internal.h
   - src/core/lib/iomgr/error_internal.h
   - src/core/lib/iomgr/ev_epoll1_linux.h
   - src/core/lib/iomgr/ev_epoll1_linux.h
   - src/core/lib/iomgr/ev_epollex_linux.h
   - src/core/lib/iomgr/ev_epollex_linux.h
@@ -545,20 +554,6 @@ filegroups:
   uses:
   uses:
   - grpc_codegen
   - grpc_codegen
   - grpc_trace_headers
   - grpc_trace_headers
-- name: grpc_cfstream
-  headers:
-  - src/core/lib/iomgr/cfstream_handle.h
-  - src/core/lib/iomgr/endpoint_cfstream.h
-  - src/core/lib/iomgr/error_cfstream.h
-  src:
-  - src/core/lib/iomgr/cfstream_handle.cc
-  - src/core/lib/iomgr/endpoint_cfstream.cc
-  - src/core/lib/iomgr/error_cfstream.cc
-  - src/core/lib/iomgr/iomgr_posix_cfstream.cc
-  - src/core/lib/iomgr/tcp_client_cfstream.cc
-  uses:
-  - grpc_base_headers
-  - gpr_base_headers
 - name: grpc_client_authority_filter
 - name: grpc_client_authority_filter
   headers:
   headers:
   - src/core/ext/filters/http/client_authority_filter.h
   - src/core/ext/filters/http/client_authority_filter.h
@@ -4522,6 +4517,7 @@ targets:
   src:
   src:
   - test/cpp/end2end/client_crash_test_server.cc
   - test/cpp/end2end/client_crash_test_server.cc
   deps:
   deps:
+  - grpc++_test_config
   - grpc++_test_util
   - grpc++_test_util
   - grpc_test_util
   - grpc_test_util
   - grpc++
   - grpc++
@@ -4734,6 +4730,7 @@ targets:
   - src/proto/grpc/testing/compiler_test.proto
   - src/proto/grpc/testing/compiler_test.proto
   - test/cpp/codegen/golden_file_test.cc
   - test/cpp/codegen/golden_file_test.cc
   deps:
   deps:
+  - grpc++_test_config
   - grpc++
   - grpc++
   - grpc
   - grpc
   - gpr
   - gpr
@@ -5449,6 +5446,7 @@ targets:
   src:
   src:
   - test/cpp/end2end/server_crash_test_client.cc
   - test/cpp/end2end/server_crash_test_client.cc
   deps:
   deps:
+  - grpc++_test_config
   - grpc++_test_util
   - grpc++_test_util
   - grpc_test_util
   - grpc_test_util
   - grpc++
   - grpc++

+ 6 - 1
config.m4

@@ -45,7 +45,6 @@ if test "$PHP_GRPC" != "no"; then
     third_party/address_sorting/address_sorting_posix.c \
     third_party/address_sorting/address_sorting_posix.c \
     third_party/address_sorting/address_sorting_windows.c \
     third_party/address_sorting/address_sorting_windows.c \
     src/core/lib/gpr/alloc.cc \
     src/core/lib/gpr/alloc.cc \
-    src/core/lib/gpr/arena.cc \
     src/core/lib/gpr/atm.cc \
     src/core/lib/gpr/atm.cc \
     src/core/lib/gpr/cpu_iphone.cc \
     src/core/lib/gpr/cpu_iphone.cc \
     src/core/lib/gpr/cpu_linux.cc \
     src/core/lib/gpr/cpu_linux.cc \
@@ -78,6 +77,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/gpr/tmpfile_posix.cc \
     src/core/lib/gpr/tmpfile_posix.cc \
     src/core/lib/gpr/tmpfile_windows.cc \
     src/core/lib/gpr/tmpfile_windows.cc \
     src/core/lib/gpr/wrap_memcpy.cc \
     src/core/lib/gpr/wrap_memcpy.cc \
+    src/core/lib/gprpp/arena.cc \
     src/core/lib/gprpp/fork.cc \
     src/core/lib/gprpp/fork.cc \
     src/core/lib/gprpp/thd_posix.cc \
     src/core/lib/gprpp/thd_posix.cc \
     src/core/lib/gprpp/thd_windows.cc \
     src/core/lib/gprpp/thd_windows.cc \
@@ -110,12 +110,15 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/http/parser.cc \
     src/core/lib/http/parser.cc \
     src/core/lib/iomgr/buffer_list.cc \
     src/core/lib/iomgr/buffer_list.cc \
     src/core/lib/iomgr/call_combiner.cc \
     src/core/lib/iomgr/call_combiner.cc \
+    src/core/lib/iomgr/cfstream_handle.cc \
     src/core/lib/iomgr/combiner.cc \
     src/core/lib/iomgr/combiner.cc \
     src/core/lib/iomgr/endpoint.cc \
     src/core/lib/iomgr/endpoint.cc \
+    src/core/lib/iomgr/endpoint_cfstream.cc \
     src/core/lib/iomgr/endpoint_pair_posix.cc \
     src/core/lib/iomgr/endpoint_pair_posix.cc \
     src/core/lib/iomgr/endpoint_pair_uv.cc \
     src/core/lib/iomgr/endpoint_pair_uv.cc \
     src/core/lib/iomgr/endpoint_pair_windows.cc \
     src/core/lib/iomgr/endpoint_pair_windows.cc \
     src/core/lib/iomgr/error.cc \
     src/core/lib/iomgr/error.cc \
+    src/core/lib/iomgr/error_cfstream.cc \
     src/core/lib/iomgr/ev_epoll1_linux.cc \
     src/core/lib/iomgr/ev_epoll1_linux.cc \
     src/core/lib/iomgr/ev_epollex_linux.cc \
     src/core/lib/iomgr/ev_epollex_linux.cc \
     src/core/lib/iomgr/ev_poll_posix.cc \
     src/core/lib/iomgr/ev_poll_posix.cc \
@@ -136,6 +139,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/iomgr/iomgr_custom.cc \
     src/core/lib/iomgr/iomgr_custom.cc \
     src/core/lib/iomgr/iomgr_internal.cc \
     src/core/lib/iomgr/iomgr_internal.cc \
     src/core/lib/iomgr/iomgr_posix.cc \
     src/core/lib/iomgr/iomgr_posix.cc \
+    src/core/lib/iomgr/iomgr_posix_cfstream.cc \
     src/core/lib/iomgr/iomgr_uv.cc \
     src/core/lib/iomgr/iomgr_uv.cc \
     src/core/lib/iomgr/iomgr_windows.cc \
     src/core/lib/iomgr/iomgr_windows.cc \
     src/core/lib/iomgr/is_epollexclusive_available.cc \
     src/core/lib/iomgr/is_epollexclusive_available.cc \
@@ -164,6 +168,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/iomgr/socket_utils_windows.cc \
     src/core/lib/iomgr/socket_utils_windows.cc \
     src/core/lib/iomgr/socket_windows.cc \
     src/core/lib/iomgr/socket_windows.cc \
     src/core/lib/iomgr/tcp_client.cc \
     src/core/lib/iomgr/tcp_client.cc \
+    src/core/lib/iomgr/tcp_client_cfstream.cc \
     src/core/lib/iomgr/tcp_client_custom.cc \
     src/core/lib/iomgr/tcp_client_custom.cc \
     src/core/lib/iomgr/tcp_client_posix.cc \
     src/core/lib/iomgr/tcp_client_posix.cc \
     src/core/lib/iomgr/tcp_client_windows.cc \
     src/core/lib/iomgr/tcp_client_windows.cc \

+ 6 - 1
config.w32

@@ -20,7 +20,6 @@ if (PHP_GRPC != "no") {
     "third_party\\address_sorting\\address_sorting_posix.c " +
     "third_party\\address_sorting\\address_sorting_posix.c " +
     "third_party\\address_sorting\\address_sorting_windows.c " +
     "third_party\\address_sorting\\address_sorting_windows.c " +
     "src\\core\\lib\\gpr\\alloc.cc " +
     "src\\core\\lib\\gpr\\alloc.cc " +
-    "src\\core\\lib\\gpr\\arena.cc " +
     "src\\core\\lib\\gpr\\atm.cc " +
     "src\\core\\lib\\gpr\\atm.cc " +
     "src\\core\\lib\\gpr\\cpu_iphone.cc " +
     "src\\core\\lib\\gpr\\cpu_iphone.cc " +
     "src\\core\\lib\\gpr\\cpu_linux.cc " +
     "src\\core\\lib\\gpr\\cpu_linux.cc " +
@@ -53,6 +52,7 @@ if (PHP_GRPC != "no") {
     "src\\core\\lib\\gpr\\tmpfile_posix.cc " +
     "src\\core\\lib\\gpr\\tmpfile_posix.cc " +
     "src\\core\\lib\\gpr\\tmpfile_windows.cc " +
     "src\\core\\lib\\gpr\\tmpfile_windows.cc " +
     "src\\core\\lib\\gpr\\wrap_memcpy.cc " +
     "src\\core\\lib\\gpr\\wrap_memcpy.cc " +
+    "src\\core\\lib\\gprpp\\arena.cc " +
     "src\\core\\lib\\gprpp\\fork.cc " +
     "src\\core\\lib\\gprpp\\fork.cc " +
     "src\\core\\lib\\gprpp\\thd_posix.cc " +
     "src\\core\\lib\\gprpp\\thd_posix.cc " +
     "src\\core\\lib\\gprpp\\thd_windows.cc " +
     "src\\core\\lib\\gprpp\\thd_windows.cc " +
@@ -85,12 +85,15 @@ if (PHP_GRPC != "no") {
     "src\\core\\lib\\http\\parser.cc " +
     "src\\core\\lib\\http\\parser.cc " +
     "src\\core\\lib\\iomgr\\buffer_list.cc " +
     "src\\core\\lib\\iomgr\\buffer_list.cc " +
     "src\\core\\lib\\iomgr\\call_combiner.cc " +
     "src\\core\\lib\\iomgr\\call_combiner.cc " +
+    "src\\core\\lib\\iomgr\\cfstream_handle.cc " +
     "src\\core\\lib\\iomgr\\combiner.cc " +
     "src\\core\\lib\\iomgr\\combiner.cc " +
     "src\\core\\lib\\iomgr\\endpoint.cc " +
     "src\\core\\lib\\iomgr\\endpoint.cc " +
+    "src\\core\\lib\\iomgr\\endpoint_cfstream.cc " +
     "src\\core\\lib\\iomgr\\endpoint_pair_posix.cc " +
     "src\\core\\lib\\iomgr\\endpoint_pair_posix.cc " +
     "src\\core\\lib\\iomgr\\endpoint_pair_uv.cc " +
     "src\\core\\lib\\iomgr\\endpoint_pair_uv.cc " +
     "src\\core\\lib\\iomgr\\endpoint_pair_windows.cc " +
     "src\\core\\lib\\iomgr\\endpoint_pair_windows.cc " +
     "src\\core\\lib\\iomgr\\error.cc " +
     "src\\core\\lib\\iomgr\\error.cc " +
+    "src\\core\\lib\\iomgr\\error_cfstream.cc " +
     "src\\core\\lib\\iomgr\\ev_epoll1_linux.cc " +
     "src\\core\\lib\\iomgr\\ev_epoll1_linux.cc " +
     "src\\core\\lib\\iomgr\\ev_epollex_linux.cc " +
     "src\\core\\lib\\iomgr\\ev_epollex_linux.cc " +
     "src\\core\\lib\\iomgr\\ev_poll_posix.cc " +
     "src\\core\\lib\\iomgr\\ev_poll_posix.cc " +
@@ -111,6 +114,7 @@ if (PHP_GRPC != "no") {
     "src\\core\\lib\\iomgr\\iomgr_custom.cc " +
     "src\\core\\lib\\iomgr\\iomgr_custom.cc " +
     "src\\core\\lib\\iomgr\\iomgr_internal.cc " +
     "src\\core\\lib\\iomgr\\iomgr_internal.cc " +
     "src\\core\\lib\\iomgr\\iomgr_posix.cc " +
     "src\\core\\lib\\iomgr\\iomgr_posix.cc " +
+    "src\\core\\lib\\iomgr\\iomgr_posix_cfstream.cc " +
     "src\\core\\lib\\iomgr\\iomgr_uv.cc " +
     "src\\core\\lib\\iomgr\\iomgr_uv.cc " +
     "src\\core\\lib\\iomgr\\iomgr_windows.cc " +
     "src\\core\\lib\\iomgr\\iomgr_windows.cc " +
     "src\\core\\lib\\iomgr\\is_epollexclusive_available.cc " +
     "src\\core\\lib\\iomgr\\is_epollexclusive_available.cc " +
@@ -139,6 +143,7 @@ if (PHP_GRPC != "no") {
     "src\\core\\lib\\iomgr\\socket_utils_windows.cc " +
     "src\\core\\lib\\iomgr\\socket_utils_windows.cc " +
     "src\\core\\lib\\iomgr\\socket_windows.cc " +
     "src\\core\\lib\\iomgr\\socket_windows.cc " +
     "src\\core\\lib\\iomgr\\tcp_client.cc " +
     "src\\core\\lib\\iomgr\\tcp_client.cc " +
+    "src\\core\\lib\\iomgr\\tcp_client_cfstream.cc " +
     "src\\core\\lib\\iomgr\\tcp_client_custom.cc " +
     "src\\core\\lib\\iomgr\\tcp_client_custom.cc " +
     "src\\core\\lib\\iomgr\\tcp_client_posix.cc " +
     "src\\core\\lib\\iomgr\\tcp_client_posix.cc " +
     "src\\core\\lib\\iomgr\\tcp_client_windows.cc " +
     "src\\core\\lib\\iomgr\\tcp_client_windows.cc " +

+ 8 - 0
gRPC-C++.podspec

@@ -264,6 +264,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/gpr/tmpfile.h',
                       'src/core/lib/gpr/tmpfile.h',
                       'src/core/lib/gpr/useful.h',
                       'src/core/lib/gpr/useful.h',
                       'src/core/lib/gprpp/abstract.h',
                       'src/core/lib/gprpp/abstract.h',
+                      'src/core/lib/gprpp/arena.h',
                       'src/core/lib/gprpp/atomic.h',
                       'src/core/lib/gprpp/atomic.h',
                       'src/core/lib/gprpp/fork.h',
                       'src/core/lib/gprpp/fork.h',
                       'src/core/lib/gprpp/manual_constructor.h',
                       'src/core/lib/gprpp/manual_constructor.h',
@@ -433,12 +434,15 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/block_annotate.h',
                       'src/core/lib/iomgr/block_annotate.h',
                       'src/core/lib/iomgr/buffer_list.h',
                       'src/core/lib/iomgr/buffer_list.h',
                       'src/core/lib/iomgr/call_combiner.h',
                       'src/core/lib/iomgr/call_combiner.h',
+                      'src/core/lib/iomgr/cfstream_handle.h',
                       'src/core/lib/iomgr/closure.h',
                       'src/core/lib/iomgr/closure.h',
                       'src/core/lib/iomgr/combiner.h',
                       'src/core/lib/iomgr/combiner.h',
                       'src/core/lib/iomgr/dynamic_annotations.h',
                       'src/core/lib/iomgr/dynamic_annotations.h',
                       'src/core/lib/iomgr/endpoint.h',
                       'src/core/lib/iomgr/endpoint.h',
+                      'src/core/lib/iomgr/endpoint_cfstream.h',
                       'src/core/lib/iomgr/endpoint_pair.h',
                       'src/core/lib/iomgr/endpoint_pair.h',
                       'src/core/lib/iomgr/error.h',
                       'src/core/lib/iomgr/error.h',
+                      'src/core/lib/iomgr/error_cfstream.h',
                       'src/core/lib/iomgr/error_internal.h',
                       'src/core/lib/iomgr/error_internal.h',
                       'src/core/lib/iomgr/ev_epoll1_linux.h',
                       'src/core/lib/iomgr/ev_epoll1_linux.h',
                       'src/core/lib/iomgr/ev_epollex_linux.h',
                       'src/core/lib/iomgr/ev_epollex_linux.h',
@@ -582,6 +586,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/gpr/tmpfile.h',
                               'src/core/lib/gpr/tmpfile.h',
                               'src/core/lib/gpr/useful.h',
                               'src/core/lib/gpr/useful.h',
                               'src/core/lib/gprpp/abstract.h',
                               'src/core/lib/gprpp/abstract.h',
+                              'src/core/lib/gprpp/arena.h',
                               'src/core/lib/gprpp/atomic.h',
                               'src/core/lib/gprpp/atomic.h',
                               'src/core/lib/gprpp/fork.h',
                               'src/core/lib/gprpp/fork.h',
                               'src/core/lib/gprpp/manual_constructor.h',
                               'src/core/lib/gprpp/manual_constructor.h',
@@ -626,12 +631,15 @@ Pod::Spec.new do |s|
                               'src/core/lib/iomgr/block_annotate.h',
                               'src/core/lib/iomgr/block_annotate.h',
                               'src/core/lib/iomgr/buffer_list.h',
                               'src/core/lib/iomgr/buffer_list.h',
                               'src/core/lib/iomgr/call_combiner.h',
                               'src/core/lib/iomgr/call_combiner.h',
+                              'src/core/lib/iomgr/cfstream_handle.h',
                               'src/core/lib/iomgr/closure.h',
                               'src/core/lib/iomgr/closure.h',
                               'src/core/lib/iomgr/combiner.h',
                               'src/core/lib/iomgr/combiner.h',
                               'src/core/lib/iomgr/dynamic_annotations.h',
                               'src/core/lib/iomgr/dynamic_annotations.h',
                               'src/core/lib/iomgr/endpoint.h',
                               'src/core/lib/iomgr/endpoint.h',
+                              'src/core/lib/iomgr/endpoint_cfstream.h',
                               'src/core/lib/iomgr/endpoint_pair.h',
                               'src/core/lib/iomgr/endpoint_pair.h',
                               'src/core/lib/iomgr/error.h',
                               'src/core/lib/iomgr/error.h',
+                              'src/core/lib/iomgr/error_cfstream.h',
                               'src/core/lib/iomgr/error_internal.h',
                               'src/core/lib/iomgr/error_internal.h',
                               'src/core/lib/iomgr/ev_epoll1_linux.h',
                               'src/core/lib/iomgr/ev_epoll1_linux.h',
                               'src/core/lib/iomgr/ev_epollex_linux.h',
                               'src/core/lib/iomgr/ev_epollex_linux.h',

+ 16 - 14
gRPC-Core.podspec

@@ -205,6 +205,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/gpr/tmpfile.h',
                       'src/core/lib/gpr/tmpfile.h',
                       'src/core/lib/gpr/useful.h',
                       'src/core/lib/gpr/useful.h',
                       'src/core/lib/gprpp/abstract.h',
                       'src/core/lib/gprpp/abstract.h',
+                      'src/core/lib/gprpp/arena.h',
                       'src/core/lib/gprpp/atomic.h',
                       'src/core/lib/gprpp/atomic.h',
                       'src/core/lib/gprpp/fork.h',
                       'src/core/lib/gprpp/fork.h',
                       'src/core/lib/gprpp/manual_constructor.h',
                       'src/core/lib/gprpp/manual_constructor.h',
@@ -215,7 +216,6 @@ Pod::Spec.new do |s|
                       'src/core/lib/gprpp/thd.h',
                       'src/core/lib/gprpp/thd.h',
                       'src/core/lib/profiling/timers.h',
                       'src/core/lib/profiling/timers.h',
                       'src/core/lib/gpr/alloc.cc',
                       'src/core/lib/gpr/alloc.cc',
-                      'src/core/lib/gpr/arena.cc',
                       'src/core/lib/gpr/atm.cc',
                       'src/core/lib/gpr/atm.cc',
                       'src/core/lib/gpr/cpu_iphone.cc',
                       'src/core/lib/gpr/cpu_iphone.cc',
                       'src/core/lib/gpr/cpu_linux.cc',
                       'src/core/lib/gpr/cpu_linux.cc',
@@ -248,6 +248,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/gpr/tmpfile_posix.cc',
                       'src/core/lib/gpr/tmpfile_posix.cc',
                       'src/core/lib/gpr/tmpfile_windows.cc',
                       'src/core/lib/gpr/tmpfile_windows.cc',
                       'src/core/lib/gpr/wrap_memcpy.cc',
                       'src/core/lib/gpr/wrap_memcpy.cc',
+                      'src/core/lib/gprpp/arena.cc',
                       'src/core/lib/gprpp/fork.cc',
                       'src/core/lib/gprpp/fork.cc',
                       'src/core/lib/gprpp/thd_posix.cc',
                       'src/core/lib/gprpp/thd_posix.cc',
                       'src/core/lib/gprpp/thd_windows.cc',
                       'src/core/lib/gprpp/thd_windows.cc',
@@ -413,12 +414,15 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/block_annotate.h',
                       'src/core/lib/iomgr/block_annotate.h',
                       'src/core/lib/iomgr/buffer_list.h',
                       'src/core/lib/iomgr/buffer_list.h',
                       'src/core/lib/iomgr/call_combiner.h',
                       'src/core/lib/iomgr/call_combiner.h',
+                      'src/core/lib/iomgr/cfstream_handle.h',
                       'src/core/lib/iomgr/closure.h',
                       'src/core/lib/iomgr/closure.h',
                       'src/core/lib/iomgr/combiner.h',
                       'src/core/lib/iomgr/combiner.h',
                       'src/core/lib/iomgr/dynamic_annotations.h',
                       'src/core/lib/iomgr/dynamic_annotations.h',
                       'src/core/lib/iomgr/endpoint.h',
                       'src/core/lib/iomgr/endpoint.h',
+                      'src/core/lib/iomgr/endpoint_cfstream.h',
                       'src/core/lib/iomgr/endpoint_pair.h',
                       'src/core/lib/iomgr/endpoint_pair.h',
                       'src/core/lib/iomgr/error.h',
                       'src/core/lib/iomgr/error.h',
+                      'src/core/lib/iomgr/error_cfstream.h',
                       'src/core/lib/iomgr/error_internal.h',
                       'src/core/lib/iomgr/error_internal.h',
                       'src/core/lib/iomgr/ev_epoll1_linux.h',
                       'src/core/lib/iomgr/ev_epoll1_linux.h',
                       'src/core/lib/iomgr/ev_epollex_linux.h',
                       'src/core/lib/iomgr/ev_epollex_linux.h',
@@ -561,12 +565,15 @@ Pod::Spec.new do |s|
                       'src/core/lib/http/parser.cc',
                       'src/core/lib/http/parser.cc',
                       'src/core/lib/iomgr/buffer_list.cc',
                       'src/core/lib/iomgr/buffer_list.cc',
                       'src/core/lib/iomgr/call_combiner.cc',
                       'src/core/lib/iomgr/call_combiner.cc',
+                      'src/core/lib/iomgr/cfstream_handle.cc',
                       'src/core/lib/iomgr/combiner.cc',
                       'src/core/lib/iomgr/combiner.cc',
                       'src/core/lib/iomgr/endpoint.cc',
                       'src/core/lib/iomgr/endpoint.cc',
+                      'src/core/lib/iomgr/endpoint_cfstream.cc',
                       'src/core/lib/iomgr/endpoint_pair_posix.cc',
                       'src/core/lib/iomgr/endpoint_pair_posix.cc',
                       'src/core/lib/iomgr/endpoint_pair_uv.cc',
                       'src/core/lib/iomgr/endpoint_pair_uv.cc',
                       'src/core/lib/iomgr/endpoint_pair_windows.cc',
                       'src/core/lib/iomgr/endpoint_pair_windows.cc',
                       'src/core/lib/iomgr/error.cc',
                       'src/core/lib/iomgr/error.cc',
+                      'src/core/lib/iomgr/error_cfstream.cc',
                       'src/core/lib/iomgr/ev_epoll1_linux.cc',
                       'src/core/lib/iomgr/ev_epoll1_linux.cc',
                       'src/core/lib/iomgr/ev_epollex_linux.cc',
                       'src/core/lib/iomgr/ev_epollex_linux.cc',
                       'src/core/lib/iomgr/ev_poll_posix.cc',
                       'src/core/lib/iomgr/ev_poll_posix.cc',
@@ -587,6 +594,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/iomgr_custom.cc',
                       'src/core/lib/iomgr/iomgr_custom.cc',
                       'src/core/lib/iomgr/iomgr_internal.cc',
                       'src/core/lib/iomgr/iomgr_internal.cc',
                       'src/core/lib/iomgr/iomgr_posix.cc',
                       'src/core/lib/iomgr/iomgr_posix.cc',
+                      'src/core/lib/iomgr/iomgr_posix_cfstream.cc',
                       'src/core/lib/iomgr/iomgr_uv.cc',
                       'src/core/lib/iomgr/iomgr_uv.cc',
                       'src/core/lib/iomgr/iomgr_windows.cc',
                       'src/core/lib/iomgr/iomgr_windows.cc',
                       'src/core/lib/iomgr/is_epollexclusive_available.cc',
                       'src/core/lib/iomgr/is_epollexclusive_available.cc',
@@ -615,6 +623,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/iomgr/socket_utils_windows.cc',
                       'src/core/lib/iomgr/socket_utils_windows.cc',
                       'src/core/lib/iomgr/socket_windows.cc',
                       'src/core/lib/iomgr/socket_windows.cc',
                       'src/core/lib/iomgr/tcp_client.cc',
                       'src/core/lib/iomgr/tcp_client.cc',
+                      'src/core/lib/iomgr/tcp_client_cfstream.cc',
                       'src/core/lib/iomgr/tcp_client_custom.cc',
                       'src/core/lib/iomgr/tcp_client_custom.cc',
                       'src/core/lib/iomgr/tcp_client_posix.cc',
                       'src/core/lib/iomgr/tcp_client_posix.cc',
                       'src/core/lib/iomgr/tcp_client_windows.cc',
                       'src/core/lib/iomgr/tcp_client_windows.cc',
@@ -859,15 +868,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/http/client_authority_filter.cc',
                       'src/core/ext/filters/http/client_authority_filter.cc',
                       'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc',
                       'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc',
                       'src/core/ext/filters/workarounds/workaround_utils.cc',
                       'src/core/ext/filters/workarounds/workaround_utils.cc',
-                      'src/core/plugin_registry/grpc_plugin_registry.cc',
-                      'src/core/lib/iomgr/cfstream_handle.cc',
-                      'src/core/lib/iomgr/endpoint_cfstream.cc',
-                      'src/core/lib/iomgr/error_cfstream.cc',
-                      'src/core/lib/iomgr/iomgr_posix_cfstream.cc',
-                      'src/core/lib/iomgr/tcp_client_cfstream.cc',
-                      'src/core/lib/iomgr/cfstream_handle.h',
-                      'src/core/lib/iomgr/endpoint_cfstream.h',
-                      'src/core/lib/iomgr/error_cfstream.h'
+                      'src/core/plugin_registry/grpc_plugin_registry.cc'
 
 
     ss.private_header_files = 'src/core/lib/gpr/alloc.h',
     ss.private_header_files = 'src/core/lib/gpr/alloc.h',
                               'src/core/lib/gpr/arena.h',
                               'src/core/lib/gpr/arena.h',
@@ -886,6 +887,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/gpr/tmpfile.h',
                               'src/core/lib/gpr/tmpfile.h',
                               'src/core/lib/gpr/useful.h',
                               'src/core/lib/gpr/useful.h',
                               'src/core/lib/gprpp/abstract.h',
                               'src/core/lib/gprpp/abstract.h',
+                              'src/core/lib/gprpp/arena.h',
                               'src/core/lib/gprpp/atomic.h',
                               'src/core/lib/gprpp/atomic.h',
                               'src/core/lib/gprpp/fork.h',
                               'src/core/lib/gprpp/fork.h',
                               'src/core/lib/gprpp/manual_constructor.h',
                               'src/core/lib/gprpp/manual_constructor.h',
@@ -1055,12 +1057,15 @@ Pod::Spec.new do |s|
                               'src/core/lib/iomgr/block_annotate.h',
                               'src/core/lib/iomgr/block_annotate.h',
                               'src/core/lib/iomgr/buffer_list.h',
                               'src/core/lib/iomgr/buffer_list.h',
                               'src/core/lib/iomgr/call_combiner.h',
                               'src/core/lib/iomgr/call_combiner.h',
+                              'src/core/lib/iomgr/cfstream_handle.h',
                               'src/core/lib/iomgr/closure.h',
                               'src/core/lib/iomgr/closure.h',
                               'src/core/lib/iomgr/combiner.h',
                               'src/core/lib/iomgr/combiner.h',
                               'src/core/lib/iomgr/dynamic_annotations.h',
                               'src/core/lib/iomgr/dynamic_annotations.h',
                               'src/core/lib/iomgr/endpoint.h',
                               'src/core/lib/iomgr/endpoint.h',
+                              'src/core/lib/iomgr/endpoint_cfstream.h',
                               'src/core/lib/iomgr/endpoint_pair.h',
                               'src/core/lib/iomgr/endpoint_pair.h',
                               'src/core/lib/iomgr/error.h',
                               'src/core/lib/iomgr/error.h',
+                              'src/core/lib/iomgr/error_cfstream.h',
                               'src/core/lib/iomgr/error_internal.h',
                               'src/core/lib/iomgr/error_internal.h',
                               'src/core/lib/iomgr/ev_epoll1_linux.h',
                               'src/core/lib/iomgr/ev_epoll1_linux.h',
                               'src/core/lib/iomgr/ev_epollex_linux.h',
                               'src/core/lib/iomgr/ev_epollex_linux.h',
@@ -1175,10 +1180,7 @@ Pod::Spec.new do |s|
                               'src/core/ext/filters/message_size/message_size_filter.h',
                               'src/core/ext/filters/message_size/message_size_filter.h',
                               'src/core/ext/filters/http/client_authority_filter.h',
                               'src/core/ext/filters/http/client_authority_filter.h',
                               'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h',
                               'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h',
-                              'src/core/ext/filters/workarounds/workaround_utils.h',
-                              'src/core/lib/iomgr/cfstream_handle.h',
-                              'src/core/lib/iomgr/endpoint_cfstream.h',
-                              'src/core/lib/iomgr/error_cfstream.h'
+                              'src/core/ext/filters/workarounds/workaround_utils.h'
   end
   end
 
 
   # CFStream is now default. Leaving this subspec only for compatibility purpose.
   # CFStream is now default. Leaving this subspec only for compatibility purpose.

+ 10 - 1
grpc.gemspec

@@ -99,6 +99,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/gpr/tmpfile.h )
   s.files += %w( src/core/lib/gpr/tmpfile.h )
   s.files += %w( src/core/lib/gpr/useful.h )
   s.files += %w( src/core/lib/gpr/useful.h )
   s.files += %w( src/core/lib/gprpp/abstract.h )
   s.files += %w( src/core/lib/gprpp/abstract.h )
+  s.files += %w( src/core/lib/gprpp/arena.h )
   s.files += %w( src/core/lib/gprpp/atomic.h )
   s.files += %w( src/core/lib/gprpp/atomic.h )
   s.files += %w( src/core/lib/gprpp/fork.h )
   s.files += %w( src/core/lib/gprpp/fork.h )
   s.files += %w( src/core/lib/gprpp/manual_constructor.h )
   s.files += %w( src/core/lib/gprpp/manual_constructor.h )
@@ -109,7 +110,6 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/gprpp/thd.h )
   s.files += %w( src/core/lib/gprpp/thd.h )
   s.files += %w( src/core/lib/profiling/timers.h )
   s.files += %w( src/core/lib/profiling/timers.h )
   s.files += %w( src/core/lib/gpr/alloc.cc )
   s.files += %w( src/core/lib/gpr/alloc.cc )
-  s.files += %w( src/core/lib/gpr/arena.cc )
   s.files += %w( src/core/lib/gpr/atm.cc )
   s.files += %w( src/core/lib/gpr/atm.cc )
   s.files += %w( src/core/lib/gpr/cpu_iphone.cc )
   s.files += %w( src/core/lib/gpr/cpu_iphone.cc )
   s.files += %w( src/core/lib/gpr/cpu_linux.cc )
   s.files += %w( src/core/lib/gpr/cpu_linux.cc )
@@ -142,6 +142,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/gpr/tmpfile_posix.cc )
   s.files += %w( src/core/lib/gpr/tmpfile_posix.cc )
   s.files += %w( src/core/lib/gpr/tmpfile_windows.cc )
   s.files += %w( src/core/lib/gpr/tmpfile_windows.cc )
   s.files += %w( src/core/lib/gpr/wrap_memcpy.cc )
   s.files += %w( src/core/lib/gpr/wrap_memcpy.cc )
+  s.files += %w( src/core/lib/gprpp/arena.cc )
   s.files += %w( src/core/lib/gprpp/fork.cc )
   s.files += %w( src/core/lib/gprpp/fork.cc )
   s.files += %w( src/core/lib/gprpp/thd_posix.cc )
   s.files += %w( src/core/lib/gprpp/thd_posix.cc )
   s.files += %w( src/core/lib/gprpp/thd_windows.cc )
   s.files += %w( src/core/lib/gprpp/thd_windows.cc )
@@ -347,12 +348,15 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/iomgr/block_annotate.h )
   s.files += %w( src/core/lib/iomgr/block_annotate.h )
   s.files += %w( src/core/lib/iomgr/buffer_list.h )
   s.files += %w( src/core/lib/iomgr/buffer_list.h )
   s.files += %w( src/core/lib/iomgr/call_combiner.h )
   s.files += %w( src/core/lib/iomgr/call_combiner.h )
+  s.files += %w( src/core/lib/iomgr/cfstream_handle.h )
   s.files += %w( src/core/lib/iomgr/closure.h )
   s.files += %w( src/core/lib/iomgr/closure.h )
   s.files += %w( src/core/lib/iomgr/combiner.h )
   s.files += %w( src/core/lib/iomgr/combiner.h )
   s.files += %w( src/core/lib/iomgr/dynamic_annotations.h )
   s.files += %w( src/core/lib/iomgr/dynamic_annotations.h )
   s.files += %w( src/core/lib/iomgr/endpoint.h )
   s.files += %w( src/core/lib/iomgr/endpoint.h )
+  s.files += %w( src/core/lib/iomgr/endpoint_cfstream.h )
   s.files += %w( src/core/lib/iomgr/endpoint_pair.h )
   s.files += %w( src/core/lib/iomgr/endpoint_pair.h )
   s.files += %w( src/core/lib/iomgr/error.h )
   s.files += %w( src/core/lib/iomgr/error.h )
+  s.files += %w( src/core/lib/iomgr/error_cfstream.h )
   s.files += %w( src/core/lib/iomgr/error_internal.h )
   s.files += %w( src/core/lib/iomgr/error_internal.h )
   s.files += %w( src/core/lib/iomgr/ev_epoll1_linux.h )
   s.files += %w( src/core/lib/iomgr/ev_epoll1_linux.h )
   s.files += %w( src/core/lib/iomgr/ev_epollex_linux.h )
   s.files += %w( src/core/lib/iomgr/ev_epollex_linux.h )
@@ -495,12 +499,15 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/http/parser.cc )
   s.files += %w( src/core/lib/http/parser.cc )
   s.files += %w( src/core/lib/iomgr/buffer_list.cc )
   s.files += %w( src/core/lib/iomgr/buffer_list.cc )
   s.files += %w( src/core/lib/iomgr/call_combiner.cc )
   s.files += %w( src/core/lib/iomgr/call_combiner.cc )
+  s.files += %w( src/core/lib/iomgr/cfstream_handle.cc )
   s.files += %w( src/core/lib/iomgr/combiner.cc )
   s.files += %w( src/core/lib/iomgr/combiner.cc )
   s.files += %w( src/core/lib/iomgr/endpoint.cc )
   s.files += %w( src/core/lib/iomgr/endpoint.cc )
+  s.files += %w( src/core/lib/iomgr/endpoint_cfstream.cc )
   s.files += %w( src/core/lib/iomgr/endpoint_pair_posix.cc )
   s.files += %w( src/core/lib/iomgr/endpoint_pair_posix.cc )
   s.files += %w( src/core/lib/iomgr/endpoint_pair_uv.cc )
   s.files += %w( src/core/lib/iomgr/endpoint_pair_uv.cc )
   s.files += %w( src/core/lib/iomgr/endpoint_pair_windows.cc )
   s.files += %w( src/core/lib/iomgr/endpoint_pair_windows.cc )
   s.files += %w( src/core/lib/iomgr/error.cc )
   s.files += %w( src/core/lib/iomgr/error.cc )
+  s.files += %w( src/core/lib/iomgr/error_cfstream.cc )
   s.files += %w( src/core/lib/iomgr/ev_epoll1_linux.cc )
   s.files += %w( src/core/lib/iomgr/ev_epoll1_linux.cc )
   s.files += %w( src/core/lib/iomgr/ev_epollex_linux.cc )
   s.files += %w( src/core/lib/iomgr/ev_epollex_linux.cc )
   s.files += %w( src/core/lib/iomgr/ev_poll_posix.cc )
   s.files += %w( src/core/lib/iomgr/ev_poll_posix.cc )
@@ -521,6 +528,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/iomgr/iomgr_custom.cc )
   s.files += %w( src/core/lib/iomgr/iomgr_custom.cc )
   s.files += %w( src/core/lib/iomgr/iomgr_internal.cc )
   s.files += %w( src/core/lib/iomgr/iomgr_internal.cc )
   s.files += %w( src/core/lib/iomgr/iomgr_posix.cc )
   s.files += %w( src/core/lib/iomgr/iomgr_posix.cc )
+  s.files += %w( src/core/lib/iomgr/iomgr_posix_cfstream.cc )
   s.files += %w( src/core/lib/iomgr/iomgr_uv.cc )
   s.files += %w( src/core/lib/iomgr/iomgr_uv.cc )
   s.files += %w( src/core/lib/iomgr/iomgr_windows.cc )
   s.files += %w( src/core/lib/iomgr/iomgr_windows.cc )
   s.files += %w( src/core/lib/iomgr/is_epollexclusive_available.cc )
   s.files += %w( src/core/lib/iomgr/is_epollexclusive_available.cc )
@@ -549,6 +557,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/iomgr/socket_utils_windows.cc )
   s.files += %w( src/core/lib/iomgr/socket_utils_windows.cc )
   s.files += %w( src/core/lib/iomgr/socket_windows.cc )
   s.files += %w( src/core/lib/iomgr/socket_windows.cc )
   s.files += %w( src/core/lib/iomgr/tcp_client.cc )
   s.files += %w( src/core/lib/iomgr/tcp_client.cc )
+  s.files += %w( src/core/lib/iomgr/tcp_client_cfstream.cc )
   s.files += %w( src/core/lib/iomgr/tcp_client_custom.cc )
   s.files += %w( src/core/lib/iomgr/tcp_client_custom.cc )
   s.files += %w( src/core/lib/iomgr/tcp_client_posix.cc )
   s.files += %w( src/core/lib/iomgr/tcp_client_posix.cc )
   s.files += %w( src/core/lib/iomgr/tcp_client_windows.cc )
   s.files += %w( src/core/lib/iomgr/tcp_client_windows.cc )

+ 21 - 1
grpc.gyp

@@ -218,7 +218,6 @@
       ],
       ],
       'sources': [
       'sources': [
         'src/core/lib/gpr/alloc.cc',
         'src/core/lib/gpr/alloc.cc',
-        'src/core/lib/gpr/arena.cc',
         'src/core/lib/gpr/atm.cc',
         'src/core/lib/gpr/atm.cc',
         'src/core/lib/gpr/cpu_iphone.cc',
         'src/core/lib/gpr/cpu_iphone.cc',
         'src/core/lib/gpr/cpu_linux.cc',
         'src/core/lib/gpr/cpu_linux.cc',
@@ -251,6 +250,7 @@
         'src/core/lib/gpr/tmpfile_posix.cc',
         'src/core/lib/gpr/tmpfile_posix.cc',
         'src/core/lib/gpr/tmpfile_windows.cc',
         'src/core/lib/gpr/tmpfile_windows.cc',
         'src/core/lib/gpr/wrap_memcpy.cc',
         'src/core/lib/gpr/wrap_memcpy.cc',
+        'src/core/lib/gprpp/arena.cc',
         'src/core/lib/gprpp/fork.cc',
         'src/core/lib/gprpp/fork.cc',
         'src/core/lib/gprpp/thd_posix.cc',
         'src/core/lib/gprpp/thd_posix.cc',
         'src/core/lib/gprpp/thd_windows.cc',
         'src/core/lib/gprpp/thd_windows.cc',
@@ -292,12 +292,15 @@
         'src/core/lib/http/parser.cc',
         'src/core/lib/http/parser.cc',
         'src/core/lib/iomgr/buffer_list.cc',
         'src/core/lib/iomgr/buffer_list.cc',
         'src/core/lib/iomgr/call_combiner.cc',
         'src/core/lib/iomgr/call_combiner.cc',
+        'src/core/lib/iomgr/cfstream_handle.cc',
         'src/core/lib/iomgr/combiner.cc',
         'src/core/lib/iomgr/combiner.cc',
         'src/core/lib/iomgr/endpoint.cc',
         'src/core/lib/iomgr/endpoint.cc',
+        'src/core/lib/iomgr/endpoint_cfstream.cc',
         'src/core/lib/iomgr/endpoint_pair_posix.cc',
         'src/core/lib/iomgr/endpoint_pair_posix.cc',
         'src/core/lib/iomgr/endpoint_pair_uv.cc',
         'src/core/lib/iomgr/endpoint_pair_uv.cc',
         'src/core/lib/iomgr/endpoint_pair_windows.cc',
         'src/core/lib/iomgr/endpoint_pair_windows.cc',
         'src/core/lib/iomgr/error.cc',
         'src/core/lib/iomgr/error.cc',
+        'src/core/lib/iomgr/error_cfstream.cc',
         'src/core/lib/iomgr/ev_epoll1_linux.cc',
         'src/core/lib/iomgr/ev_epoll1_linux.cc',
         'src/core/lib/iomgr/ev_epollex_linux.cc',
         'src/core/lib/iomgr/ev_epollex_linux.cc',
         'src/core/lib/iomgr/ev_poll_posix.cc',
         'src/core/lib/iomgr/ev_poll_posix.cc',
@@ -318,6 +321,7 @@
         'src/core/lib/iomgr/iomgr_custom.cc',
         'src/core/lib/iomgr/iomgr_custom.cc',
         'src/core/lib/iomgr/iomgr_internal.cc',
         'src/core/lib/iomgr/iomgr_internal.cc',
         'src/core/lib/iomgr/iomgr_posix.cc',
         'src/core/lib/iomgr/iomgr_posix.cc',
+        'src/core/lib/iomgr/iomgr_posix_cfstream.cc',
         'src/core/lib/iomgr/iomgr_uv.cc',
         'src/core/lib/iomgr/iomgr_uv.cc',
         'src/core/lib/iomgr/iomgr_windows.cc',
         'src/core/lib/iomgr/iomgr_windows.cc',
         'src/core/lib/iomgr/is_epollexclusive_available.cc',
         'src/core/lib/iomgr/is_epollexclusive_available.cc',
@@ -346,6 +350,7 @@
         'src/core/lib/iomgr/socket_utils_windows.cc',
         'src/core/lib/iomgr/socket_utils_windows.cc',
         'src/core/lib/iomgr/socket_windows.cc',
         'src/core/lib/iomgr/socket_windows.cc',
         'src/core/lib/iomgr/tcp_client.cc',
         'src/core/lib/iomgr/tcp_client.cc',
+        'src/core/lib/iomgr/tcp_client_cfstream.cc',
         'src/core/lib/iomgr/tcp_client_custom.cc',
         'src/core/lib/iomgr/tcp_client_custom.cc',
         'src/core/lib/iomgr/tcp_client_posix.cc',
         'src/core/lib/iomgr/tcp_client_posix.cc',
         'src/core/lib/iomgr/tcp_client_windows.cc',
         'src/core/lib/iomgr/tcp_client_windows.cc',
@@ -660,12 +665,15 @@
         'src/core/lib/http/parser.cc',
         'src/core/lib/http/parser.cc',
         'src/core/lib/iomgr/buffer_list.cc',
         'src/core/lib/iomgr/buffer_list.cc',
         'src/core/lib/iomgr/call_combiner.cc',
         'src/core/lib/iomgr/call_combiner.cc',
+        'src/core/lib/iomgr/cfstream_handle.cc',
         'src/core/lib/iomgr/combiner.cc',
         'src/core/lib/iomgr/combiner.cc',
         'src/core/lib/iomgr/endpoint.cc',
         'src/core/lib/iomgr/endpoint.cc',
+        'src/core/lib/iomgr/endpoint_cfstream.cc',
         'src/core/lib/iomgr/endpoint_pair_posix.cc',
         'src/core/lib/iomgr/endpoint_pair_posix.cc',
         'src/core/lib/iomgr/endpoint_pair_uv.cc',
         'src/core/lib/iomgr/endpoint_pair_uv.cc',
         'src/core/lib/iomgr/endpoint_pair_windows.cc',
         'src/core/lib/iomgr/endpoint_pair_windows.cc',
         'src/core/lib/iomgr/error.cc',
         'src/core/lib/iomgr/error.cc',
+        'src/core/lib/iomgr/error_cfstream.cc',
         'src/core/lib/iomgr/ev_epoll1_linux.cc',
         'src/core/lib/iomgr/ev_epoll1_linux.cc',
         'src/core/lib/iomgr/ev_epollex_linux.cc',
         'src/core/lib/iomgr/ev_epollex_linux.cc',
         'src/core/lib/iomgr/ev_poll_posix.cc',
         'src/core/lib/iomgr/ev_poll_posix.cc',
@@ -686,6 +694,7 @@
         'src/core/lib/iomgr/iomgr_custom.cc',
         'src/core/lib/iomgr/iomgr_custom.cc',
         'src/core/lib/iomgr/iomgr_internal.cc',
         'src/core/lib/iomgr/iomgr_internal.cc',
         'src/core/lib/iomgr/iomgr_posix.cc',
         'src/core/lib/iomgr/iomgr_posix.cc',
+        'src/core/lib/iomgr/iomgr_posix_cfstream.cc',
         'src/core/lib/iomgr/iomgr_uv.cc',
         'src/core/lib/iomgr/iomgr_uv.cc',
         'src/core/lib/iomgr/iomgr_windows.cc',
         'src/core/lib/iomgr/iomgr_windows.cc',
         'src/core/lib/iomgr/is_epollexclusive_available.cc',
         'src/core/lib/iomgr/is_epollexclusive_available.cc',
@@ -714,6 +723,7 @@
         'src/core/lib/iomgr/socket_utils_windows.cc',
         'src/core/lib/iomgr/socket_utils_windows.cc',
         'src/core/lib/iomgr/socket_windows.cc',
         'src/core/lib/iomgr/socket_windows.cc',
         'src/core/lib/iomgr/tcp_client.cc',
         'src/core/lib/iomgr/tcp_client.cc',
+        'src/core/lib/iomgr/tcp_client_cfstream.cc',
         'src/core/lib/iomgr/tcp_client_custom.cc',
         'src/core/lib/iomgr/tcp_client_custom.cc',
         'src/core/lib/iomgr/tcp_client_posix.cc',
         'src/core/lib/iomgr/tcp_client_posix.cc',
         'src/core/lib/iomgr/tcp_client_windows.cc',
         'src/core/lib/iomgr/tcp_client_windows.cc',
@@ -905,12 +915,15 @@
         'src/core/lib/http/parser.cc',
         'src/core/lib/http/parser.cc',
         'src/core/lib/iomgr/buffer_list.cc',
         'src/core/lib/iomgr/buffer_list.cc',
         'src/core/lib/iomgr/call_combiner.cc',
         'src/core/lib/iomgr/call_combiner.cc',
+        'src/core/lib/iomgr/cfstream_handle.cc',
         'src/core/lib/iomgr/combiner.cc',
         'src/core/lib/iomgr/combiner.cc',
         'src/core/lib/iomgr/endpoint.cc',
         'src/core/lib/iomgr/endpoint.cc',
+        'src/core/lib/iomgr/endpoint_cfstream.cc',
         'src/core/lib/iomgr/endpoint_pair_posix.cc',
         'src/core/lib/iomgr/endpoint_pair_posix.cc',
         'src/core/lib/iomgr/endpoint_pair_uv.cc',
         'src/core/lib/iomgr/endpoint_pair_uv.cc',
         'src/core/lib/iomgr/endpoint_pair_windows.cc',
         'src/core/lib/iomgr/endpoint_pair_windows.cc',
         'src/core/lib/iomgr/error.cc',
         'src/core/lib/iomgr/error.cc',
+        'src/core/lib/iomgr/error_cfstream.cc',
         'src/core/lib/iomgr/ev_epoll1_linux.cc',
         'src/core/lib/iomgr/ev_epoll1_linux.cc',
         'src/core/lib/iomgr/ev_epollex_linux.cc',
         'src/core/lib/iomgr/ev_epollex_linux.cc',
         'src/core/lib/iomgr/ev_poll_posix.cc',
         'src/core/lib/iomgr/ev_poll_posix.cc',
@@ -931,6 +944,7 @@
         'src/core/lib/iomgr/iomgr_custom.cc',
         'src/core/lib/iomgr/iomgr_custom.cc',
         'src/core/lib/iomgr/iomgr_internal.cc',
         'src/core/lib/iomgr/iomgr_internal.cc',
         'src/core/lib/iomgr/iomgr_posix.cc',
         'src/core/lib/iomgr/iomgr_posix.cc',
+        'src/core/lib/iomgr/iomgr_posix_cfstream.cc',
         'src/core/lib/iomgr/iomgr_uv.cc',
         'src/core/lib/iomgr/iomgr_uv.cc',
         'src/core/lib/iomgr/iomgr_windows.cc',
         'src/core/lib/iomgr/iomgr_windows.cc',
         'src/core/lib/iomgr/is_epollexclusive_available.cc',
         'src/core/lib/iomgr/is_epollexclusive_available.cc',
@@ -959,6 +973,7 @@
         'src/core/lib/iomgr/socket_utils_windows.cc',
         'src/core/lib/iomgr/socket_utils_windows.cc',
         'src/core/lib/iomgr/socket_windows.cc',
         'src/core/lib/iomgr/socket_windows.cc',
         'src/core/lib/iomgr/tcp_client.cc',
         'src/core/lib/iomgr/tcp_client.cc',
+        'src/core/lib/iomgr/tcp_client_cfstream.cc',
         'src/core/lib/iomgr/tcp_client_custom.cc',
         'src/core/lib/iomgr/tcp_client_custom.cc',
         'src/core/lib/iomgr/tcp_client_posix.cc',
         'src/core/lib/iomgr/tcp_client_posix.cc',
         'src/core/lib/iomgr/tcp_client_windows.cc',
         'src/core/lib/iomgr/tcp_client_windows.cc',
@@ -1126,12 +1141,15 @@
         'src/core/lib/http/parser.cc',
         'src/core/lib/http/parser.cc',
         'src/core/lib/iomgr/buffer_list.cc',
         'src/core/lib/iomgr/buffer_list.cc',
         'src/core/lib/iomgr/call_combiner.cc',
         'src/core/lib/iomgr/call_combiner.cc',
+        'src/core/lib/iomgr/cfstream_handle.cc',
         'src/core/lib/iomgr/combiner.cc',
         'src/core/lib/iomgr/combiner.cc',
         'src/core/lib/iomgr/endpoint.cc',
         'src/core/lib/iomgr/endpoint.cc',
+        'src/core/lib/iomgr/endpoint_cfstream.cc',
         'src/core/lib/iomgr/endpoint_pair_posix.cc',
         'src/core/lib/iomgr/endpoint_pair_posix.cc',
         'src/core/lib/iomgr/endpoint_pair_uv.cc',
         'src/core/lib/iomgr/endpoint_pair_uv.cc',
         'src/core/lib/iomgr/endpoint_pair_windows.cc',
         'src/core/lib/iomgr/endpoint_pair_windows.cc',
         'src/core/lib/iomgr/error.cc',
         'src/core/lib/iomgr/error.cc',
+        'src/core/lib/iomgr/error_cfstream.cc',
         'src/core/lib/iomgr/ev_epoll1_linux.cc',
         'src/core/lib/iomgr/ev_epoll1_linux.cc',
         'src/core/lib/iomgr/ev_epollex_linux.cc',
         'src/core/lib/iomgr/ev_epollex_linux.cc',
         'src/core/lib/iomgr/ev_poll_posix.cc',
         'src/core/lib/iomgr/ev_poll_posix.cc',
@@ -1152,6 +1170,7 @@
         'src/core/lib/iomgr/iomgr_custom.cc',
         'src/core/lib/iomgr/iomgr_custom.cc',
         'src/core/lib/iomgr/iomgr_internal.cc',
         'src/core/lib/iomgr/iomgr_internal.cc',
         'src/core/lib/iomgr/iomgr_posix.cc',
         'src/core/lib/iomgr/iomgr_posix.cc',
+        'src/core/lib/iomgr/iomgr_posix_cfstream.cc',
         'src/core/lib/iomgr/iomgr_uv.cc',
         'src/core/lib/iomgr/iomgr_uv.cc',
         'src/core/lib/iomgr/iomgr_windows.cc',
         'src/core/lib/iomgr/iomgr_windows.cc',
         'src/core/lib/iomgr/is_epollexclusive_available.cc',
         'src/core/lib/iomgr/is_epollexclusive_available.cc',
@@ -1180,6 +1199,7 @@
         'src/core/lib/iomgr/socket_utils_windows.cc',
         'src/core/lib/iomgr/socket_utils_windows.cc',
         'src/core/lib/iomgr/socket_windows.cc',
         'src/core/lib/iomgr/socket_windows.cc',
         'src/core/lib/iomgr/tcp_client.cc',
         'src/core/lib/iomgr/tcp_client.cc',
+        'src/core/lib/iomgr/tcp_client_cfstream.cc',
         'src/core/lib/iomgr/tcp_client_custom.cc',
         'src/core/lib/iomgr/tcp_client_custom.cc',
         'src/core/lib/iomgr/tcp_client_posix.cc',
         'src/core/lib/iomgr/tcp_client_posix.cc',
         'src/core/lib/iomgr/tcp_client_windows.cc',
         'src/core/lib/iomgr/tcp_client_windows.cc',

+ 2 - 1
include/grpc/impl/codegen/grpc_types.h

@@ -494,7 +494,8 @@ typedef struct grpc_event {
       field is guaranteed to be 0 */
       field is guaranteed to be 0 */
   int success;
   int success;
   /** The tag passed to grpc_call_start_batch etc to start this operation.
   /** The tag passed to grpc_call_start_batch etc to start this operation.
-      Only GRPC_OP_COMPLETE has a tag. */
+      *Only* GRPC_OP_COMPLETE has a tag. For all other grpc_completion_type
+      values, tag is uninitialized. */
   void* tag;
   void* tag;
 } grpc_event;
 } grpc_event;
 
 

+ 10 - 1
package.xml

@@ -104,6 +104,7 @@
     <file baseinstalldir="/" name="src/core/lib/gpr/tmpfile.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/tmpfile.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/useful.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/useful.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/abstract.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/abstract.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gprpp/arena.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/atomic.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/atomic.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/fork.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/fork.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/manual_constructor.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/manual_constructor.h" role="src" />
@@ -114,7 +115,6 @@
     <file baseinstalldir="/" name="src/core/lib/gprpp/thd.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/thd.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/profiling/timers.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/profiling/timers.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/alloc.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/alloc.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/gpr/arena.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/atm.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/atm.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/cpu_iphone.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/cpu_iphone.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/cpu_linux.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/cpu_linux.cc" role="src" />
@@ -147,6 +147,7 @@
     <file baseinstalldir="/" name="src/core/lib/gpr/tmpfile_posix.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/tmpfile_posix.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/tmpfile_windows.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/tmpfile_windows.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/wrap_memcpy.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gpr/wrap_memcpy.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/gprpp/arena.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/fork.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/fork.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/thd_posix.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/thd_posix.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/thd_windows.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/thd_windows.cc" role="src" />
@@ -352,12 +353,15 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/block_annotate.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/block_annotate.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/buffer_list.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/buffer_list.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/call_combiner.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/call_combiner.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/cfstream_handle.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/closure.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/closure.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/combiner.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/combiner.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/dynamic_annotations.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/dynamic_annotations.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_cfstream.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/error.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/error.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/error_cfstream.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/error_internal.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/error_internal.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_epoll1_linux.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_epoll1_linux.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_epollex_linux.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_epollex_linux.h" role="src" />
@@ -500,12 +504,15 @@
     <file baseinstalldir="/" name="src/core/lib/http/parser.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/http/parser.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/buffer_list.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/buffer_list.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/call_combiner.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/call_combiner.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/cfstream_handle.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/combiner.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/combiner.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_cfstream.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair_posix.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair_posix.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair_uv.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair_uv.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair_windows.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair_windows.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/error.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/error.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/error_cfstream.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_epoll1_linux.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_epoll1_linux.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_epollex_linux.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_epollex_linux.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_poll_posix.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_poll_posix.cc" role="src" />
@@ -526,6 +533,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_custom.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_custom.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_internal.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_internal.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_posix.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_posix.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_posix_cfstream.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_uv.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_uv.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_windows.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_windows.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/is_epollexclusive_available.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/is_epollexclusive_available.cc" role="src" />
@@ -554,6 +562,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils_windows.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils_windows.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_windows.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_windows.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_cfstream.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_custom.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_custom.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_posix.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_posix.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_windows.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client_windows.cc" role="src" />

+ 13 - 19
src/core/ext/filters/client_channel/client_channel.cc

@@ -614,7 +614,7 @@ class CallData {
   grpc_slice path_;  // Request path.
   grpc_slice path_;  // Request path.
   gpr_timespec call_start_time_;
   gpr_timespec call_start_time_;
   grpc_millis deadline_;
   grpc_millis deadline_;
-  gpr_arena* arena_;
+  Arena* arena_;
   grpc_call_stack* owning_call_;
   grpc_call_stack* owning_call_;
   CallCombiner* call_combiner_;
   CallCombiner* call_combiner_;
   grpc_call_context_element* call_context_;
   grpc_call_context_element* call_context_;
@@ -1506,8 +1506,8 @@ void CallData::MaybeCacheSendOpsForBatch(PendingBatch* pending) {
     GPR_ASSERT(send_initial_metadata_storage_ == nullptr);
     GPR_ASSERT(send_initial_metadata_storage_ == nullptr);
     grpc_metadata_batch* send_initial_metadata =
     grpc_metadata_batch* send_initial_metadata =
         batch->payload->send_initial_metadata.send_initial_metadata;
         batch->payload->send_initial_metadata.send_initial_metadata;
-    send_initial_metadata_storage_ = (grpc_linked_mdelem*)gpr_arena_alloc(
-        arena_, sizeof(grpc_linked_mdelem) * send_initial_metadata->list.count);
+    send_initial_metadata_storage_ = (grpc_linked_mdelem*)arena_->Alloc(
+        sizeof(grpc_linked_mdelem) * send_initial_metadata->list.count);
     grpc_metadata_batch_copy(send_initial_metadata, &send_initial_metadata_,
     grpc_metadata_batch_copy(send_initial_metadata, &send_initial_metadata_,
                              send_initial_metadata_storage_);
                              send_initial_metadata_storage_);
     send_initial_metadata_flags_ =
     send_initial_metadata_flags_ =
@@ -1516,10 +1516,8 @@ void CallData::MaybeCacheSendOpsForBatch(PendingBatch* pending) {
   }
   }
   // Set up cache for send_message ops.
   // Set up cache for send_message ops.
   if (batch->send_message) {
   if (batch->send_message) {
-    ByteStreamCache* cache = static_cast<ByteStreamCache*>(
-        gpr_arena_alloc(arena_, sizeof(ByteStreamCache)));
-    new (cache)
-        ByteStreamCache(std::move(batch->payload->send_message.send_message));
+    ByteStreamCache* cache = arena_->New<ByteStreamCache>(
+        std::move(batch->payload->send_message.send_message));
     send_messages_.push_back(cache);
     send_messages_.push_back(cache);
   }
   }
   // Save metadata batch for send_trailing_metadata ops.
   // Save metadata batch for send_trailing_metadata ops.
@@ -1528,8 +1526,7 @@ void CallData::MaybeCacheSendOpsForBatch(PendingBatch* pending) {
     GPR_ASSERT(send_trailing_metadata_storage_ == nullptr);
     GPR_ASSERT(send_trailing_metadata_storage_ == nullptr);
     grpc_metadata_batch* send_trailing_metadata =
     grpc_metadata_batch* send_trailing_metadata =
         batch->payload->send_trailing_metadata.send_trailing_metadata;
         batch->payload->send_trailing_metadata.send_trailing_metadata;
-    send_trailing_metadata_storage_ = (grpc_linked_mdelem*)gpr_arena_alloc(
-        arena_,
+    send_trailing_metadata_storage_ = (grpc_linked_mdelem*)arena_->Alloc(
         sizeof(grpc_linked_mdelem) * send_trailing_metadata->list.count);
         sizeof(grpc_linked_mdelem) * send_trailing_metadata->list.count);
     grpc_metadata_batch_copy(send_trailing_metadata, &send_trailing_metadata_,
     grpc_metadata_batch_copy(send_trailing_metadata, &send_trailing_metadata_,
                              send_trailing_metadata_storage_);
                              send_trailing_metadata_storage_);
@@ -2015,10 +2012,8 @@ bool CallData::MaybeRetry(grpc_call_element* elem,
 CallData::SubchannelCallBatchData* CallData::SubchannelCallBatchData::Create(
 CallData::SubchannelCallBatchData* CallData::SubchannelCallBatchData::Create(
     grpc_call_element* elem, int refcount, bool set_on_complete) {
     grpc_call_element* elem, int refcount, bool set_on_complete) {
   CallData* calld = static_cast<CallData*>(elem->call_data);
   CallData* calld = static_cast<CallData*>(elem->call_data);
-  SubchannelCallBatchData* batch_data =
-      new (gpr_arena_alloc(calld->arena_, sizeof(*batch_data)))
-          SubchannelCallBatchData(elem, calld, refcount, set_on_complete);
-  return batch_data;
+  return calld->arena_->New<SubchannelCallBatchData>(elem, calld, refcount,
+                                                     set_on_complete);
 }
 }
 
 
 CallData::SubchannelCallBatchData::SubchannelCallBatchData(
 CallData::SubchannelCallBatchData::SubchannelCallBatchData(
@@ -2610,10 +2605,10 @@ void CallData::AddRetriableSendInitialMetadataOp(
   //
   //
   // If we've already completed one or more attempts, add the
   // If we've already completed one or more attempts, add the
   // grpc-retry-attempts header.
   // grpc-retry-attempts header.
-  retry_state->send_initial_metadata_storage = static_cast<grpc_linked_mdelem*>(
-      gpr_arena_alloc(arena_, sizeof(grpc_linked_mdelem) *
-                                  (send_initial_metadata_.list.count +
-                                   (num_attempts_completed_ > 0))));
+  retry_state->send_initial_metadata_storage =
+      static_cast<grpc_linked_mdelem*>(arena_->Alloc(
+          sizeof(grpc_linked_mdelem) *
+          (send_initial_metadata_.list.count + (num_attempts_completed_ > 0))));
   grpc_metadata_batch_copy(&send_initial_metadata_,
   grpc_metadata_batch_copy(&send_initial_metadata_,
                            &retry_state->send_initial_metadata,
                            &retry_state->send_initial_metadata,
                            retry_state->send_initial_metadata_storage);
                            retry_state->send_initial_metadata_storage);
@@ -2672,8 +2667,7 @@ void CallData::AddRetriableSendTrailingMetadataOp(
   // the filters in the subchannel stack may modify this batch, and we don't
   // the filters in the subchannel stack may modify this batch, and we don't
   // want those modifications to be passed forward to subsequent attempts.
   // want those modifications to be passed forward to subsequent attempts.
   retry_state->send_trailing_metadata_storage =
   retry_state->send_trailing_metadata_storage =
-      static_cast<grpc_linked_mdelem*>(gpr_arena_alloc(
-          arena_,
+      static_cast<grpc_linked_mdelem*>(arena_->Alloc(
           sizeof(grpc_linked_mdelem) * send_trailing_metadata_.list.count));
           sizeof(grpc_linked_mdelem) * send_trailing_metadata_.list.count));
   grpc_metadata_batch_copy(&send_trailing_metadata_,
   grpc_metadata_batch_copy(&send_trailing_metadata_,
                            &retry_state->send_trailing_metadata,
                            &retry_state->send_trailing_metadata,

+ 3 - 3
src/core/ext/filters/client_channel/health/health_check_client.cc

@@ -280,8 +280,8 @@ HealthCheckClient::CallState::CallState(
     : InternallyRefCounted<CallState>(&grpc_health_check_client_trace),
     : InternallyRefCounted<CallState>(&grpc_health_check_client_trace),
       health_check_client_(std::move(health_check_client)),
       health_check_client_(std::move(health_check_client)),
       pollent_(grpc_polling_entity_create_from_pollset_set(interested_parties)),
       pollent_(grpc_polling_entity_create_from_pollset_set(interested_parties)),
-      arena_(gpr_arena_create(health_check_client_->connected_subchannel_
-                                  ->GetInitialCallSizeEstimate(0))),
+      arena_(Arena::Create(health_check_client_->connected_subchannel_
+                               ->GetInitialCallSizeEstimate(0))),
       payload_(context_) {}
       payload_(context_) {}
 
 
 HealthCheckClient::CallState::~CallState() {
 HealthCheckClient::CallState::~CallState() {
@@ -302,7 +302,7 @@ HealthCheckClient::CallState::~CallState() {
   // need to take a ref of the call stack to guarantee closure liveness.
   // need to take a ref of the call stack to guarantee closure liveness.
   call_combiner_.SetNotifyOnCancel(nullptr);
   call_combiner_.SetNotifyOnCancel(nullptr);
   ExecCtx::Get()->Flush();
   ExecCtx::Get()->Flush();
-  gpr_arena_destroy(arena_);
+  arena_->Destroy();
 }
 }
 
 
 void HealthCheckClient::CallState::Orphan() {
 void HealthCheckClient::CallState::Orphan() {

+ 2 - 2
src/core/ext/filters/client_channel/health/health_check_client.h

@@ -27,7 +27,7 @@
 #include "src/core/ext/filters/client_channel/client_channel_channelz.h"
 #include "src/core/ext/filters/client_channel/client_channel_channelz.h"
 #include "src/core/ext/filters/client_channel/subchannel.h"
 #include "src/core/ext/filters/client_channel/subchannel.h"
 #include "src/core/lib/backoff/backoff.h"
 #include "src/core/lib/backoff/backoff.h"
-#include "src/core/lib/gpr/arena.h"
+#include "src/core/lib/gprpp/arena.h"
 #include "src/core/lib/gprpp/atomic.h"
 #include "src/core/lib/gprpp/atomic.h"
 #include "src/core/lib/gprpp/orphanable.h"
 #include "src/core/lib/gprpp/orphanable.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
@@ -97,7 +97,7 @@ class HealthCheckClient : public InternallyRefCounted<HealthCheckClient> {
     RefCountedPtr<HealthCheckClient> health_check_client_;
     RefCountedPtr<HealthCheckClient> health_check_client_;
     grpc_polling_entity pollent_;
     grpc_polling_entity pollent_;
 
 
-    gpr_arena* arena_;
+    Arena* arena_;
     grpc_core::CallCombiner call_combiner_;
     grpc_core::CallCombiner call_combiner_;
     grpc_call_context_element context_[GRPC_CONTEXT_COUNT] = {};
     grpc_call_context_element context_[GRPC_CONTEXT_COUNT] = {};
 
 

+ 1 - 1
src/core/ext/filters/client_channel/subchannel.cc

@@ -121,7 +121,7 @@ RefCountedPtr<SubchannelCall> ConnectedSubchannel::CreateCall(
   const size_t allocation_size =
   const size_t allocation_size =
       GetInitialCallSizeEstimate(args.parent_data_size);
       GetInitialCallSizeEstimate(args.parent_data_size);
   RefCountedPtr<SubchannelCall> call(
   RefCountedPtr<SubchannelCall> call(
-      new (gpr_arena_alloc(args.arena, allocation_size))
+      new (args.arena->Alloc(allocation_size))
           SubchannelCall(Ref(DEBUG_LOCATION, "subchannel_call"), args));
           SubchannelCall(Ref(DEBUG_LOCATION, "subchannel_call"), args));
   grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call.get());
   grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call.get());
   const grpc_call_element_args call_args = {
   const grpc_call_element_args call_args = {

+ 2 - 2
src/core/ext/filters/client_channel/subchannel.h

@@ -26,7 +26,7 @@
 #include "src/core/ext/filters/client_channel/subchannel_pool_interface.h"
 #include "src/core/ext/filters/client_channel/subchannel_pool_interface.h"
 #include "src/core/lib/backoff/backoff.h"
 #include "src/core/lib/backoff/backoff.h"
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/gpr/arena.h"
+#include "src/core/lib/gprpp/arena.h"
 #include "src/core/lib/gprpp/ref_counted.h"
 #include "src/core/lib/gprpp/ref_counted.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/gprpp/sync.h"
 #include "src/core/lib/gprpp/sync.h"
@@ -75,7 +75,7 @@ class ConnectedSubchannel : public RefCounted<ConnectedSubchannel> {
     grpc_slice path;
     grpc_slice path;
     gpr_timespec start_time;
     gpr_timespec start_time;
     grpc_millis deadline;
     grpc_millis deadline;
-    gpr_arena* arena;
+    Arena* arena;
     grpc_call_context_element* context;
     grpc_call_context_element* context;
     grpc_core::CallCombiner* call_combiner;
     grpc_core::CallCombiner* call_combiner;
     size_t parent_data_size;
     size_t parent_data_size;

+ 4 - 3
src/core/ext/transport/chttp2/transport/chttp2_transport.cc

@@ -655,11 +655,12 @@ grpc_chttp2_stream::Reffer::Reffer(grpc_chttp2_stream* s) {
 grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t,
 grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t,
                                        grpc_stream_refcount* refcount,
                                        grpc_stream_refcount* refcount,
                                        const void* server_data,
                                        const void* server_data,
-                                       gpr_arena* arena)
+                                       grpc_core::Arena* arena)
     : t(t),
     : t(t),
       refcount(refcount),
       refcount(refcount),
       reffer(this),
       reffer(this),
-      metadata_buffer{{arena}, {arena}} {
+      metadata_buffer{grpc_chttp2_incoming_metadata_buffer(arena),
+                      grpc_chttp2_incoming_metadata_buffer(arena)} {
   if (server_data) {
   if (server_data) {
     id = static_cast<uint32_t>((uintptr_t)server_data);
     id = static_cast<uint32_t>((uintptr_t)server_data);
     *t->accepting_stream = this;
     *t->accepting_stream = this;
@@ -740,7 +741,7 @@ grpc_chttp2_stream::~grpc_chttp2_stream() {
 
 
 static int init_stream(grpc_transport* gt, grpc_stream* gs,
 static int init_stream(grpc_transport* gt, grpc_stream* gs,
                        grpc_stream_refcount* refcount, const void* server_data,
                        grpc_stream_refcount* refcount, const void* server_data,
-                       gpr_arena* arena) {
+                       grpc_core::Arena* arena) {
   GPR_TIMER_SCOPE("init_stream", 0);
   GPR_TIMER_SCOPE("init_stream", 0);
   grpc_chttp2_transport* t = reinterpret_cast<grpc_chttp2_transport*>(gt);
   grpc_chttp2_transport* t = reinterpret_cast<grpc_chttp2_transport*>(gt);
   new (gs) grpc_chttp2_stream(t, refcount, server_data, arena);
   new (gs) grpc_chttp2_stream(t, refcount, server_data, arena);

+ 1 - 1
src/core/ext/transport/chttp2/transport/incoming_metadata.cc

@@ -36,7 +36,7 @@ grpc_error* grpc_chttp2_incoming_metadata_buffer_add(
     buffer->count++;
     buffer->count++;
   } else {
   } else {
     storage = static_cast<grpc_linked_mdelem*>(
     storage = static_cast<grpc_linked_mdelem*>(
-        gpr_arena_alloc(buffer->arena, sizeof(grpc_linked_mdelem)));
+        buffer->arena->Alloc(sizeof(grpc_linked_mdelem)));
   }
   }
   return grpc_metadata_batch_add_tail(&buffer->batch, storage, elem);
   return grpc_metadata_batch_add_tail(&buffer->batch, storage, elem);
 }
 }

+ 3 - 2
src/core/ext/transport/chttp2/transport/incoming_metadata.h

@@ -24,7 +24,8 @@
 #include "src/core/lib/transport/transport.h"
 #include "src/core/lib/transport/transport.h"
 
 
 struct grpc_chttp2_incoming_metadata_buffer {
 struct grpc_chttp2_incoming_metadata_buffer {
-  grpc_chttp2_incoming_metadata_buffer(gpr_arena* arena) : arena(arena) {
+  explicit grpc_chttp2_incoming_metadata_buffer(grpc_core::Arena* arena)
+      : arena(arena) {
     grpc_metadata_batch_init(&batch);
     grpc_metadata_batch_init(&batch);
     batch.deadline = GRPC_MILLIS_INF_FUTURE;
     batch.deadline = GRPC_MILLIS_INF_FUTURE;
   }
   }
@@ -34,7 +35,7 @@ struct grpc_chttp2_incoming_metadata_buffer {
 
 
   static constexpr size_t kPreallocatedMDElem = 10;
   static constexpr size_t kPreallocatedMDElem = 10;
 
 
-  gpr_arena* arena;
+  grpc_core::Arena* arena;
   size_t size = 0;   // total size of metadata.
   size_t size = 0;   // total size of metadata.
   size_t count = 0;  // minimum of count of metadata and kPreallocatedMDElem.
   size_t count = 0;  // minimum of count of metadata and kPreallocatedMDElem.
   // These preallocated mdelems are used while count < kPreallocatedMDElem.
   // These preallocated mdelems are used while count < kPreallocatedMDElem.

+ 1 - 1
src/core/ext/transport/chttp2/transport/internal.h

@@ -504,7 +504,7 @@ typedef enum {
 
 
 struct grpc_chttp2_stream {
 struct grpc_chttp2_stream {
   grpc_chttp2_stream(grpc_chttp2_transport* t, grpc_stream_refcount* refcount,
   grpc_chttp2_stream(grpc_chttp2_transport* t, grpc_stream_refcount* refcount,
-                     const void* server_data, gpr_arena* arena);
+                     const void* server_data, grpc_core::Arena* arena);
   ~grpc_chttp2_stream();
   ~grpc_chttp2_stream();
 
 
   void* context;
   void* context;

+ 7 - 6
src/core/ext/transport/cronet/transport/cronet_transport.cc

@@ -110,7 +110,7 @@ typedef struct grpc_cronet_transport grpc_cronet_transport;
 /* TODO (makdharma): reorder structure for memory efficiency per
 /* TODO (makdharma): reorder structure for memory efficiency per
    http://www.catb.org/esr/structure-packing/#_structure_reordering: */
    http://www.catb.org/esr/structure-packing/#_structure_reordering: */
 struct read_state {
 struct read_state {
-  read_state(gpr_arena* arena)
+  read_state(grpc_core::Arena* arena)
       : trailing_metadata(arena), initial_metadata(arena) {
       : trailing_metadata(arena), initial_metadata(arena) {
     grpc_slice_buffer_init(&read_slice_buffer);
     grpc_slice_buffer_init(&read_slice_buffer);
   }
   }
@@ -144,7 +144,7 @@ struct write_state {
 
 
 /* track state of one stream op */
 /* track state of one stream op */
 struct op_state {
 struct op_state {
-  op_state(gpr_arena* arena) : rs(arena) {}
+  op_state(grpc_core::Arena* arena) : rs(arena) {}
 
 
   bool state_op_done[OP_NUM_OPS] = {};
   bool state_op_done[OP_NUM_OPS] = {};
   bool state_callback_received[OP_NUM_OPS] = {};
   bool state_callback_received[OP_NUM_OPS] = {};
@@ -186,10 +186,10 @@ struct op_storage {
 
 
 struct stream_obj {
 struct stream_obj {
   stream_obj(grpc_transport* gt, grpc_stream* gs,
   stream_obj(grpc_transport* gt, grpc_stream* gs,
-             grpc_stream_refcount* refcount, gpr_arena* arena);
+             grpc_stream_refcount* refcount, grpc_core::Arena* arena);
   ~stream_obj();
   ~stream_obj();
 
 
-  gpr_arena* arena;
+  grpc_core::Arena* arena;
   struct op_and_state* oas = nullptr;
   struct op_and_state* oas = nullptr;
   grpc_transport_stream_op_batch* curr_op = nullptr;
   grpc_transport_stream_op_batch* curr_op = nullptr;
   grpc_cronet_transport* curr_ct;
   grpc_cronet_transport* curr_ct;
@@ -1368,7 +1368,8 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) {
 */
 */
 
 
 inline stream_obj::stream_obj(grpc_transport* gt, grpc_stream* gs,
 inline stream_obj::stream_obj(grpc_transport* gt, grpc_stream* gs,
-                              grpc_stream_refcount* refcount, gpr_arena* arena)
+                              grpc_stream_refcount* refcount,
+                              grpc_core::Arena* arena)
     : arena(arena),
     : arena(arena),
       curr_ct(reinterpret_cast<grpc_cronet_transport*>(gt)),
       curr_ct(reinterpret_cast<grpc_cronet_transport*>(gt)),
       curr_gs(gs),
       curr_gs(gs),
@@ -1387,7 +1388,7 @@ inline stream_obj::~stream_obj() {
 
 
 static int init_stream(grpc_transport* gt, grpc_stream* gs,
 static int init_stream(grpc_transport* gt, grpc_stream* gs,
                        grpc_stream_refcount* refcount, const void* server_data,
                        grpc_stream_refcount* refcount, const void* server_data,
-                       gpr_arena* arena) {
+                       grpc_core::Arena* arena) {
   new (gs) stream_obj(gt, gs, refcount, arena);
   new (gs) stream_obj(gt, gs, refcount, arena);
   return 0;
   return 0;
 }
 }

+ 9 - 9
src/core/ext/transport/inproc/inproc_transport.cc

@@ -120,7 +120,7 @@ struct inproc_transport {
 
 
 struct inproc_stream {
 struct inproc_stream {
   inproc_stream(inproc_transport* t, grpc_stream_refcount* refcount,
   inproc_stream(inproc_transport* t, grpc_stream_refcount* refcount,
-                const void* server_data, gpr_arena* arena)
+                const void* server_data, grpc_core::Arena* arena)
       : t(t), refs(refcount), arena(arena) {
       : t(t), refs(refcount), arena(arena) {
     // Ref this stream right now for ctor and list.
     // Ref this stream right now for ctor and list.
     ref("inproc_init_stream:init");
     ref("inproc_init_stream:init");
@@ -250,7 +250,7 @@ struct inproc_stream {
   grpc_stream_refcount* refs;
   grpc_stream_refcount* refs;
   grpc_closure* closure_at_destroy = nullptr;
   grpc_closure* closure_at_destroy = nullptr;
 
 
-  gpr_arena* arena;
+  grpc_core::Arena* arena;
 
 
   grpc_transport_stream_op_batch* send_message_op = nullptr;
   grpc_transport_stream_op_batch* send_message_op = nullptr;
   grpc_transport_stream_op_batch* send_trailing_md_op = nullptr;
   grpc_transport_stream_op_batch* send_trailing_md_op = nullptr;
@@ -309,8 +309,8 @@ grpc_error* fill_in_metadata(inproc_stream* s,
   grpc_error* error = GRPC_ERROR_NONE;
   grpc_error* error = GRPC_ERROR_NONE;
   for (grpc_linked_mdelem* elem = metadata->list.head;
   for (grpc_linked_mdelem* elem = metadata->list.head;
        (elem != nullptr) && (error == GRPC_ERROR_NONE); elem = elem->next) {
        (elem != nullptr) && (error == GRPC_ERROR_NONE); elem = elem->next) {
-    grpc_linked_mdelem* nelem = static_cast<grpc_linked_mdelem*>(
-        gpr_arena_alloc(s->arena, sizeof(*nelem)));
+    grpc_linked_mdelem* nelem =
+        static_cast<grpc_linked_mdelem*>(s->arena->Alloc(sizeof(*nelem)));
     nelem->md =
     nelem->md =
         grpc_mdelem_from_slices(grpc_slice_intern(GRPC_MDKEY(elem->md)),
         grpc_mdelem_from_slices(grpc_slice_intern(GRPC_MDKEY(elem->md)),
                                 grpc_slice_intern(GRPC_MDVALUE(elem->md)));
                                 grpc_slice_intern(GRPC_MDVALUE(elem->md)));
@@ -322,7 +322,7 @@ grpc_error* fill_in_metadata(inproc_stream* s,
 
 
 int init_stream(grpc_transport* gt, grpc_stream* gs,
 int init_stream(grpc_transport* gt, grpc_stream* gs,
                 grpc_stream_refcount* refcount, const void* server_data,
                 grpc_stream_refcount* refcount, const void* server_data,
-                gpr_arena* arena) {
+                grpc_core::Arena* arena) {
   INPROC_LOG(GPR_INFO, "init_stream %p %p %p", gt, gs, server_data);
   INPROC_LOG(GPR_INFO, "init_stream %p %p %p", gt, gs, server_data);
   inproc_transport* t = reinterpret_cast<inproc_transport*>(gt);
   inproc_transport* t = reinterpret_cast<inproc_transport*>(gt);
   new (gs) inproc_stream(t, refcount, server_data, arena);
   new (gs) inproc_stream(t, refcount, server_data, arena);
@@ -436,13 +436,13 @@ void fail_helper_locked(inproc_stream* s, grpc_error* error) {
       // since it expects that as well as no error yet
       // since it expects that as well as no error yet
       grpc_metadata_batch fake_md;
       grpc_metadata_batch fake_md;
       grpc_metadata_batch_init(&fake_md);
       grpc_metadata_batch_init(&fake_md);
-      grpc_linked_mdelem* path_md = static_cast<grpc_linked_mdelem*>(
-          gpr_arena_alloc(s->arena, sizeof(*path_md)));
+      grpc_linked_mdelem* path_md =
+          static_cast<grpc_linked_mdelem*>(s->arena->Alloc(sizeof(*path_md)));
       path_md->md = grpc_mdelem_from_slices(g_fake_path_key, g_fake_path_value);
       path_md->md = grpc_mdelem_from_slices(g_fake_path_key, g_fake_path_value);
       GPR_ASSERT(grpc_metadata_batch_link_tail(&fake_md, path_md) ==
       GPR_ASSERT(grpc_metadata_batch_link_tail(&fake_md, path_md) ==
                  GRPC_ERROR_NONE);
                  GRPC_ERROR_NONE);
-      grpc_linked_mdelem* auth_md = static_cast<grpc_linked_mdelem*>(
-          gpr_arena_alloc(s->arena, sizeof(*auth_md)));
+      grpc_linked_mdelem* auth_md =
+          static_cast<grpc_linked_mdelem*>(s->arena->Alloc(sizeof(*auth_md)));
       auth_md->md = grpc_mdelem_from_slices(g_fake_auth_key, g_fake_auth_value);
       auth_md->md = grpc_mdelem_from_slices(g_fake_auth_key, g_fake_auth_value);
       GPR_ASSERT(grpc_metadata_batch_link_tail(&fake_md, auth_md) ==
       GPR_ASSERT(grpc_metadata_batch_link_tail(&fake_md, auth_md) ==
                  GRPC_ERROR_NONE);
                  GRPC_ERROR_NONE);

+ 2 - 2
src/core/lib/channel/channel_stack.h

@@ -42,7 +42,7 @@
 #include <grpc/support/time.h>
 #include <grpc/support/time.h>
 
 
 #include "src/core/lib/debug/trace.h"
 #include "src/core/lib/debug/trace.h"
-#include "src/core/lib/gpr/arena.h"
+#include "src/core/lib/gprpp/arena.h"
 #include "src/core/lib/iomgr/call_combiner.h"
 #include "src/core/lib/iomgr/call_combiner.h"
 #include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/transport/transport.h"
 #include "src/core/lib/transport/transport.h"
@@ -69,7 +69,7 @@ typedef struct {
   const grpc_slice& path;
   const grpc_slice& path;
   gpr_timespec start_time;
   gpr_timespec start_time;
   grpc_millis deadline;
   grpc_millis deadline;
-  gpr_arena* arena;
+  grpc_core::Arena* arena;
   grpc_core::CallCombiner* call_combiner;
   grpc_core::CallCombiner* call_combiner;
 } grpc_call_element_args;
 } grpc_call_element_args;
 
 

+ 0 - 152
src/core/lib/gpr/arena.cc

@@ -1,152 +0,0 @@
-/*
- *
- * Copyright 2017 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <grpc/support/port_platform.h>
-
-#include "src/core/lib/gpr/arena.h"
-
-#include <string.h>
-#include <new>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/atm.h>
-#include <grpc/support/log.h>
-#include <grpc/support/sync.h>
-
-#include "src/core/lib/gpr/alloc.h"
-#include "src/core/lib/gprpp/memory.h"
-
-static void* gpr_arena_malloc(size_t size) {
-  return gpr_malloc_aligned(size, GPR_MAX_ALIGNMENT);
-}
-
-// Uncomment this to use a simple arena that simply allocates the
-// requested amount of memory for each call to gpr_arena_alloc().  This
-// effectively eliminates the efficiency gain of using an arena, but it
-// may be useful for debugging purposes.
-//#define SIMPLE_ARENA_FOR_DEBUGGING
-#ifdef SIMPLE_ARENA_FOR_DEBUGGING
-
-struct gpr_arena {
-  gpr_arena() { gpr_mu_init(&mu); }
-  ~gpr_arena() {
-    gpr_mu_destroy(&mu);
-    for (size_t i = 0; i < num_ptrs; ++i) {
-      gpr_free_aligned(ptrs[i]);
-    }
-    gpr_free(ptrs);
-  }
-
-  gpr_mu mu;
-  void** ptrs = nullptr;
-  size_t num_ptrs = 0;
-};
-
-gpr_arena* gpr_arena_create(size_t ignored_initial_size) {
-  return grpc_core::New<gpr_arena>();
-}
-
-size_t gpr_arena_destroy(gpr_arena* arena) {
-  grpc_core::Delete(arena);
-  return 1;  // Value doesn't matter, since it won't be used.
-}
-
-void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
-  gpr_mu_lock(&arena->mu);
-  arena->ptrs =
-      (void**)gpr_realloc(arena->ptrs, sizeof(void*) * (arena->num_ptrs + 1));
-  void* retval = arena->ptrs[arena->num_ptrs++] = gpr_arena_malloc(size);
-  gpr_mu_unlock(&arena->mu);
-  return retval;
-}
-
-#else  // SIMPLE_ARENA_FOR_DEBUGGING
-
-// TODO(roth): We currently assume that all callers need alignment of 16
-// bytes, which may be wrong in some cases.  As part of converting the
-// arena API to C++, we should consider replacing gpr_arena_alloc() with a
-// template that takes the type of the value being allocated, which
-// would allow us to use the alignment actually needed by the caller.
-
-typedef struct zone {
-  zone* next = nullptr;
-} zone;
-
-struct gpr_arena {
-  gpr_arena(size_t initial_size)
-      : initial_zone_size(initial_size), last_zone(&initial_zone) {
-    gpr_mu_init(&arena_growth_mutex);
-  }
-  ~gpr_arena() {
-    gpr_mu_destroy(&arena_growth_mutex);
-    zone* z = initial_zone.next;
-    while (z) {
-      zone* next_z = z->next;
-      z->~zone();
-      gpr_free_aligned(z);
-      z = next_z;
-    }
-  }
-
-  // Keep track of the total used size. We use this in our call sizing
-  // historesis.
-  gpr_atm total_used = 0;
-  size_t initial_zone_size;
-  zone initial_zone;
-  zone* last_zone;
-  gpr_mu arena_growth_mutex;
-};
-
-gpr_arena* gpr_arena_create(size_t initial_size) {
-  initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size);
-  return new (gpr_arena_malloc(
-      GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + initial_size))
-      gpr_arena(initial_size);
-}
-
-size_t gpr_arena_destroy(gpr_arena* arena) {
-  const gpr_atm size = gpr_atm_no_barrier_load(&arena->total_used);
-  arena->~gpr_arena();
-  gpr_free_aligned(arena);
-  return static_cast<size_t>(size);
-}
-
-void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
-  size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size);
-  size_t begin = gpr_atm_no_barrier_fetch_add(&arena->total_used, size);
-  if (begin + size <= arena->initial_zone_size) {
-    return reinterpret_cast<char*>(arena) +
-           GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + begin;
-  } else {
-    // If the allocation isn't able to end in the initial zone, create a new
-    // zone for this allocation, and any unused space in the initial zone is
-    // wasted. This overflowing and wasting is uncommon because of our arena
-    // sizing historesis (that is, most calls should have a large enough initial
-    // zone and will not need to grow the arena).
-    gpr_mu_lock(&arena->arena_growth_mutex);
-    zone* z = new (gpr_arena_malloc(
-        GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + size)) zone();
-    arena->last_zone->next = z;
-    arena->last_zone = z;
-    gpr_mu_unlock(&arena->arena_growth_mutex);
-    return reinterpret_cast<char*>(z) +
-           GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone));
-  }
-}
-
-#endif  // SIMPLE_ARENA_FOR_DEBUGGING

+ 13 - 7
src/core/lib/gpr/arena.h

@@ -21,21 +21,27 @@
 // the arena as a whole is freed
 // the arena as a whole is freed
 // Tracks the total memory allocated against it, so that future arenas can
 // Tracks the total memory allocated against it, so that future arenas can
 // pre-allocate the right amount of memory
 // pre-allocate the right amount of memory
+// This transitional API is deprecated and will be removed soon in favour of
+// src/core/lib/gprpp/arena.h .
 
 
 #ifndef GRPC_CORE_LIB_GPR_ARENA_H
 #ifndef GRPC_CORE_LIB_GPR_ARENA_H
 #define GRPC_CORE_LIB_GPR_ARENA_H
 #define GRPC_CORE_LIB_GPR_ARENA_H
 
 
 #include <grpc/support/port_platform.h>
 #include <grpc/support/port_platform.h>
 
 
-#include <stddef.h>
-
-typedef struct gpr_arena gpr_arena;
+#include "src/core/lib/gprpp/arena.h"
 
 
+// TODO(arjunroy) : Remove deprecated gpr_arena API once all callers are gone.
+typedef class grpc_core::Arena gpr_arena;
 // Create an arena, with \a initial_size bytes in the first allocated buffer
 // Create an arena, with \a initial_size bytes in the first allocated buffer
-gpr_arena* gpr_arena_create(size_t initial_size);
-// Allocate \a size bytes from the arena
-void* gpr_arena_alloc(gpr_arena* arena, size_t size);
+inline gpr_arena* gpr_arena_create(size_t initial_size) {
+  return grpc_core::Arena::Create(initial_size);
+}
 // Destroy an arena, returning the total number of bytes allocated
 // Destroy an arena, returning the total number of bytes allocated
-size_t gpr_arena_destroy(gpr_arena* arena);
+inline size_t gpr_arena_destroy(gpr_arena* arena) { return arena->Destroy(); }
+// Allocate \a size bytes from the arena
+inline void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
+  return arena->Alloc(size);
+}
 
 
 #endif /* GRPC_CORE_LIB_GPR_ARENA_H */
 #endif /* GRPC_CORE_LIB_GPR_ARENA_H */

+ 90 - 0
src/core/lib/gprpp/arena.cc

@@ -0,0 +1,90 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/gprpp/arena.h"
+
+#include <string.h>
+#include <new>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/atm.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+
+#include "src/core/lib/gpr/alloc.h"
+#include "src/core/lib/gprpp/memory.h"
+
+template <size_t alignment>
+static void* gpr_arena_malloc(size_t size) {
+  return gpr_malloc_aligned(size, alignment);
+}
+
+namespace grpc_core {
+
+Arena::~Arena() {
+  Zone* z = last_zone_;
+  while (z) {
+    Zone* prev_z = z->prev;
+    z->~Zone();
+    gpr_free_aligned(z);
+    z = prev_z;
+  }
+}
+
+Arena* Arena::Create(size_t initial_size) {
+  static constexpr size_t base_size =
+      GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Arena));
+  initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size);
+  size_t alloc_size = base_size + initial_size;
+  static constexpr size_t alignment =
+      (GPR_CACHELINE_SIZE > GPR_MAX_ALIGNMENT &&
+       GPR_CACHELINE_SIZE % GPR_MAX_ALIGNMENT == 0)
+          ? GPR_CACHELINE_SIZE
+          : GPR_MAX_ALIGNMENT;
+  return new (gpr_arena_malloc<alignment>(alloc_size)) Arena(initial_size);
+}
+
+size_t Arena::Destroy() {
+  size_t size = total_used_.Load(MemoryOrder::RELAXED);
+  this->~Arena();
+  gpr_free_aligned(this);
+  return size;
+}
+
+void* Arena::AllocZone(size_t size) {
+  // If the allocation isn't able to end in the initial zone, create a new
+  // zone for this allocation, and any unused space in the initial zone is
+  // wasted. This overflowing and wasting is uncommon because of our arena
+  // sizing hysteresis (that is, most calls should have a large enough initial
+  // zone and will not need to grow the arena).
+  static constexpr size_t zone_base_size =
+      GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Zone));
+  size_t alloc_size = zone_base_size + size;
+  Zone* z = new (gpr_arena_malloc<GPR_MAX_ALIGNMENT>(alloc_size)) Zone();
+  {
+    gpr_spinlock_lock(&arena_growth_spinlock_);
+    z->prev = last_zone_;
+    last_zone_ = z;
+    gpr_spinlock_unlock(&arena_growth_spinlock_);
+  }
+  return reinterpret_cast<char*>(z) + zone_base_size;
+}
+
+}  // namespace grpc_core

+ 99 - 0
src/core/lib/gprpp/arena.h

@@ -0,0 +1,99 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// \file Arena based allocator
+// Allows very fast allocation of memory, but that memory cannot be freed until
+// the arena as a whole is freed
+// Tracks the total memory allocated against it, so that future arenas can
+// pre-allocate the right amount of memory
+
+#ifndef GRPC_CORE_LIB_GPRPP_ARENA_H
+#define GRPC_CORE_LIB_GPRPP_ARENA_H
+
+#include <grpc/support/port_platform.h>
+
+#include <new>
+#include <utility>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/sync.h>
+
+#include "src/core/lib/gpr/alloc.h"
+#include "src/core/lib/gpr/spinlock.h"
+#include "src/core/lib/gprpp/atomic.h"
+
+#include <stddef.h>
+
+namespace grpc_core {
+
+class Arena {
+ public:
+  // Create an arena, with \a initial_size bytes in the first allocated buffer.
+  static Arena* Create(size_t initial_size);
+  // Destroy an arena, returning the total number of bytes allocated.
+  size_t Destroy();
+  // Allocate \a size bytes from the arena.
+  void* Alloc(size_t size) {
+    static constexpr size_t base_size =
+        GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Arena));
+    size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size);
+    size_t begin = total_used_.FetchAdd(size, MemoryOrder::RELAXED);
+    if (begin + size <= initial_zone_size_) {
+      return reinterpret_cast<char*>(this) + base_size + begin;
+    } else {
+      return AllocZone(size);
+    }
+  }
+
+  // TODO(roth): We currently assume that all callers need alignment of 16
+  // bytes, which may be wrong in some cases. When we have time, we should
+  // change this to instead use the alignment of the type being allocated by
+  // this method.
+  template <typename T, typename... Args>
+  T* New(Args&&... args) {
+    T* t = static_cast<T*>(Alloc(sizeof(T)));
+    new (t) T(std::forward<Args>(args)...);
+    return t;
+  }
+
+ private:
+  struct Zone {
+    Zone* prev;
+  };
+
+  explicit Arena(size_t initial_size) : initial_zone_size_(initial_size) {}
+  ~Arena();
+
+  void* AllocZone(size_t size);
+
+  // Keep track of the total used size. We use this in our call sizing
+  // hysteresis.
+  Atomic<size_t> total_used_;
+  size_t initial_zone_size_;
+  gpr_spinlock arena_growth_spinlock_ = GPR_SPINLOCK_STATIC_INITIALIZER;
+  // If the initial arena allocation wasn't enough, we allocate additional zones
+  // in a reverse linked list. Each additional zone consists of (1) a pointer to
+  // the zone added before this zone (null if this is the first additional zone)
+  // and (2) the allocated memory. The arena itself maintains a pointer to the
+  // last zone; the zone list is reverse-walked during arena destruction only.
+  Zone* last_zone_ = nullptr;
+};
+
+}  // namespace grpc_core
+
+#endif /* GRPC_CORE_LIB_GPRPP_ARENA_H */

+ 1 - 1
src/core/lib/iomgr/internal_errqueue.cc

@@ -36,7 +36,7 @@ static bool errqueue_supported = false;
 bool kernel_supports_errqueue() { return errqueue_supported; }
 bool kernel_supports_errqueue() { return errqueue_supported; }
 
 
 void grpc_errqueue_init() {
 void grpc_errqueue_init() {
-/* Both-compile time and run-time linux kernel versions should be atleast 4.0.0
+/* Both-compile time and run-time linux kernel versions should be at least 4.0.0
  */
  */
 #ifdef GRPC_LINUX_ERRQUEUE
 #ifdef GRPC_LINUX_ERRQUEUE
   struct utsname buffer;
   struct utsname buffer;

+ 1 - 1
src/core/lib/iomgr/timer_generic.cc

@@ -487,7 +487,7 @@ static void timer_cancel(grpc_timer* timer) {
 /* Rebalances the timer shard by computing a new 'queue_deadline_cap' and moving
 /* Rebalances the timer shard by computing a new 'queue_deadline_cap' and moving
    all relevant timers in shard->list (i.e timers with deadlines earlier than
    all relevant timers in shard->list (i.e timers with deadlines earlier than
    'queue_deadline_cap') into into shard->heap.
    'queue_deadline_cap') into into shard->heap.
-   Returns 'true' if shard->heap has atleast ONE element
+   Returns 'true' if shard->heap has at least ONE element
    REQUIRES: shard->mu locked */
    REQUIRES: shard->mu locked */
 static bool refill_heap(timer_shard* shard, grpc_millis now) {
 static bool refill_heap(timer_shard* shard, grpc_millis now) {
   /* Compute the new queue window width and bound by the limits: */
   /* Compute the new queue window width and bound by the limits: */

+ 6 - 7
src/core/lib/security/context/security_context.cc

@@ -21,8 +21,8 @@
 #include <string.h>
 #include <string.h>
 
 
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/gpr/arena.h"
 #include "src/core/lib/gpr/string.h"
 #include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/arena.h"
 #include "src/core/lib/gprpp/ref_counted.h"
 #include "src/core/lib/gprpp/ref_counted.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/security/context/security_context.h"
@@ -102,9 +102,9 @@ grpc_client_security_context::~grpc_client_security_context() {
 }
 }
 
 
 grpc_client_security_context* grpc_client_security_context_create(
 grpc_client_security_context* grpc_client_security_context_create(
-    gpr_arena* arena, grpc_call_credentials* creds) {
-  return new (gpr_arena_alloc(arena, sizeof(grpc_client_security_context)))
-      grpc_client_security_context(creds != nullptr ? creds->Ref() : nullptr);
+    grpc_core::Arena* arena, grpc_call_credentials* creds) {
+  return arena->New<grpc_client_security_context>(
+      creds != nullptr ? creds->Ref() : nullptr);
 }
 }
 
 
 void grpc_client_security_context_destroy(void* ctx) {
 void grpc_client_security_context_destroy(void* ctx) {
@@ -123,9 +123,8 @@ grpc_server_security_context::~grpc_server_security_context() {
 }
 }
 
 
 grpc_server_security_context* grpc_server_security_context_create(
 grpc_server_security_context* grpc_server_security_context_create(
-    gpr_arena* arena) {
-  return new (gpr_arena_alloc(arena, sizeof(grpc_server_security_context)))
-      grpc_server_security_context();
+    grpc_core::Arena* arena) {
+  return arena->New<grpc_server_security_context>();
 }
 }
 
 
 void grpc_server_security_context_destroy(void* ctx) {
 void grpc_server_security_context_destroy(void* ctx) {

+ 3 - 4
src/core/lib/security/context/security_context.h

@@ -21,6 +21,7 @@
 
 
 #include <grpc/support/port_platform.h>
 #include <grpc/support/port_platform.h>
 
 
+#include "src/core/lib/gprpp/arena.h"
 #include "src/core/lib/gprpp/ref_counted.h"
 #include "src/core/lib/gprpp/ref_counted.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/iomgr/pollset.h"
 #include "src/core/lib/iomgr/pollset.h"
@@ -28,8 +29,6 @@
 
 
 extern grpc_core::DebugOnlyTraceFlag grpc_trace_auth_context_refcount;
 extern grpc_core::DebugOnlyTraceFlag grpc_trace_auth_context_refcount;
 
 
-struct gpr_arena;
-
 /* --- grpc_auth_context ---
 /* --- grpc_auth_context ---
 
 
    High level authentication context object. Can optionally be chained. */
    High level authentication context object. Can optionally be chained. */
@@ -121,7 +120,7 @@ struct grpc_client_security_context {
 };
 };
 
 
 grpc_client_security_context* grpc_client_security_context_create(
 grpc_client_security_context* grpc_client_security_context_create(
-    gpr_arena* arena, grpc_call_credentials* creds);
+    grpc_core::Arena* arena, grpc_call_credentials* creds);
 void grpc_client_security_context_destroy(void* ctx);
 void grpc_client_security_context_destroy(void* ctx);
 
 
 /* --- grpc_server_security_context ---
 /* --- grpc_server_security_context ---
@@ -137,7 +136,7 @@ struct grpc_server_security_context {
 };
 };
 
 
 grpc_server_security_context* grpc_server_security_context_create(
 grpc_server_security_context* grpc_server_security_context_create(
-    gpr_arena* arena);
+    grpc_core::Arena* arena);
 void grpc_server_security_context_destroy(void* ctx);
 void grpc_server_security_context_destroy(void* ctx);
 
 
 /* --- Channel args for auth context --- */
 /* --- Channel args for auth context --- */

+ 21 - 21
src/core/lib/surface/call.cc

@@ -35,9 +35,9 @@
 #include "src/core/lib/compression/algorithm_metadata.h"
 #include "src/core/lib/compression/algorithm_metadata.h"
 #include "src/core/lib/debug/stats.h"
 #include "src/core/lib/debug/stats.h"
 #include "src/core/lib/gpr/alloc.h"
 #include "src/core/lib/gpr/alloc.h"
-#include "src/core/lib/gpr/arena.h"
 #include "src/core/lib/gpr/string.h"
 #include "src/core/lib/gpr/string.h"
 #include "src/core/lib/gpr/useful.h"
 #include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/gprpp/arena.h"
 #include "src/core/lib/gprpp/manual_constructor.h"
 #include "src/core/lib/gprpp/manual_constructor.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/profiling/timers.h"
@@ -124,7 +124,7 @@ struct child_call {
 #define RECV_INITIAL_METADATA_FIRST ((gpr_atm)1)
 #define RECV_INITIAL_METADATA_FIRST ((gpr_atm)1)
 
 
 struct grpc_call {
 struct grpc_call {
-  grpc_call(gpr_arena* arena, const grpc_call_create_args& args)
+  grpc_call(grpc_core::Arena* arena, const grpc_call_create_args& args)
       : arena(arena),
       : arena(arena),
         cq(args.cq),
         cq(args.cq),
         channel(args.channel),
         channel(args.channel),
@@ -143,7 +143,7 @@ struct grpc_call {
   }
   }
 
 
   gpr_refcount ext_ref;
   gpr_refcount ext_ref;
-  gpr_arena* arena;
+  grpc_core::Arena* arena;
   grpc_core::CallCombiner call_combiner;
   grpc_core::CallCombiner call_combiner;
   grpc_completion_queue* cq;
   grpc_completion_queue* cq;
   grpc_polling_entity pollent;
   grpc_polling_entity pollent;
@@ -290,13 +290,13 @@ static void add_init_error(grpc_error** composite, grpc_error* new_err) {
 }
 }
 
 
 void* grpc_call_arena_alloc(grpc_call* call, size_t size) {
 void* grpc_call_arena_alloc(grpc_call* call, size_t size) {
-  return gpr_arena_alloc(call->arena, size);
+  return call->arena->Alloc(size);
 }
 }
 
 
 static parent_call* get_or_create_parent_call(grpc_call* call) {
 static parent_call* get_or_create_parent_call(grpc_call* call) {
   parent_call* p = (parent_call*)gpr_atm_acq_load(&call->parent_call_atm);
   parent_call* p = (parent_call*)gpr_atm_acq_load(&call->parent_call_atm);
   if (p == nullptr) {
   if (p == nullptr) {
-    p = new (gpr_arena_alloc(call->arena, sizeof(*p))) parent_call();
+    p = call->arena->New<parent_call>();
     if (!gpr_atm_rel_cas(&call->parent_call_atm, (gpr_atm) nullptr,
     if (!gpr_atm_rel_cas(&call->parent_call_atm, (gpr_atm) nullptr,
                          (gpr_atm)p)) {
                          (gpr_atm)p)) {
       p->~parent_call();
       p->~parent_call();
@@ -327,10 +327,10 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args,
   grpc_call* call;
   grpc_call* call;
   size_t initial_size = grpc_channel_get_call_size_estimate(args->channel);
   size_t initial_size = grpc_channel_get_call_size_estimate(args->channel);
   GRPC_STATS_INC_CALL_INITIAL_SIZE(initial_size);
   GRPC_STATS_INC_CALL_INITIAL_SIZE(initial_size);
-  gpr_arena* arena = gpr_arena_create(initial_size);
-  call = new (gpr_arena_alloc(
-      arena, GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) +
-                 channel_stack->call_stack_size)) grpc_call(arena, *args);
+  grpc_core::Arena* arena = grpc_core::Arena::Create(initial_size);
+  call = new (arena->Alloc(GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) +
+                           channel_stack->call_stack_size))
+      grpc_call(arena, *args);
   *out_call = call;
   *out_call = call;
   grpc_slice path = grpc_empty_slice();
   grpc_slice path = grpc_empty_slice();
   if (call->is_client) {
   if (call->is_client) {
@@ -362,8 +362,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args,
   bool immediately_cancel = false;
   bool immediately_cancel = false;
 
 
   if (args->parent != nullptr) {
   if (args->parent != nullptr) {
-    call->child = new (gpr_arena_alloc(arena, sizeof(child_call)))
-        child_call(args->parent);
+    call->child = arena->New<child_call>(args->parent);
 
 
     GRPC_CALL_INTERNAL_REF(args->parent, "child");
     GRPC_CALL_INTERNAL_REF(args->parent, "child");
     GPR_ASSERT(call->is_client);
     GPR_ASSERT(call->is_client);
@@ -500,9 +499,9 @@ void grpc_call_internal_unref(grpc_call* c REF_ARG) {
 static void release_call(void* call, grpc_error* error) {
 static void release_call(void* call, grpc_error* error) {
   grpc_call* c = static_cast<grpc_call*>(call);
   grpc_call* c = static_cast<grpc_call*>(call);
   grpc_channel* channel = c->channel;
   grpc_channel* channel = c->channel;
-  gpr_arena* arena = c->arena;
+  grpc_core::Arena* arena = c->arena;
   c->~grpc_call();
   c->~grpc_call();
-  grpc_channel_update_call_size_estimate(channel, gpr_arena_destroy(arena));
+  grpc_channel_update_call_size_estimate(channel, arena->Destroy());
   GRPC_CHANNEL_INTERNAL_UNREF(channel, "call");
   GRPC_CHANNEL_INTERNAL_UNREF(channel, "call");
 }
 }
 
 
@@ -1067,7 +1066,7 @@ static void recv_trailing_filter(void* args, grpc_metadata_batch* b,
   publish_app_metadata(call, b, true);
   publish_app_metadata(call, b, true);
 }
 }
 
 
-gpr_arena* grpc_call_get_arena(grpc_call* call) { return call->arena; }
+grpc_core::Arena* grpc_call_get_arena(grpc_call* call) { return call->arena; }
 
 
 grpc_call_stack* grpc_call_get_call_stack(grpc_call* call) {
 grpc_call_stack* grpc_call_get_call_stack(grpc_call* call) {
   return CALL_STACK_FROM_CALL(call);
   return CALL_STACK_FROM_CALL(call);
@@ -1128,8 +1127,7 @@ static batch_control* reuse_or_allocate_batch_control(grpc_call* call,
     bctl->~batch_control();
     bctl->~batch_control();
     bctl->op = {};
     bctl->op = {};
   } else {
   } else {
-    bctl = new (gpr_arena_alloc(call->arena, sizeof(batch_control)))
-        batch_control();
+    bctl = call->arena->New<batch_control>();
     *pslot = bctl;
     *pslot = bctl;
   }
   }
   bctl->call = call;
   bctl->call = call;
@@ -1557,7 +1555,10 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops,
           goto done_with_error;
           goto done_with_error;
         }
         }
         /* process compression level */
         /* process compression level */
-        memset(&call->compression_md, 0, sizeof(call->compression_md));
+        grpc_metadata& compression_md = call->compression_md;
+        compression_md.key = grpc_empty_slice();
+        compression_md.value = grpc_empty_slice();
+        compression_md.flags = 0;
         size_t additional_metadata_count = 0;
         size_t additional_metadata_count = 0;
         grpc_compression_level effective_compression_level =
         grpc_compression_level effective_compression_level =
             GRPC_COMPRESS_LEVEL_NONE;
             GRPC_COMPRESS_LEVEL_NONE;
@@ -1580,8 +1581,8 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops,
                   call, effective_compression_level);
                   call, effective_compression_level);
           /* the following will be picked up by the compress filter and used
           /* the following will be picked up by the compress filter and used
            * as the call's compression algorithm. */
            * as the call's compression algorithm. */
-          call->compression_md.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST;
-          call->compression_md.value = grpc_compression_algorithm_slice(calgo);
+          compression_md.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST;
+          compression_md.value = grpc_compression_algorithm_slice(calgo);
           additional_metadata_count++;
           additional_metadata_count++;
         }
         }
 
 
@@ -1595,8 +1596,7 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops,
         if (!prepare_application_metadata(
         if (!prepare_application_metadata(
                 call, static_cast<int>(op->data.send_initial_metadata.count),
                 call, static_cast<int>(op->data.send_initial_metadata.count),
                 op->data.send_initial_metadata.metadata, 0, call->is_client,
                 op->data.send_initial_metadata.metadata, 0, call->is_client,
-                &call->compression_md,
-                static_cast<int>(additional_metadata_count))) {
+                &compression_md, static_cast<int>(additional_metadata_count))) {
           error = GRPC_CALL_ERROR_INVALID_METADATA;
           error = GRPC_CALL_ERROR_INVALID_METADATA;
           goto done_with_error;
           goto done_with_error;
         }
         }

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

@@ -23,6 +23,7 @@
 
 
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/channel/context.h"
 #include "src/core/lib/channel/context.h"
+#include "src/core/lib/gprpp/arena.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/api_trace.h"
 
 
 #include <grpc/grpc.h>
 #include <grpc/grpc.h>
@@ -72,7 +73,7 @@ void grpc_call_internal_unref(grpc_call* call);
 #define GRPC_CALL_INTERNAL_UNREF(call, reason) grpc_call_internal_unref(call)
 #define GRPC_CALL_INTERNAL_UNREF(call, reason) grpc_call_internal_unref(call)
 #endif
 #endif
 
 
-gpr_arena* grpc_call_get_arena(grpc_call* call);
+grpc_core::Arena* grpc_call_get_arena(grpc_call* call);
 
 
 grpc_call_stack* grpc_call_get_call_stack(grpc_call* call);
 grpc_call_stack* grpc_call_get_call_stack(grpc_call* call);
 
 

+ 0 - 1
src/core/lib/surface/call_details.cc

@@ -29,7 +29,6 @@
 
 
 void grpc_call_details_init(grpc_call_details* cd) {
 void grpc_call_details_init(grpc_call_details* cd) {
   GRPC_API_TRACE("grpc_call_details_init(cd=%p)", 1, (cd));
   GRPC_API_TRACE("grpc_call_details_init(cd=%p)", 1, (cd));
-  memset(cd, 0, sizeof(*cd));
   cd->method = grpc_empty_slice();
   cd->method = grpc_empty_slice();
   cd->host = grpc_empty_slice();
   cd->host = grpc_empty_slice();
 }
 }

+ 7 - 7
src/core/lib/surface/completion_queue.cc

@@ -1002,15 +1002,15 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline,
         continue;
         continue;
       }
       }
 
 
-      memset(&ret, 0, sizeof(ret));
       ret.type = GRPC_QUEUE_SHUTDOWN;
       ret.type = GRPC_QUEUE_SHUTDOWN;
+      ret.success = 0;
       break;
       break;
     }
     }
 
 
     if (!is_finished_arg.first_loop &&
     if (!is_finished_arg.first_loop &&
         grpc_core::ExecCtx::Get()->Now() >= deadline_millis) {
         grpc_core::ExecCtx::Get()->Now() >= deadline_millis) {
-      memset(&ret, 0, sizeof(ret));
       ret.type = GRPC_QUEUE_TIMEOUT;
       ret.type = GRPC_QUEUE_TIMEOUT;
+      ret.success = 0;
       dump_pending_tags(cq);
       dump_pending_tags(cq);
       break;
       break;
     }
     }
@@ -1027,8 +1027,8 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline,
       gpr_log(GPR_ERROR, "Completion queue next failed: %s", msg);
       gpr_log(GPR_ERROR, "Completion queue next failed: %s", msg);
 
 
       GRPC_ERROR_UNREF(err);
       GRPC_ERROR_UNREF(err);
-      memset(&ret, 0, sizeof(ret));
       ret.type = GRPC_QUEUE_TIMEOUT;
       ret.type = GRPC_QUEUE_TIMEOUT;
+      ret.success = 0;
       dump_pending_tags(cq);
       dump_pending_tags(cq);
       break;
       break;
     }
     }
@@ -1234,8 +1234,8 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag,
     }
     }
     if (cqd->shutdown.Load(grpc_core::MemoryOrder::RELAXED)) {
     if (cqd->shutdown.Load(grpc_core::MemoryOrder::RELAXED)) {
       gpr_mu_unlock(cq->mu);
       gpr_mu_unlock(cq->mu);
-      memset(&ret, 0, sizeof(ret));
       ret.type = GRPC_QUEUE_SHUTDOWN;
       ret.type = GRPC_QUEUE_SHUTDOWN;
+      ret.success = 0;
       break;
       break;
     }
     }
     if (!add_plucker(cq, tag, &worker)) {
     if (!add_plucker(cq, tag, &worker)) {
@@ -1244,9 +1244,9 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag,
               "is %d",
               "is %d",
               GRPC_MAX_COMPLETION_QUEUE_PLUCKERS);
               GRPC_MAX_COMPLETION_QUEUE_PLUCKERS);
       gpr_mu_unlock(cq->mu);
       gpr_mu_unlock(cq->mu);
-      memset(&ret, 0, sizeof(ret));
       /* TODO(ctiller): should we use a different result here */
       /* TODO(ctiller): should we use a different result here */
       ret.type = GRPC_QUEUE_TIMEOUT;
       ret.type = GRPC_QUEUE_TIMEOUT;
+      ret.success = 0;
       dump_pending_tags(cq);
       dump_pending_tags(cq);
       break;
       break;
     }
     }
@@ -1254,8 +1254,8 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag,
         grpc_core::ExecCtx::Get()->Now() >= deadline_millis) {
         grpc_core::ExecCtx::Get()->Now() >= deadline_millis) {
       del_plucker(cq, tag, &worker);
       del_plucker(cq, tag, &worker);
       gpr_mu_unlock(cq->mu);
       gpr_mu_unlock(cq->mu);
-      memset(&ret, 0, sizeof(ret));
       ret.type = GRPC_QUEUE_TIMEOUT;
       ret.type = GRPC_QUEUE_TIMEOUT;
+      ret.success = 0;
       dump_pending_tags(cq);
       dump_pending_tags(cq);
       break;
       break;
     }
     }
@@ -1269,8 +1269,8 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag,
       gpr_log(GPR_ERROR, "Completion queue pluck failed: %s", msg);
       gpr_log(GPR_ERROR, "Completion queue pluck failed: %s", msg);
 
 
       GRPC_ERROR_UNREF(err);
       GRPC_ERROR_UNREF(err);
-      memset(&ret, 0, sizeof(ret));
       ret.type = GRPC_QUEUE_TIMEOUT;
       ret.type = GRPC_QUEUE_TIMEOUT;
+      ret.success = 0;
       dump_pending_tags(cq);
       dump_pending_tags(cq);
       break;
       break;
     }
     }

+ 3 - 2
src/core/lib/surface/server.cc

@@ -347,8 +347,8 @@ static void channel_broadcaster_shutdown(channel_broadcaster* cb,
  */
  */
 
 
 static void request_matcher_init(request_matcher* rm, grpc_server* server) {
 static void request_matcher_init(request_matcher* rm, grpc_server* server) {
-  memset(rm, 0, sizeof(*rm));
   rm->server = server;
   rm->server = server;
+  rm->pending_head = rm->pending_tail = nullptr;
   rm->requests_per_cq = static_cast<gpr_locked_mpscq*>(
   rm->requests_per_cq = static_cast<gpr_locked_mpscq*>(
       gpr_malloc(sizeof(*rm->requests_per_cq) * server->cq_count));
       gpr_malloc(sizeof(*rm->requests_per_cq) * server->cq_count));
   for (size_t i = 0; i < server->cq_count; i++) {
   for (size_t i = 0; i < server->cq_count; i++) {
@@ -601,8 +601,9 @@ static void finish_start_new_rpc(
       break;
       break;
     case GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER: {
     case GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER: {
       grpc_op op;
       grpc_op op;
-      memset(&op, 0, sizeof(op));
       op.op = GRPC_OP_RECV_MESSAGE;
       op.op = GRPC_OP_RECV_MESSAGE;
+      op.flags = 0;
+      op.reserved = nullptr;
       op.data.recv_message.recv_message = &calld->payload;
       op.data.recv_message.recv_message = &calld->payload;
       GRPC_CLOSURE_INIT(&calld->publish, publish_new_rpc, elem,
       GRPC_CLOSURE_INIT(&calld->publish, publish_new_rpc, elem,
                         grpc_schedule_on_exec_ctx);
                         grpc_schedule_on_exec_ctx);

+ 2 - 1
src/core/lib/transport/transport.cc

@@ -124,7 +124,8 @@ void grpc_transport_destroy(grpc_transport* transport) {
 
 
 int grpc_transport_init_stream(grpc_transport* transport, grpc_stream* stream,
 int grpc_transport_init_stream(grpc_transport* transport, grpc_stream* stream,
                                grpc_stream_refcount* refcount,
                                grpc_stream_refcount* refcount,
-                               const void* server_data, gpr_arena* arena) {
+                               const void* server_data,
+                               grpc_core::Arena* arena) {
   return transport->vtable->init_stream(transport, stream, refcount,
   return transport->vtable->init_stream(transport, stream, refcount,
                                         server_data, arena);
                                         server_data, arena);
 }
 }

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

@@ -24,7 +24,7 @@
 #include <stddef.h>
 #include <stddef.h>
 
 
 #include "src/core/lib/channel/context.h"
 #include "src/core/lib/channel/context.h"
-#include "src/core/lib/gpr/arena.h"
+#include "src/core/lib/gprpp/arena.h"
 #include "src/core/lib/iomgr/call_combiner.h"
 #include "src/core/lib/iomgr/call_combiner.h"
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/iomgr/polling_entity.h"
@@ -358,7 +358,8 @@ size_t grpc_transport_stream_size(grpc_transport* transport);
                    supplied from the accept_stream callback function */
                    supplied from the accept_stream callback function */
 int grpc_transport_init_stream(grpc_transport* transport, grpc_stream* stream,
 int grpc_transport_init_stream(grpc_transport* transport, grpc_stream* stream,
                                grpc_stream_refcount* refcount,
                                grpc_stream_refcount* refcount,
-                               const void* server_data, gpr_arena* arena);
+                               const void* server_data,
+                               grpc_core::Arena* arena);
 
 
 void grpc_transport_set_pops(grpc_transport* transport, grpc_stream* stream,
 void grpc_transport_set_pops(grpc_transport* transport, grpc_stream* stream,
                              grpc_polling_entity* pollent);
                              grpc_polling_entity* pollent);

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

@@ -34,7 +34,7 @@ typedef struct grpc_transport_vtable {
   /* implementation of grpc_transport_init_stream */
   /* implementation of grpc_transport_init_stream */
   int (*init_stream)(grpc_transport* self, grpc_stream* stream,
   int (*init_stream)(grpc_transport* self, grpc_stream* stream,
                      grpc_stream_refcount* refcount, const void* server_data,
                      grpc_stream_refcount* refcount, const void* server_data,
-                     gpr_arena* arena);
+                     grpc_core::Arena* arena);
 
 
   /* implementation of grpc_transport_set_pollset */
   /* implementation of grpc_transport_set_pollset */
   void (*set_pollset)(grpc_transport* self, grpc_stream* stream,
   void (*set_pollset)(grpc_transport* self, grpc_stream* stream,

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

@@ -47,7 +47,6 @@ namespace Grpc.Core.Internal.Tests
             GrpcEnvironment.ReleaseAsync().Wait();
             GrpcEnvironment.ReleaseAsync().Wait();
             Assert.AreEqual(CompletionQueueEvent.CompletionType.Shutdown, ev.type);
             Assert.AreEqual(CompletionQueueEvent.CompletionType.Shutdown, ev.type);
             Assert.AreNotEqual(IntPtr.Zero, ev.success);
             Assert.AreNotEqual(IntPtr.Zero, ev.success);
-            Assert.AreEqual(IntPtr.Zero, ev.tag);
         }
         }
     }
     }
 }
 }

+ 31 - 16
src/objective-c/GRPCClient/GRPCCall.h

@@ -34,6 +34,7 @@
 
 
 #import <Foundation/Foundation.h>
 #import <Foundation/Foundation.h>
 #import <RxLibrary/GRXWriter.h>
 #import <RxLibrary/GRXWriter.h>
+#include <grpc/status.h>
 
 
 #include <AvailabilityMacros.h>
 #include <AvailabilityMacros.h>
 
 
@@ -53,20 +54,20 @@ extern NSString *const kGRPCErrorDomain;
  */
  */
 typedef NS_ENUM(NSUInteger, GRPCErrorCode) {
 typedef NS_ENUM(NSUInteger, GRPCErrorCode) {
   /** The operation was cancelled (typically by the caller). */
   /** The operation was cancelled (typically by the caller). */
-  GRPCErrorCodeCancelled = 1,
+  GRPCErrorCodeCancelled = GRPC_STATUS_CANCELLED,
 
 
   /**
   /**
    * Unknown error. Errors raised by APIs that do not return enough error information may be
    * Unknown error. Errors raised by APIs that do not return enough error information may be
    * converted to this error.
    * converted to this error.
    */
    */
-  GRPCErrorCodeUnknown = 2,
+  GRPCErrorCodeUnknown = GRPC_STATUS_UNKNOWN,
 
 
   /**
   /**
    * The client specified an invalid argument. Note that this differs from FAILED_PRECONDITION.
    * The client specified an invalid argument. Note that this differs from FAILED_PRECONDITION.
    * INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the
    * INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the
    * server (e.g., a malformed file name).
    * server (e.g., a malformed file name).
    */
    */
-  GRPCErrorCodeInvalidArgument = 3,
+  GRPCErrorCodeInvalidArgument = GRPC_STATUS_INVALID_ARGUMENT,
 
 
   /**
   /**
    * Deadline expired before operation could complete. For operations that change the state of the
    * Deadline expired before operation could complete. For operations that change the state of the
@@ -74,13 +75,13 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) {
    * example, a successful response from the server could have been delayed long enough for the
    * example, a successful response from the server could have been delayed long enough for the
    * deadline to expire.
    * deadline to expire.
    */
    */
-  GRPCErrorCodeDeadlineExceeded = 4,
+  GRPCErrorCodeDeadlineExceeded = GRPC_STATUS_DEADLINE_EXCEEDED,
 
 
   /** Some requested entity (e.g., file or directory) was not found. */
   /** Some requested entity (e.g., file or directory) was not found. */
-  GRPCErrorCodeNotFound = 5,
+  GRPCErrorCodeNotFound = GRPC_STATUS_NOT_FOUND,
 
 
   /** Some entity that we attempted to create (e.g., file or directory) already exists. */
   /** Some entity that we attempted to create (e.g., file or directory) already exists. */
-  GRPCErrorCodeAlreadyExists = 6,
+  GRPCErrorCodeAlreadyExists = GRPC_STATUS_ALREADY_EXISTS,
 
 
   /**
   /**
    * The caller does not have permission to execute the specified operation. PERMISSION_DENIED isn't
    * The caller does not have permission to execute the specified operation. PERMISSION_DENIED isn't
@@ -88,16 +89,16 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) {
    * those errors). PERMISSION_DENIED doesn't indicate a failure to identify the caller
    * those errors). PERMISSION_DENIED doesn't indicate a failure to identify the caller
    * (UNAUTHENTICATED is used instead for those errors).
    * (UNAUTHENTICATED is used instead for those errors).
    */
    */
-  GRPCErrorCodePermissionDenied = 7,
+  GRPCErrorCodePermissionDenied = GRPC_STATUS_PERMISSION_DENIED,
 
 
   /**
   /**
    * The request does not have valid authentication credentials for the operation (e.g. the caller's
    * The request does not have valid authentication credentials for the operation (e.g. the caller's
    * identity can't be verified).
    * identity can't be verified).
    */
    */
-  GRPCErrorCodeUnauthenticated = 16,
+  GRPCErrorCodeUnauthenticated = GRPC_STATUS_UNAUTHENTICATED,
 
 
   /** Some resource has been exhausted, perhaps a per-user quota. */
   /** Some resource has been exhausted, perhaps a per-user quota. */
-  GRPCErrorCodeResourceExhausted = 8,
+  GRPCErrorCodeResourceExhausted = GRPC_STATUS_RESOURCE_EXHAUSTED,
 
 
   /**
   /**
    * The RPC was rejected because the server is not in a state required for the procedure's
    * The RPC was rejected because the server is not in a state required for the procedure's
@@ -106,14 +107,14 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) {
    * performing another RPC). The details depend on the service being called, and should be found in
    * performing another RPC). The details depend on the service being called, and should be found in
    * the NSError's userInfo.
    * the NSError's userInfo.
    */
    */
-  GRPCErrorCodeFailedPrecondition = 9,
+  GRPCErrorCodeFailedPrecondition = GRPC_STATUS_FAILED_PRECONDITION,
 
 
   /**
   /**
    * The RPC was aborted, typically due to a concurrency issue like sequencer check failures,
    * The RPC was aborted, typically due to a concurrency issue like sequencer check failures,
    * transaction aborts, etc. The client should retry at a higher-level (e.g., restarting a read-
    * transaction aborts, etc. The client should retry at a higher-level (e.g., restarting a read-
    * modify-write sequence).
    * modify-write sequence).
    */
    */
-  GRPCErrorCodeAborted = 10,
+  GRPCErrorCodeAborted = GRPC_STATUS_ABORTED,
 
 
   /**
   /**
    * The RPC was attempted past the valid range. E.g., enumerating past the end of a list.
    * The RPC was attempted past the valid range. E.g., enumerating past the end of a list.
@@ -122,25 +123,25 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) {
    * to return the element at a negative index, but it will generate OUT_OF_RANGE if asked to return
    * to return the element at a negative index, but it will generate OUT_OF_RANGE if asked to return
    * the element at an index past the current size of the list.
    * the element at an index past the current size of the list.
    */
    */
-  GRPCErrorCodeOutOfRange = 11,
+  GRPCErrorCodeOutOfRange = GRPC_STATUS_OUT_OF_RANGE,
 
 
   /** The procedure is not implemented or not supported/enabled in this server. */
   /** The procedure is not implemented or not supported/enabled in this server. */
-  GRPCErrorCodeUnimplemented = 12,
+  GRPCErrorCodeUnimplemented = GRPC_STATUS_UNIMPLEMENTED,
 
 
   /**
   /**
    * Internal error. Means some invariant expected by the server application or the gRPC library has
    * Internal error. Means some invariant expected by the server application or the gRPC library has
    * been broken.
    * been broken.
    */
    */
-  GRPCErrorCodeInternal = 13,
+  GRPCErrorCodeInternal = GRPC_STATUS_INTERNAL,
 
 
   /**
   /**
    * The server is currently unavailable. This is most likely a transient condition and may be
    * The server is currently unavailable. This is most likely a transient condition and may be
    * corrected by retrying with a backoff.
    * corrected by retrying with a backoff.
    */
    */
-  GRPCErrorCodeUnavailable = 14,
+  GRPCErrorCodeUnavailable = GRPC_STATUS_UNAVAILABLE,
 
 
   /** Unrecoverable data loss or corruption. */
   /** Unrecoverable data loss or corruption. */
-  GRPCErrorCodeDataLoss = 15,
+  GRPCErrorCodeDataLoss = GRPC_STATUS_DATA_LOSS,
 };
 };
 
 
 /**
 /**
@@ -183,6 +184,12 @@ extern NSString *const kGRPCTrailersKey;
 - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata
 - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata
                                error:(nullable NSError *)error;
                                error:(nullable NSError *)error;
 
 
+/**
+ * Issued when flow control is enabled for the call and a message written with writeData: method of
+ * GRPCCall2 is passed to gRPC core with SEND_MESSAGE operation.
+ */
+- (void)didWriteData;
+
 @end
 @end
 
 
 /**
 /**
@@ -263,6 +270,14 @@ extern NSString *const kGRPCTrailersKey;
  */
  */
 - (void)finish;
 - (void)finish;
 
 
+/**
+ * Tell gRPC to receive the next N gRPC message from gRPC core.
+ *
+ * This method should only be used when flow control is enabled. When flow control is not enabled,
+ * this method is a no-op.
+ */
+- (void)receiveNextMessages:(NSUInteger)numberOfMessages;
+
 /**
 /**
  * Get a copy of the original call options.
  * Get a copy of the original call options.
  */
  */

+ 120 - 13
src/objective-c/GRPCClient/GRPCCall.m

@@ -63,6 +63,15 @@ const char *kCFStreamVarName = "grpc_cfstream";
               requestsWriter:(GRXWriter *)requestsWriter
               requestsWriter:(GRXWriter *)requestsWriter
                  callOptions:(GRPCCallOptions *)callOptions;
                  callOptions:(GRPCCallOptions *)callOptions;
 
 
+- (instancetype)initWithHost:(NSString *)host
+                        path:(NSString *)path
+                  callSafety:(GRPCCallSafety)safety
+              requestsWriter:(GRXWriter *)requestsWriter
+                 callOptions:(GRPCCallOptions *)callOptions
+                   writeDone:(void (^)(void))writeDone;
+
+- (void)receiveNextMessages:(NSUInteger)numberOfMessages;
+
 @end
 @end
 
 
 @implementation GRPCRequestOptions
 @implementation GRPCRequestOptions
@@ -113,6 +122,8 @@ const char *kCFStreamVarName = "grpc_cfstream";
   BOOL _canceled;
   BOOL _canceled;
   /** Flags whether call has been finished. */
   /** Flags whether call has been finished. */
   BOOL _finished;
   BOOL _finished;
+  /** The number of pending messages receiving requests. */
+  NSUInteger _pendingReceiveNextMessages;
 }
 }
 
 
 - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions
 - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions
@@ -190,11 +201,22 @@ const char *kCFStreamVarName = "grpc_cfstream";
                                       path:_requestOptions.path
                                       path:_requestOptions.path
                                 callSafety:_requestOptions.safety
                                 callSafety:_requestOptions.safety
                             requestsWriter:_pipe
                             requestsWriter:_pipe
-                               callOptions:_callOptions];
+                               callOptions:_callOptions
+                                 writeDone:^{
+                                   @synchronized(self) {
+                                     if (self->_handler) {
+                                       [self issueDidWriteData];
+                                     }
+                                   }
+                                 }];
     [_call setResponseDispatchQueue:_dispatchQueue];
     [_call setResponseDispatchQueue:_dispatchQueue];
     if (_callOptions.initialMetadata) {
     if (_callOptions.initialMetadata) {
       [_call.requestHeaders addEntriesFromDictionary:_callOptions.initialMetadata];
       [_call.requestHeaders addEntriesFromDictionary:_callOptions.initialMetadata];
     }
     }
+    if (_pendingReceiveNextMessages > 0) {
+      [_call receiveNextMessages:_pendingReceiveNextMessages];
+      _pendingReceiveNextMessages = 0;
+    }
     copiedCall = _call;
     copiedCall = _call;
   }
   }
 
 
@@ -364,6 +386,33 @@ const char *kCFStreamVarName = "grpc_cfstream";
   }
   }
 }
 }
 
 
+- (void)issueDidWriteData {
+  @synchronized(self) {
+    if (_callOptions.flowControlEnabled && [_handler respondsToSelector:@selector(didWriteData)]) {
+      dispatch_async(_dispatchQueue, ^{
+        id<GRPCResponseHandler> copiedHandler = nil;
+        @synchronized(self) {
+          copiedHandler = self->_handler;
+        };
+        [copiedHandler didWriteData];
+      });
+    }
+  }
+}
+
+- (void)receiveNextMessages:(NSUInteger)numberOfMessages {
+  // branching based on _callOptions.flowControlEnabled is handled inside _call
+  GRPCCall *copiedCall = nil;
+  @synchronized(self) {
+    copiedCall = _call;
+    if (copiedCall == nil) {
+      _pendingReceiveNextMessages += numberOfMessages;
+      return;
+    }
+  }
+  [copiedCall receiveNextMessages:numberOfMessages];
+}
+
 @end
 @end
 
 
 // The following methods of a C gRPC call object aren't reentrant, and thus
 // The following methods of a C gRPC call object aren't reentrant, and thus
@@ -427,6 +476,15 @@ const char *kCFStreamVarName = "grpc_cfstream";
 
 
   // The OAuth2 token fetched from a token provider.
   // The OAuth2 token fetched from a token provider.
   NSString *_fetchedOauth2AccessToken;
   NSString *_fetchedOauth2AccessToken;
+
+  // The callback to be called when a write message op is done.
+  void (^_writeDone)(void);
+
+  // Indicate a read request to core is pending.
+  BOOL _pendingCoreRead;
+
+  // Indicate pending read message request from user.
+  NSUInteger _pendingReceiveNextMessages;
 }
 }
 
 
 @synthesize state = _state;
 @synthesize state = _state;
@@ -486,12 +544,26 @@ const char *kCFStreamVarName = "grpc_cfstream";
 - (instancetype)initWithHost:(NSString *)host
 - (instancetype)initWithHost:(NSString *)host
                         path:(NSString *)path
                         path:(NSString *)path
                   callSafety:(GRPCCallSafety)safety
                   callSafety:(GRPCCallSafety)safety
-              requestsWriter:(GRXWriter *)requestWriter
+              requestsWriter:(GRXWriter *)requestsWriter
                  callOptions:(GRPCCallOptions *)callOptions {
                  callOptions:(GRPCCallOptions *)callOptions {
+  return [self initWithHost:host
+                       path:path
+                 callSafety:safety
+             requestsWriter:requestsWriter
+                callOptions:callOptions
+                  writeDone:nil];
+}
+
+- (instancetype)initWithHost:(NSString *)host
+                        path:(NSString *)path
+                  callSafety:(GRPCCallSafety)safety
+              requestsWriter:(GRXWriter *)requestsWriter
+                 callOptions:(GRPCCallOptions *)callOptions
+                   writeDone:(void (^)(void))writeDone {
   // Purposely using pointer rather than length (host.length == 0) for backwards compatibility.
   // Purposely using pointer rather than length (host.length == 0) for backwards compatibility.
   NSAssert(host != nil && path != nil, @"Neither host nor path can be nil.");
   NSAssert(host != nil && path != nil, @"Neither host nor path can be nil.");
   NSAssert(safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value.");
   NSAssert(safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value.");
-  NSAssert(requestWriter.state == GRXWriterStateNotStarted,
+  NSAssert(requestsWriter.state == GRXWriterStateNotStarted,
            @"The requests writer can't be already started.");
            @"The requests writer can't be already started.");
   if (!host || !path) {
   if (!host || !path) {
     return nil;
     return nil;
@@ -499,7 +571,7 @@ const char *kCFStreamVarName = "grpc_cfstream";
   if (safety > GRPCCallSafetyCacheableRequest) {
   if (safety > GRPCCallSafetyCacheableRequest) {
     return nil;
     return nil;
   }
   }
-  if (requestWriter.state != GRXWriterStateNotStarted) {
+  if (requestsWriter.state != GRXWriterStateNotStarted) {
     return nil;
     return nil;
   }
   }
 
 
@@ -512,16 +584,20 @@ const char *kCFStreamVarName = "grpc_cfstream";
     // Serial queue to invoke the non-reentrant methods of the grpc_call object.
     // Serial queue to invoke the non-reentrant methods of the grpc_call object.
     _callQueue = dispatch_queue_create("io.grpc.call", DISPATCH_QUEUE_SERIAL);
     _callQueue = dispatch_queue_create("io.grpc.call", DISPATCH_QUEUE_SERIAL);
 
 
-    _requestWriter = requestWriter;
-
+    _requestWriter = requestsWriter;
     _requestHeaders = [[GRPCRequestHeaders alloc] initWithCall:self];
     _requestHeaders = [[GRPCRequestHeaders alloc] initWithCall:self];
+    _writeDone = writeDone;
 
 
-    if ([requestWriter isKindOfClass:[GRXImmediateSingleWriter class]]) {
+    if ([requestsWriter isKindOfClass:[GRXImmediateSingleWriter class]]) {
       _unaryCall = YES;
       _unaryCall = YES;
       _unaryOpBatch = [NSMutableArray arrayWithCapacity:kMaxClientBatch];
       _unaryOpBatch = [NSMutableArray arrayWithCapacity:kMaxClientBatch];
     }
     }
 
 
     _responseQueue = dispatch_get_main_queue();
     _responseQueue = dispatch_get_main_queue();
+
+    // do not start a read until initial metadata is received
+    _pendingReceiveNextMessages = 0;
+    _pendingCoreRead = YES;
   }
   }
   return self;
   return self;
 }
 }
@@ -593,11 +669,16 @@ const char *kCFStreamVarName = "grpc_cfstream";
 // If the call is currently paused, this is a noop. Restarting the call will invoke this
 // If the call is currently paused, this is a noop. Restarting the call will invoke this
 // method.
 // method.
 // TODO(jcanizales): Rename to readResponseIfNotPaused.
 // TODO(jcanizales): Rename to readResponseIfNotPaused.
-- (void)startNextRead {
+- (void)maybeStartNextRead {
   @synchronized(self) {
   @synchronized(self) {
     if (_state != GRXWriterStateStarted) {
     if (_state != GRXWriterStateStarted) {
       return;
       return;
     }
     }
+    if (_callOptions.flowControlEnabled && (_pendingCoreRead || _pendingReceiveNextMessages == 0)) {
+      return;
+    }
+    _pendingCoreRead = YES;
+    _pendingReceiveNextMessages--;
   }
   }
 
 
   dispatch_async(_callQueue, ^{
   dispatch_async(_callQueue, ^{
@@ -620,6 +701,7 @@ const char *kCFStreamVarName = "grpc_cfstream";
         // that's on the hands of any server to have. Instead we finish and ask
         // that's on the hands of any server to have. Instead we finish and ask
         // the server to cancel.
         // the server to cancel.
         @synchronized(strongSelf) {
         @synchronized(strongSelf) {
+          strongSelf->_pendingCoreRead = NO;
           [strongSelf
           [strongSelf
               finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
               finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
                                                   code:GRPCErrorCodeResourceExhausted
                                                   code:GRPCErrorCodeResourceExhausted
@@ -635,7 +717,13 @@ const char *kCFStreamVarName = "grpc_cfstream";
         @synchronized(strongSelf) {
         @synchronized(strongSelf) {
           [strongSelf->_responseWriteable enqueueValue:data
           [strongSelf->_responseWriteable enqueueValue:data
                                      completionHandler:^{
                                      completionHandler:^{
-                                       [strongSelf startNextRead];
+                                       __strong GRPCCall *strongSelf = weakSelf;
+                                       if (strongSelf) {
+                                         @synchronized(strongSelf) {
+                                           strongSelf->_pendingCoreRead = NO;
+                                           [strongSelf maybeStartNextRead];
+                                         }
+                                       }
                                      }];
                                      }];
         }
         }
       }
       }
@@ -686,6 +774,20 @@ const char *kCFStreamVarName = "grpc_cfstream";
   });
   });
 }
 }
 
 
+- (void)receiveNextMessages:(NSUInteger)numberOfMessages {
+  if (numberOfMessages == 0) {
+    return;
+  }
+  @synchronized(self) {
+    _pendingReceiveNextMessages += numberOfMessages;
+
+    if (_state != GRXWriterStateStarted || !_callOptions.flowControlEnabled) {
+      return;
+    }
+    [self maybeStartNextRead];
+  }
+}
+
 #pragma mark GRXWriteable implementation
 #pragma mark GRXWriteable implementation
 
 
 // Only called from the call queue. The error handler will be called from the
 // Only called from the call queue. The error handler will be called from the
@@ -699,9 +801,11 @@ const char *kCFStreamVarName = "grpc_cfstream";
     GRPCCall *strongSelf = weakSelf;
     GRPCCall *strongSelf = weakSelf;
     if (strongSelf) {
     if (strongSelf) {
       strongSelf->_requestWriter.state = GRXWriterStateStarted;
       strongSelf->_requestWriter.state = GRXWriterStateStarted;
+      if (strongSelf->_writeDone) {
+        strongSelf->_writeDone();
+      }
     }
     }
   };
   };
-
   GRPCOpSendMessage *op =
   GRPCOpSendMessage *op =
       [[GRPCOpSendMessage alloc] initWithMessage:message handler:resumingHandler];
       [[GRPCOpSendMessage alloc] initWithMessage:message handler:resumingHandler];
   if (!_unaryCall) {
   if (!_unaryCall) {
@@ -778,8 +882,11 @@ const char *kCFStreamVarName = "grpc_cfstream";
     // Response headers received.
     // Response headers received.
     __strong GRPCCall *strongSelf = weakSelf;
     __strong GRPCCall *strongSelf = weakSelf;
     if (strongSelf) {
     if (strongSelf) {
-      strongSelf.responseHeaders = headers;
-      [strongSelf startNextRead];
+      @synchronized(strongSelf) {
+        strongSelf.responseHeaders = headers;
+        strongSelf->_pendingCoreRead = NO;
+        [strongSelf maybeStartNextRead];
+      }
     }
     }
   }
   }
       completionHandler:^(NSError *error, NSDictionary *trailers) {
       completionHandler:^(NSError *error, NSDictionary *trailers) {
@@ -933,7 +1040,7 @@ const char *kCFStreamVarName = "grpc_cfstream";
       case GRXWriterStateStarted:
       case GRXWriterStateStarted:
         if (_state == GRXWriterStatePaused) {
         if (_state == GRXWriterStatePaused) {
           _state = newState;
           _state = newState;
-          [self startNextRead];
+          [self maybeStartNextRead];
         }
         }
         return;
         return;
       case GRXWriterStateNotStarted:
       case GRXWriterStateNotStarted:

+ 21 - 0
src/objective-c/GRPCClient/GRPCCallOptions.h

@@ -90,6 +90,14 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) {
  */
  */
 @property(readonly) NSTimeInterval timeout;
 @property(readonly) NSTimeInterval timeout;
 
 
+/**
+ * Enable flow control of a gRPC call. The option is default to NO. If set to YES, writeData: method
+ * should only be called at most once before a didWriteData callback is issued, and
+ * receiveNextMessage: must be called each time before gRPC call issues a didReceiveMessage
+ * callback.
+ */
+@property(readonly) BOOL flowControlEnabled;
+
 // OAuth2 parameters. Users of gRPC may specify one of the following two parameters.
 // OAuth2 parameters. Users of gRPC may specify one of the following two parameters.
 
 
 /**
 /**
@@ -232,6 +240,19 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) {
  */
  */
 @property(readwrite) NSTimeInterval timeout;
 @property(readwrite) NSTimeInterval timeout;
 
 
+/**
+ * Enable flow control of a gRPC call. The option is default to NO. If set to YES, writeData: method
+ * should only be called at most once before a didWriteData callback is issued, and
+ * receiveNextMessage: must be called each time before gRPC call can issue a didReceiveMessage
+ * callback.
+ *
+ * If writeData: method is called more than once before issuance of a didWriteData callback, gRPC
+ * will continue to queue the message and write them to gRPC core in order. However, the user
+ * assumes their own responsibility of flow control by keeping tracking of the pending writes in
+ * the call.
+ */
+@property(readwrite) BOOL flowControlEnabled;
+
 // OAuth2 parameters. Users of gRPC may specify one of the following two parameters.
 // OAuth2 parameters. Users of gRPC may specify one of the following two parameters.
 
 
 /**
 /**

+ 16 - 0
src/objective-c/GRPCClient/GRPCCallOptions.m

@@ -22,6 +22,7 @@
 // The default values for the call options.
 // The default values for the call options.
 static NSString *const kDefaultServerAuthority = nil;
 static NSString *const kDefaultServerAuthority = nil;
 static const NSTimeInterval kDefaultTimeout = 0;
 static const NSTimeInterval kDefaultTimeout = 0;
+static const BOOL kDefaultFlowControlEnabled = NO;
 static NSDictionary *const kDefaultInitialMetadata = nil;
 static NSDictionary *const kDefaultInitialMetadata = nil;
 static NSString *const kDefaultUserAgentPrefix = nil;
 static NSString *const kDefaultUserAgentPrefix = nil;
 static const NSUInteger kDefaultResponseSizeLimit = 0;
 static const NSUInteger kDefaultResponseSizeLimit = 0;
@@ -59,6 +60,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) {
  @protected
  @protected
   NSString *_serverAuthority;
   NSString *_serverAuthority;
   NSTimeInterval _timeout;
   NSTimeInterval _timeout;
+  BOOL _flowControlEnabled;
   NSString *_oauth2AccessToken;
   NSString *_oauth2AccessToken;
   id<GRPCAuthorizationProtocol> _authTokenProvider;
   id<GRPCAuthorizationProtocol> _authTokenProvider;
   NSDictionary *_initialMetadata;
   NSDictionary *_initialMetadata;
@@ -84,6 +86,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) {
 
 
 @synthesize serverAuthority = _serverAuthority;
 @synthesize serverAuthority = _serverAuthority;
 @synthesize timeout = _timeout;
 @synthesize timeout = _timeout;
+@synthesize flowControlEnabled = _flowControlEnabled;
 @synthesize oauth2AccessToken = _oauth2AccessToken;
 @synthesize oauth2AccessToken = _oauth2AccessToken;
 @synthesize authTokenProvider = _authTokenProvider;
 @synthesize authTokenProvider = _authTokenProvider;
 @synthesize initialMetadata = _initialMetadata;
 @synthesize initialMetadata = _initialMetadata;
@@ -109,6 +112,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) {
 - (instancetype)init {
 - (instancetype)init {
   return [self initWithServerAuthority:kDefaultServerAuthority
   return [self initWithServerAuthority:kDefaultServerAuthority
                                timeout:kDefaultTimeout
                                timeout:kDefaultTimeout
+                    flowControlEnabled:kDefaultFlowControlEnabled
                      oauth2AccessToken:kDefaultOauth2AccessToken
                      oauth2AccessToken:kDefaultOauth2AccessToken
                      authTokenProvider:kDefaultAuthTokenProvider
                      authTokenProvider:kDefaultAuthTokenProvider
                        initialMetadata:kDefaultInitialMetadata
                        initialMetadata:kDefaultInitialMetadata
@@ -134,6 +138,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) {
 
 
 - (instancetype)initWithServerAuthority:(NSString *)serverAuthority
 - (instancetype)initWithServerAuthority:(NSString *)serverAuthority
                                 timeout:(NSTimeInterval)timeout
                                 timeout:(NSTimeInterval)timeout
+                     flowControlEnabled:(BOOL)flowControlEnabled
                       oauth2AccessToken:(NSString *)oauth2AccessToken
                       oauth2AccessToken:(NSString *)oauth2AccessToken
                       authTokenProvider:(id<GRPCAuthorizationProtocol>)authTokenProvider
                       authTokenProvider:(id<GRPCAuthorizationProtocol>)authTokenProvider
                         initialMetadata:(NSDictionary *)initialMetadata
                         initialMetadata:(NSDictionary *)initialMetadata
@@ -158,6 +163,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) {
   if ((self = [super init])) {
   if ((self = [super init])) {
     _serverAuthority = [serverAuthority copy];
     _serverAuthority = [serverAuthority copy];
     _timeout = timeout < 0 ? 0 : timeout;
     _timeout = timeout < 0 ? 0 : timeout;
+    _flowControlEnabled = flowControlEnabled;
     _oauth2AccessToken = [oauth2AccessToken copy];
     _oauth2AccessToken = [oauth2AccessToken copy];
     _authTokenProvider = authTokenProvider;
     _authTokenProvider = authTokenProvider;
     _initialMetadata =
     _initialMetadata =
@@ -193,6 +199,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) {
   GRPCCallOptions *newOptions =
   GRPCCallOptions *newOptions =
       [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority
       [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority
                                                             timeout:_timeout
                                                             timeout:_timeout
+                                                 flowControlEnabled:_flowControlEnabled
                                                   oauth2AccessToken:_oauth2AccessToken
                                                   oauth2AccessToken:_oauth2AccessToken
                                                   authTokenProvider:_authTokenProvider
                                                   authTokenProvider:_authTokenProvider
                                                     initialMetadata:_initialMetadata
                                                     initialMetadata:_initialMetadata
@@ -221,6 +228,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) {
   GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone]
   GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone]
       initWithServerAuthority:[_serverAuthority copy]
       initWithServerAuthority:[_serverAuthority copy]
                       timeout:_timeout
                       timeout:_timeout
+           flowControlEnabled:_flowControlEnabled
             oauth2AccessToken:[_oauth2AccessToken copy]
             oauth2AccessToken:[_oauth2AccessToken copy]
             authTokenProvider:_authTokenProvider
             authTokenProvider:_authTokenProvider
               initialMetadata:[[NSDictionary alloc] initWithDictionary:_initialMetadata
               initialMetadata:[[NSDictionary alloc] initWithDictionary:_initialMetadata
@@ -301,6 +309,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) {
 
 
 @dynamic serverAuthority;
 @dynamic serverAuthority;
 @dynamic timeout;
 @dynamic timeout;
+@dynamic flowControlEnabled;
 @dynamic oauth2AccessToken;
 @dynamic oauth2AccessToken;
 @dynamic authTokenProvider;
 @dynamic authTokenProvider;
 @dynamic initialMetadata;
 @dynamic initialMetadata;
@@ -326,6 +335,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) {
 - (instancetype)init {
 - (instancetype)init {
   return [self initWithServerAuthority:kDefaultServerAuthority
   return [self initWithServerAuthority:kDefaultServerAuthority
                                timeout:kDefaultTimeout
                                timeout:kDefaultTimeout
+                    flowControlEnabled:kDefaultFlowControlEnabled
                      oauth2AccessToken:kDefaultOauth2AccessToken
                      oauth2AccessToken:kDefaultOauth2AccessToken
                      authTokenProvider:kDefaultAuthTokenProvider
                      authTokenProvider:kDefaultAuthTokenProvider
                        initialMetadata:kDefaultInitialMetadata
                        initialMetadata:kDefaultInitialMetadata
@@ -353,6 +363,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) {
   GRPCCallOptions *newOptions =
   GRPCCallOptions *newOptions =
       [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority
       [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority
                                                             timeout:_timeout
                                                             timeout:_timeout
+                                                 flowControlEnabled:_flowControlEnabled
                                                   oauth2AccessToken:_oauth2AccessToken
                                                   oauth2AccessToken:_oauth2AccessToken
                                                   authTokenProvider:_authTokenProvider
                                                   authTokenProvider:_authTokenProvider
                                                     initialMetadata:_initialMetadata
                                                     initialMetadata:_initialMetadata
@@ -381,6 +392,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) {
   GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone]
   GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone]
       initWithServerAuthority:_serverAuthority
       initWithServerAuthority:_serverAuthority
                       timeout:_timeout
                       timeout:_timeout
+           flowControlEnabled:_flowControlEnabled
             oauth2AccessToken:_oauth2AccessToken
             oauth2AccessToken:_oauth2AccessToken
             authTokenProvider:_authTokenProvider
             authTokenProvider:_authTokenProvider
               initialMetadata:_initialMetadata
               initialMetadata:_initialMetadata
@@ -417,6 +429,10 @@ static BOOL areObjectsEqual(id obj1, id obj2) {
   }
   }
 }
 }
 
 
+- (void)setFlowControlEnabled:(BOOL)flowControlEnabled {
+  _flowControlEnabled = flowControlEnabled;
+}
+
 - (void)setOauth2AccessToken:(NSString *)oauth2AccessToken {
 - (void)setOauth2AccessToken:(NSString *)oauth2AccessToken {
   _oauth2AccessToken = [oauth2AccessToken copy];
   _oauth2AccessToken = [oauth2AccessToken copy];
 }
 }

+ 27 - 0
src/objective-c/ProtoRPC/ProtoRPC.h

@@ -57,6 +57,13 @@ NS_ASSUME_NONNULL_BEGIN
 - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata
 - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata
                                error:(nullable NSError *)error;
                                error:(nullable NSError *)error;
 
 
+/**
+ * Issued when flow control is enabled for the call and a message (written with writeMessage: method
+ * of GRPCStreamingProtoCall or the initializer of GRPCUnaryProtoCall) is passed to gRPC core with
+ * SEND_MESSAGE operation.
+ */
+- (void)didWriteMessage;
+
 @end
 @end
 
 
 /** A unary-request RPC call with Protobuf. */
 /** A unary-request RPC call with Protobuf. */
@@ -130,6 +137,26 @@ NS_ASSUME_NONNULL_BEGIN
  */
  */
 - (void)finish;
 - (void)finish;
 
 
+/**
+ * Tell gRPC to receive another message.
+ *
+ * This method should only be used when flow control is enabled. If flow control is enabled, gRPC
+ * will only receive additional messages after the user indicates so by using either
+ * receiveNextMessage: or receiveNextMessages: methods. If flow control is not enabled, messages
+ * will be automatically received after the previous one is delivered.
+ */
+- (void)receiveNextMessage;
+
+/**
+ * Tell gRPC to receive another N message.
+ *
+ * This method should only be used when flow control is enabled. If flow control is enabled, the
+ * messages received from the server are buffered in gRPC until the user want to receive the next
+ * message. If flow control is not enabled, messages will be automatically received after the
+ * previous one is delivered.
+ */
+- (void)receiveNextMessages:(NSUInteger)numberOfMessages;
+
 @end
 @end
 
 
 NS_ASSUME_NONNULL_END
 NS_ASSUME_NONNULL_END

+ 27 - 2
src/objective-c/ProtoRPC/ProtoRPC.m

@@ -41,8 +41,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing
     @"Expected class" : expectedClass,
     @"Expected class" : expectedClass,
     @"Received value" : proto,
     @"Received value" : proto,
   };
   };
-  // TODO(jcanizales): Use kGRPCErrorDomain and GRPCErrorCodeInternal when they're public.
-  return [NSError errorWithDomain:@"io.grpc" code:13 userInfo:info];
+  return [NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeInternal userInfo:info];
 }
 }
 
 
 @implementation GRPCUnaryProtoCall {
 @implementation GRPCUnaryProtoCall {
@@ -72,6 +71,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing
 
 
 - (void)start {
 - (void)start {
   [_call start];
   [_call start];
+  [_call receiveNextMessage];
   [_call writeMessage:_message];
   [_call writeMessage:_message];
   [_call finish];
   [_call finish];
 }
 }
@@ -197,6 +197,17 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing
   [copiedCall finish];
   [copiedCall finish];
 }
 }
 
 
+- (void)receiveNextMessage {
+  [self receiveNextMessages:1];
+}
+- (void)receiveNextMessages:(NSUInteger)numberOfMessages {
+  GRPCCall2 *copiedCall;
+  @synchronized(self) {
+    copiedCall = _call;
+  }
+  [copiedCall receiveNextMessages:numberOfMessages];
+}
+
 - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata {
 - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata {
   @synchronized(self) {
   @synchronized(self) {
     if (initialMetadata != nil &&
     if (initialMetadata != nil &&
@@ -260,6 +271,20 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing
   }
   }
 }
 }
 
 
+- (void)didWriteData {
+  @synchronized(self) {
+    if ([_handler respondsToSelector:@selector(didWriteMessage)]) {
+      dispatch_async(_dispatchQueue, ^{
+        id<GRPCProtoResponseHandler> copiedHandler = nil;
+        @synchronized(self) {
+          copiedHandler = self->_handler;
+        }
+        [copiedHandler didWriteMessage];
+      });
+    }
+  }
+}
+
 - (dispatch_queue_t)dispatchQueue {
 - (dispatch_queue_t)dispatchQueue {
   return _dispatchQueue;
   return _dispatchQueue;
 }
 }

+ 295 - 3
src/objective-c/tests/APIv2Tests/APIv2Tests.m

@@ -40,11 +40,13 @@ static NSString *const kService = @"TestService";
 static GRPCProtoMethod *kInexistentMethod;
 static GRPCProtoMethod *kInexistentMethod;
 static GRPCProtoMethod *kEmptyCallMethod;
 static GRPCProtoMethod *kEmptyCallMethod;
 static GRPCProtoMethod *kUnaryCallMethod;
 static GRPCProtoMethod *kUnaryCallMethod;
+static GRPCProtoMethod *kOutputStreamingCallMethod;
 static GRPCProtoMethod *kFullDuplexCallMethod;
 static GRPCProtoMethod *kFullDuplexCallMethod;
 
 
 static const int kSimpleDataLength = 100;
 static const int kSimpleDataLength = 100;
 
 
-static const NSTimeInterval kTestTimeout = 16;
+static const NSTimeInterval kTestTimeout = 8;
+static const NSTimeInterval kInvertedTimeout = 2;
 
 
 // Reveal the _class ivar for testing access
 // Reveal the _class ivar for testing access
 @interface GRPCCall2 () {
 @interface GRPCCall2 () {
@@ -57,6 +59,11 @@ static const NSTimeInterval kTestTimeout = 16;
 // Convenience class to use blocks as callbacks
 // Convenience class to use blocks as callbacks
 @interface ClientTestsBlockCallbacks : NSObject<GRPCResponseHandler>
 @interface ClientTestsBlockCallbacks : NSObject<GRPCResponseHandler>
 
 
+- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
+                                messageCallback:(void (^)(id))messageCallback
+                                  closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback
+                              writeDataCallback:(void (^)(void))writeDataCallback;
+
 - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
 - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
                                 messageCallback:(void (^)(id))messageCallback
                                 messageCallback:(void (^)(id))messageCallback
                                   closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback;
                                   closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback;
@@ -67,21 +74,33 @@ static const NSTimeInterval kTestTimeout = 16;
   void (^_initialMetadataCallback)(NSDictionary *);
   void (^_initialMetadataCallback)(NSDictionary *);
   void (^_messageCallback)(id);
   void (^_messageCallback)(id);
   void (^_closeCallback)(NSDictionary *, NSError *);
   void (^_closeCallback)(NSDictionary *, NSError *);
+  void (^_writeDataCallback)(void);
   dispatch_queue_t _dispatchQueue;
   dispatch_queue_t _dispatchQueue;
 }
 }
 
 
 - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
 - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
                                 messageCallback:(void (^)(id))messageCallback
                                 messageCallback:(void (^)(id))messageCallback
-                                  closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback {
+                                  closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback
+                              writeDataCallback:(void (^)(void))writeDataCallback {
   if ((self = [super init])) {
   if ((self = [super init])) {
     _initialMetadataCallback = initialMetadataCallback;
     _initialMetadataCallback = initialMetadataCallback;
     _messageCallback = messageCallback;
     _messageCallback = messageCallback;
     _closeCallback = closeCallback;
     _closeCallback = closeCallback;
+    _writeDataCallback = writeDataCallback;
     _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
     _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
   }
   }
   return self;
   return self;
 }
 }
 
 
+- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
+                                messageCallback:(void (^)(id))messageCallback
+                                  closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback {
+  return [self initWithInitialMetadataCallback:initialMetadataCallback
+                               messageCallback:messageCallback
+                                 closeCallback:closeCallback
+                             writeDataCallback:nil];
+}
+
 - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata {
 - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata {
   if (self->_initialMetadataCallback) {
   if (self->_initialMetadataCallback) {
     self->_initialMetadataCallback(initialMetadata);
     self->_initialMetadataCallback(initialMetadata);
@@ -100,6 +119,12 @@ static const NSTimeInterval kTestTimeout = 16;
   }
   }
 }
 }
 
 
+- (void)didWriteData {
+  if (self->_writeDataCallback) {
+    self->_writeDataCallback();
+  }
+}
+
 - (dispatch_queue_t)dispatchQueue {
 - (dispatch_queue_t)dispatchQueue {
   return _dispatchQueue;
   return _dispatchQueue;
 }
 }
@@ -120,6 +145,9 @@ static const NSTimeInterval kTestTimeout = 16;
       [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"EmptyCall"];
       [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"EmptyCall"];
   kUnaryCallMethod =
   kUnaryCallMethod =
       [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"UnaryCall"];
       [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"UnaryCall"];
+  kOutputStreamingCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage
+                                                                service:kService
+                                                                 method:@"StreamingOutputCall"];
   kFullDuplexCallMethod =
   kFullDuplexCallMethod =
       [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"FullDuplexCall"];
       [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"FullDuplexCall"];
 }
 }
@@ -151,7 +179,7 @@ static const NSTimeInterval kTestTimeout = 16;
                                  closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
                                  closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
                                    trailing_md = trailingMetadata;
                                    trailing_md = trailingMetadata;
                                    if (error) {
                                    if (error) {
-                                     XCTAssertEqual(error.code, 16,
+                                     XCTAssertEqual(error.code, GRPCErrorCodeUnauthenticated,
                                                     @"Finished with unexpected error: %@", error);
                                                     @"Finished with unexpected error: %@", error);
                                      XCTAssertEqualObjects(init_md,
                                      XCTAssertEqualObjects(init_md,
                                                            error.userInfo[kGRPCHeadersKey]);
                                                            error.userInfo[kGRPCHeadersKey]);
@@ -478,4 +506,268 @@ static const NSTimeInterval kTestTimeout = 16;
   [self waitForExpectationsWithTimeout:kTestTimeout handler:nil];
   [self waitForExpectationsWithTimeout:kTestTimeout handler:nil];
 }
 }
 
 
+- (void)testFlowControlWrite {
+  __weak XCTestExpectation *expectWriteData =
+      [self expectationWithDescription:@"Reported write data"];
+
+  RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
+  RMTResponseParameters *parameters = [RMTResponseParameters message];
+  parameters.size = kSimpleDataLength;
+  [request.responseParametersArray addObject:parameters];
+  request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength];
+
+  GRPCRequestOptions *callRequest =
+      [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress
+                                          path:kUnaryCallMethod.HTTPPath
+                                        safety:GRPCCallSafetyDefault];
+  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
+  options.transportType = GRPCTransportTypeInsecure;
+  options.flowControlEnabled = YES;
+  GRPCCall2 *call =
+      [[GRPCCall2 alloc] initWithRequestOptions:callRequest
+                                responseHandler:[[ClientTestsBlockCallbacks alloc]
+                                                    initWithInitialMetadataCallback:nil
+                                                                    messageCallback:nil
+                                                                      closeCallback:nil
+                                                                  writeDataCallback:^{
+                                                                    [expectWriteData fulfill];
+                                                                  }]
+                                    callOptions:options];
+
+  [call start];
+  [call receiveNextMessages:1];
+  [call writeData:[request data]];
+
+  // Wait for 3 seconds and make sure we do not receive the response
+  [self waitForExpectationsWithTimeout:kTestTimeout handler:nil];
+
+  [call finish];
+}
+
+- (void)testFlowControlRead {
+  __weak __block XCTestExpectation *expectBlockedMessage =
+      [self expectationWithDescription:@"Message not delivered without recvNextMessage"];
+  __weak __block XCTestExpectation *expectPassedMessage = nil;
+  __weak __block XCTestExpectation *expectBlockedClose =
+      [self expectationWithDescription:@"Call not closed with pending message"];
+  __weak __block XCTestExpectation *expectPassedClose = nil;
+  expectBlockedMessage.inverted = YES;
+  expectBlockedClose.inverted = YES;
+
+  RMTSimpleRequest *request = [RMTSimpleRequest message];
+  request.responseSize = kSimpleDataLength;
+  request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength];
+
+  GRPCRequestOptions *callRequest =
+      [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress
+                                          path:kUnaryCallMethod.HTTPPath
+                                        safety:GRPCCallSafetyDefault];
+  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
+  options.transportType = GRPCTransportTypeInsecure;
+  options.flowControlEnabled = YES;
+  __block int unblocked = NO;
+  GRPCCall2 *call = [[GRPCCall2 alloc]
+      initWithRequestOptions:callRequest
+             responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil
+                                 messageCallback:^(NSData *message) {
+                                   if (!unblocked) {
+                                     [expectBlockedMessage fulfill];
+                                   } else {
+                                     [expectPassedMessage fulfill];
+                                   }
+                                 }
+                                 closeCallback:^(NSDictionary *trailers, NSError *error) {
+                                   if (!unblocked) {
+                                     [expectBlockedClose fulfill];
+                                   } else {
+                                     [expectPassedClose fulfill];
+                                   }
+                                 }]
+                 callOptions:options];
+
+  [call start];
+  [call writeData:[request data]];
+  [call finish];
+
+  // Wait to make sure we do not receive the response
+  [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil];
+
+  expectPassedMessage =
+      [self expectationWithDescription:@"Message delivered with receiveNextMessage"];
+  expectPassedClose = [self expectationWithDescription:@"Close delivered after receiveNextMessage"];
+
+  unblocked = YES;
+  [call receiveNextMessages:1];
+
+  [self waitForExpectationsWithTimeout:kTestTimeout handler:nil];
+}
+
+- (void)testFlowControlMultipleMessages {
+  __weak XCTestExpectation *expectPassedMessage =
+      [self expectationWithDescription:@"two messages delivered with receiveNextMessage"];
+  expectPassedMessage.expectedFulfillmentCount = 2;
+  __weak XCTestExpectation *expectBlockedMessage =
+      [self expectationWithDescription:@"Message 3 not delivered"];
+  expectBlockedMessage.inverted = YES;
+  __weak XCTestExpectation *expectWriteTwice =
+      [self expectationWithDescription:@"Write 2 messages done"];
+  expectWriteTwice.expectedFulfillmentCount = 2;
+
+  RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
+  RMTResponseParameters *parameters = [RMTResponseParameters message];
+  parameters.size = kSimpleDataLength;
+  [request.responseParametersArray addObject:parameters];
+  request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength];
+
+  GRPCRequestOptions *callRequest =
+      [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress
+                                          path:kFullDuplexCallMethod.HTTPPath
+                                        safety:GRPCCallSafetyDefault];
+  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
+  options.transportType = GRPCTransportTypeInsecure;
+  options.flowControlEnabled = YES;
+  __block NSUInteger messageId = 0;
+  __block GRPCCall2 *call = [[GRPCCall2 alloc]
+      initWithRequestOptions:callRequest
+             responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil
+                                 messageCallback:^(NSData *message) {
+                                   if (messageId <= 1) {
+                                     [expectPassedMessage fulfill];
+                                   } else {
+                                     [expectBlockedMessage fulfill];
+                                   }
+                                   messageId++;
+                                 }
+                                 closeCallback:nil
+                                 writeDataCallback:^{
+                                   [expectWriteTwice fulfill];
+                                 }]
+                 callOptions:options];
+
+  [call receiveNextMessages:2];
+  [call start];
+  [call writeData:[request data]];
+  [call writeData:[request data]];
+
+  [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil];
+}
+
+- (void)testFlowControlReadReadyBeforeStart {
+  __weak XCTestExpectation *expectPassedMessage =
+      [self expectationWithDescription:@"Message delivered with receiveNextMessage"];
+  __weak XCTestExpectation *expectPassedClose =
+      [self expectationWithDescription:@"Close delivered with receiveNextMessage"];
+
+  RMTSimpleRequest *request = [RMTSimpleRequest message];
+  request.responseSize = kSimpleDataLength;
+  request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength];
+
+  GRPCRequestOptions *callRequest =
+      [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress
+                                          path:kUnaryCallMethod.HTTPPath
+                                        safety:GRPCCallSafetyDefault];
+  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
+  options.transportType = GRPCTransportTypeInsecure;
+  options.flowControlEnabled = YES;
+  __block BOOL closed = NO;
+  GRPCCall2 *call = [[GRPCCall2 alloc]
+      initWithRequestOptions:callRequest
+             responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil
+                                 messageCallback:^(NSData *message) {
+                                   [expectPassedMessage fulfill];
+                                   XCTAssertFalse(closed);
+                                 }
+                                 closeCallback:^(NSDictionary *ttrailers, NSError *error) {
+                                   closed = YES;
+                                   [expectPassedClose fulfill];
+                                 }]
+                 callOptions:options];
+
+  [call receiveNextMessages:1];
+  [call start];
+  [call writeData:[request data]];
+  [call finish];
+
+  [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil];
+}
+
+- (void)testFlowControlReadReadyAfterStart {
+  __weak XCTestExpectation *expectPassedMessage =
+      [self expectationWithDescription:@"Message delivered with receiveNextMessage"];
+  __weak XCTestExpectation *expectPassedClose =
+      [self expectationWithDescription:@"Close delivered with receiveNextMessage"];
+
+  RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
+  RMTResponseParameters *parameters = [RMTResponseParameters message];
+  parameters.size = kSimpleDataLength;
+  [request.responseParametersArray addObject:parameters];
+  request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength];
+
+  GRPCRequestOptions *callRequest =
+      [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress
+                                          path:kUnaryCallMethod.HTTPPath
+                                        safety:GRPCCallSafetyDefault];
+  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
+  options.transportType = GRPCTransportTypeInsecure;
+  options.flowControlEnabled = YES;
+  __block BOOL closed = NO;
+  GRPCCall2 *call = [[GRPCCall2 alloc]
+      initWithRequestOptions:callRequest
+             responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil
+                                 messageCallback:^(NSData *message) {
+                                   [expectPassedMessage fulfill];
+                                   XCTAssertFalse(closed);
+                                 }
+                                 closeCallback:^(NSDictionary *trailers, NSError *error) {
+                                   closed = YES;
+                                   [expectPassedClose fulfill];
+                                 }]
+                 callOptions:options];
+
+  [call start];
+  [call receiveNextMessages:1];
+  [call writeData:[request data]];
+  [call finish];
+
+  [self waitForExpectationsWithTimeout:kTestTimeout handler:nil];
+}
+
+- (void)testFlowControlReadNonBlockingFailure {
+  __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."];
+
+  GRPCRequestOptions *requestOptions =
+      [[GRPCRequestOptions alloc] initWithHost:kHostAddress
+                                          path:kUnaryCallMethod.HTTPPath
+                                        safety:GRPCCallSafetyDefault];
+  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
+  options.flowControlEnabled = YES;
+  options.transportType = GRPCTransportTypeInsecure;
+
+  RMTSimpleRequest *request = [RMTSimpleRequest message];
+  request.payload.body = [NSMutableData dataWithLength:options.responseSizeLimit];
+
+  RMTEchoStatus *status = [RMTEchoStatus message];
+  status.code = 2;
+  status.message = @"test";
+  request.responseStatus = status;
+
+  GRPCCall2 *call = [[GRPCCall2 alloc]
+      initWithRequestOptions:requestOptions
+             responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil
+                                 messageCallback:^(NSData *data) {
+                                   XCTFail(@"Received unexpected message");
+                                 }
+                                 closeCallback:^(NSDictionary *trailingMetadata, NSError *error) {
+                                   XCTAssertNotNil(error, @"Expecting non-nil error");
+                                   XCTAssertEqual(error.code, 2);
+                                   [completion fulfill];
+                                 }]
+                 callOptions:options];
+  [call writeData:[request data]];
+  [call start];
+  [call finish];
+
+  [self waitForExpectationsWithTimeout:kTestTimeout handler:nil];
+}
+
 @end
 @end

+ 96 - 11
src/objective-c/tests/InteropTests.m

@@ -79,6 +79,11 @@ BOOL isRemoteInteropTest(NSString *host) {
 // Convenience class to use blocks as callbacks
 // Convenience class to use blocks as callbacks
 @interface InteropTestsBlockCallbacks : NSObject<GRPCProtoResponseHandler>
 @interface InteropTestsBlockCallbacks : NSObject<GRPCProtoResponseHandler>
 
 
+- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
+                                messageCallback:(void (^)(id))messageCallback
+                                  closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback
+                           writeMessageCallback:(void (^)(void))writeMessageCallback;
+
 - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
 - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
                                 messageCallback:(void (^)(id))messageCallback
                                 messageCallback:(void (^)(id))messageCallback
                                   closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback;
                                   closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback;
@@ -89,21 +94,33 @@ BOOL isRemoteInteropTest(NSString *host) {
   void (^_initialMetadataCallback)(NSDictionary *);
   void (^_initialMetadataCallback)(NSDictionary *);
   void (^_messageCallback)(id);
   void (^_messageCallback)(id);
   void (^_closeCallback)(NSDictionary *, NSError *);
   void (^_closeCallback)(NSDictionary *, NSError *);
+  void (^_writeMessageCallback)(void);
   dispatch_queue_t _dispatchQueue;
   dispatch_queue_t _dispatchQueue;
 }
 }
 
 
 - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
 - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
                                 messageCallback:(void (^)(id))messageCallback
                                 messageCallback:(void (^)(id))messageCallback
-                                  closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback {
+                                  closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback
+                           writeMessageCallback:(void (^)(void))writeMessageCallback {
   if ((self = [super init])) {
   if ((self = [super init])) {
     _initialMetadataCallback = initialMetadataCallback;
     _initialMetadataCallback = initialMetadataCallback;
     _messageCallback = messageCallback;
     _messageCallback = messageCallback;
     _closeCallback = closeCallback;
     _closeCallback = closeCallback;
+    _writeMessageCallback = writeMessageCallback;
     _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
     _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
   }
   }
   return self;
   return self;
 }
 }
 
 
+- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback
+                                messageCallback:(void (^)(id))messageCallback
+                                  closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback {
+  return [self initWithInitialMetadataCallback:initialMetadataCallback
+                               messageCallback:messageCallback
+                                 closeCallback:closeCallback
+                          writeMessageCallback:nil];
+}
+
 - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata {
 - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata {
   if (_initialMetadataCallback) {
   if (_initialMetadataCallback) {
     _initialMetadataCallback(initialMetadata);
     _initialMetadataCallback(initialMetadata);
@@ -122,6 +139,12 @@ BOOL isRemoteInteropTest(NSString *host) {
   }
   }
 }
 }
 
 
+- (void)didWriteMessage {
+  if (_writeMessageCallback) {
+    _writeMessageCallback();
+  }
+}
+
 - (dispatch_queue_t)dispatchQueue {
 - (dispatch_queue_t)dispatchQueue {
   return _dispatchQueue;
   return _dispatchQueue;
 }
 }
@@ -355,9 +378,9 @@ BOOL isRemoteInteropTest(NSString *host) {
     request.responseSize = 314159;
     request.responseSize = 314159;
     request.payload.body = [NSMutableData dataWithLength:271828];
     request.payload.body = [NSMutableData dataWithLength:271828];
     if (i % 3 == 0) {
     if (i % 3 == 0) {
-      request.responseStatus.code = GRPC_STATUS_UNAVAILABLE;
+      request.responseStatus.code = GRPCErrorCodeUnavailable;
     } else if (i % 7 == 0) {
     } else if (i % 7 == 0) {
-      request.responseStatus.code = GRPC_STATUS_CANCELLED;
+      request.responseStatus.code = GRPCErrorCodeCancelled;
     }
     }
     GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
     GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
     options.transportType = [[self class] transportType];
     options.transportType = [[self class] transportType];
@@ -404,9 +427,9 @@ BOOL isRemoteInteropTest(NSString *host) {
     request.responseSize = 314159;
     request.responseSize = 314159;
     request.payload.body = [NSMutableData dataWithLength:271828];
     request.payload.body = [NSMutableData dataWithLength:271828];
     if (i % 3 == 0) {
     if (i % 3 == 0) {
-      request.responseStatus.code = GRPC_STATUS_UNAVAILABLE;
+      request.responseStatus.code = GRPCErrorCodeUnavailable;
     } else if (i % 7 == 0) {
     } else if (i % 7 == 0) {
-      request.responseStatus.code = GRPC_STATUS_CANCELLED;
+      request.responseStatus.code = GRPCErrorCodeCancelled;
     }
     }
 
 
     [_service unaryCallWithRequest:request
     [_service unaryCallWithRequest:request
@@ -702,6 +725,67 @@ BOOL isRemoteInteropTest(NSString *host) {
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
 }
 }
 
 
+- (void)testPingPongRPCWithFlowControl {
+  XCTAssertNotNil([[self class] host]);
+  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPongWithV2API"];
+
+  NSArray *requests = @[ @27182, @8, @1828, @45904 ];
+  NSArray *responses = @[ @31415, @9, @2653, @58979 ];
+
+  __block int index = 0;
+
+  id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index]
+                                               requestedResponseSize:responses[index]];
+  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
+  options.transportType = [[self class] transportType];
+  options.PEMRootCertificates = [[self class] PEMRootCertificates];
+  options.hostNameOverride = [[self class] hostNameOverride];
+  options.flowControlEnabled = YES;
+  __block BOOL canWriteData = NO;
+
+  __block GRPCStreamingProtoCall *call = [_service
+      fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc]
+                                            initWithInitialMetadataCallback:nil
+                                            messageCallback:^(id message) {
+                                              XCTAssertLessThan(index, 4,
+                                                                @"More than 4 responses received.");
+                                              id expected = [RMTStreamingOutputCallResponse
+                                                  messageWithPayloadSize:responses[index]];
+                                              XCTAssertEqualObjects(message, expected);
+                                              index += 1;
+                                              if (index < 4) {
+                                                id request = [RMTStreamingOutputCallRequest
+                                                    messageWithPayloadSize:requests[index]
+                                                     requestedResponseSize:responses[index]];
+                                                XCTAssertTrue(canWriteData);
+                                                canWriteData = NO;
+                                                [call writeMessage:request];
+                                                [call receiveNextMessage];
+                                              } else {
+                                                [call finish];
+                                              }
+                                            }
+                                            closeCallback:^(NSDictionary *trailingMetadata,
+                                                            NSError *error) {
+                                              XCTAssertNil(error,
+                                                           @"Finished with unexpected error: %@",
+                                                           error);
+                                              XCTAssertEqual(index, 4,
+                                                             @"Received %i responses instead of 4.",
+                                                             index);
+                                              [expectation fulfill];
+                                            }
+                                            writeMessageCallback:^{
+                                              canWriteData = YES;
+                                            }]
+                            callOptions:options];
+  [call start];
+  [call receiveNextMessage];
+  [call writeMessage:request];
+
+  [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
+}
+
 - (void)testEmptyStreamRPC {
 - (void)testEmptyStreamRPC {
   XCTAssertNotNil([[self class] host]);
   XCTAssertNotNil([[self class] host]);
   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"];
   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"];
@@ -726,7 +810,7 @@ BOOL isRemoteInteropTest(NSString *host) {
       RPCToStreamingInputCallWithRequestsWriter:requestsBuffer
       RPCToStreamingInputCallWithRequestsWriter:requestsBuffer
                                         handler:^(RMTStreamingInputCallResponse *response,
                                         handler:^(RMTStreamingInputCallResponse *response,
                                                   NSError *error) {
                                                   NSError *error) {
-                                          XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
+                                          XCTAssertEqual(error.code, GRPCErrorCodeCancelled);
                                           [expectation fulfill];
                                           [expectation fulfill];
                                         }];
                                         }];
   XCTAssertEqual(call.state, GRXWriterStateNotStarted);
   XCTAssertEqual(call.state, GRXWriterStateNotStarted);
@@ -754,7 +838,8 @@ BOOL isRemoteInteropTest(NSString *host) {
                                                 }
                                                 }
                                                 closeCallback:^(NSDictionary *trailingMetadata,
                                                 closeCallback:^(NSDictionary *trailingMetadata,
                                                                 NSError *error) {
                                                                 NSError *error) {
-                                                  XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
+                                                  XCTAssertEqual(error.code,
+                                                                 GRPCErrorCodeCancelled);
                                                   [expectation fulfill];
                                                   [expectation fulfill];
                                                 }]
                                                 }]
                                 callOptions:nil];
                                 callOptions:nil];
@@ -785,7 +870,7 @@ BOOL isRemoteInteropTest(NSString *host) {
                                               NSError *error) {
                                               NSError *error) {
                                  if (receivedResponse) {
                                  if (receivedResponse) {
                                    XCTAssert(done, @"Unexpected extra response %@", response);
                                    XCTAssert(done, @"Unexpected extra response %@", response);
-                                   XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
+                                   XCTAssertEqual(error.code, GRPCErrorCodeCancelled);
                                    [expectation fulfill];
                                    [expectation fulfill];
                                  } else {
                                  } else {
                                    XCTAssertNil(error, @"Finished with unexpected error: %@",
                                    XCTAssertNil(error, @"Finished with unexpected error: %@",
@@ -828,7 +913,7 @@ BOOL isRemoteInteropTest(NSString *host) {
                                             }
                                             }
                                             closeCallback:^(NSDictionary *trailingMetadata,
                                             closeCallback:^(NSDictionary *trailingMetadata,
                                                             NSError *error) {
                                                             NSError *error) {
-                                              XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
+                                              XCTAssertEqual(error.code, GRPCErrorCodeCancelled);
                                               [completionExpectation fulfill];
                                               [completionExpectation fulfill];
                                             }]
                                             }]
                             callOptions:options];
                             callOptions:options];
@@ -858,7 +943,7 @@ BOOL isRemoteInteropTest(NSString *host) {
                                             }
                                             }
                                             closeCallback:^(NSDictionary *trailingMetadata,
                                             closeCallback:^(NSDictionary *trailingMetadata,
                                                             NSError *error) {
                                                             NSError *error) {
-                                              XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
+                                              XCTAssertEqual(error.code, GRPCErrorCodeCancelled);
                                               [completionExpectation fulfill];
                                               [completionExpectation fulfill];
                                             }]
                                             }]
                             callOptions:options];
                             callOptions:options];
@@ -959,7 +1044,7 @@ BOOL isRemoteInteropTest(NSString *host) {
                             } else {
                             } else {
                               // Keepalive should kick after 1s elapsed and fails the call.
                               // Keepalive should kick after 1s elapsed and fails the call.
                               XCTAssertNotNil(error);
                               XCTAssertNotNil(error);
-                              XCTAssertEqual(error.code, GRPC_STATUS_UNAVAILABLE);
+                              XCTAssertEqual(error.code, GRPCErrorCodeUnavailable);
                               XCTAssertEqualObjects(
                               XCTAssertEqualObjects(
                                   error.localizedDescription, @"keepalive watchdog timeout",
                                   error.localizedDescription, @"keepalive watchdog timeout",
                                   @"Unexpected failure that is not keepalive watchdog timeout.");
                                   @"Unexpected failure that is not keepalive watchdog timeout.");

+ 3 - 3
src/objective-c/tests/UnitTests/UnitTests.m

@@ -42,18 +42,18 @@
       [NSError grpc_errorFromStatusCode:GRPC_STATUS_UNAVAILABLE details:nil errorString:nil];
       [NSError grpc_errorFromStatusCode:GRPC_STATUS_UNAVAILABLE details:nil errorString:nil];
 
 
   XCTAssertNil(error1);
   XCTAssertNil(error1);
-  XCTAssertEqual(error2.code, 1);
+  XCTAssertEqual(error2.code, GRPCErrorCodeCancelled);
   XCTAssertEqualObjects(error2.domain, @"io.grpc");
   XCTAssertEqualObjects(error2.domain, @"io.grpc");
   XCTAssertEqualObjects(error2.userInfo[NSLocalizedDescriptionKey],
   XCTAssertEqualObjects(error2.userInfo[NSLocalizedDescriptionKey],
                         [NSString stringWithUTF8String:kDetails]);
                         [NSString stringWithUTF8String:kDetails]);
   XCTAssertEqualObjects(error2.userInfo[NSDebugDescriptionErrorKey],
   XCTAssertEqualObjects(error2.userInfo[NSDebugDescriptionErrorKey],
                         [NSString stringWithUTF8String:kErrorString]);
                         [NSString stringWithUTF8String:kErrorString]);
-  XCTAssertEqual(error3.code, 16);
+  XCTAssertEqual(error3.code, GRPCErrorCodeUnauthenticated);
   XCTAssertEqualObjects(error3.domain, @"io.grpc");
   XCTAssertEqualObjects(error3.domain, @"io.grpc");
   XCTAssertEqualObjects(error3.userInfo[NSLocalizedDescriptionKey],
   XCTAssertEqualObjects(error3.userInfo[NSLocalizedDescriptionKey],
                         [NSString stringWithUTF8String:kDetails]);
                         [NSString stringWithUTF8String:kDetails]);
   XCTAssertNil(error3.userInfo[NSDebugDescriptionErrorKey]);
   XCTAssertNil(error3.userInfo[NSDebugDescriptionErrorKey]);
-  XCTAssertEqual(error4.code, 14);
+  XCTAssertEqual(error4.code, GRPCErrorCodeUnavailable);
   XCTAssertEqualObjects(error4.domain, @"io.grpc");
   XCTAssertEqualObjects(error4.domain, @"io.grpc");
   XCTAssertNil(error4.userInfo[NSLocalizedDescriptionKey]);
   XCTAssertNil(error4.userInfo[NSLocalizedDescriptionKey]);
   XCTAssertNil(error4.userInfo[NSDebugDescriptionErrorKey]);
   XCTAssertNil(error4.userInfo[NSDebugDescriptionErrorKey]);

+ 6 - 1
src/python/grpcio/grpc_core_dependencies.py

@@ -19,7 +19,6 @@ CORE_SOURCE_FILES = [
     'third_party/address_sorting/address_sorting_posix.c',
     'third_party/address_sorting/address_sorting_posix.c',
     'third_party/address_sorting/address_sorting_windows.c',
     'third_party/address_sorting/address_sorting_windows.c',
     'src/core/lib/gpr/alloc.cc',
     'src/core/lib/gpr/alloc.cc',
-    'src/core/lib/gpr/arena.cc',
     'src/core/lib/gpr/atm.cc',
     'src/core/lib/gpr/atm.cc',
     'src/core/lib/gpr/cpu_iphone.cc',
     'src/core/lib/gpr/cpu_iphone.cc',
     'src/core/lib/gpr/cpu_linux.cc',
     'src/core/lib/gpr/cpu_linux.cc',
@@ -52,6 +51,7 @@ CORE_SOURCE_FILES = [
     'src/core/lib/gpr/tmpfile_posix.cc',
     'src/core/lib/gpr/tmpfile_posix.cc',
     'src/core/lib/gpr/tmpfile_windows.cc',
     'src/core/lib/gpr/tmpfile_windows.cc',
     'src/core/lib/gpr/wrap_memcpy.cc',
     'src/core/lib/gpr/wrap_memcpy.cc',
+    'src/core/lib/gprpp/arena.cc',
     'src/core/lib/gprpp/fork.cc',
     'src/core/lib/gprpp/fork.cc',
     'src/core/lib/gprpp/thd_posix.cc',
     'src/core/lib/gprpp/thd_posix.cc',
     'src/core/lib/gprpp/thd_windows.cc',
     'src/core/lib/gprpp/thd_windows.cc',
@@ -84,12 +84,15 @@ CORE_SOURCE_FILES = [
     'src/core/lib/http/parser.cc',
     'src/core/lib/http/parser.cc',
     'src/core/lib/iomgr/buffer_list.cc',
     'src/core/lib/iomgr/buffer_list.cc',
     'src/core/lib/iomgr/call_combiner.cc',
     'src/core/lib/iomgr/call_combiner.cc',
+    'src/core/lib/iomgr/cfstream_handle.cc',
     'src/core/lib/iomgr/combiner.cc',
     'src/core/lib/iomgr/combiner.cc',
     'src/core/lib/iomgr/endpoint.cc',
     'src/core/lib/iomgr/endpoint.cc',
+    'src/core/lib/iomgr/endpoint_cfstream.cc',
     'src/core/lib/iomgr/endpoint_pair_posix.cc',
     'src/core/lib/iomgr/endpoint_pair_posix.cc',
     'src/core/lib/iomgr/endpoint_pair_uv.cc',
     'src/core/lib/iomgr/endpoint_pair_uv.cc',
     'src/core/lib/iomgr/endpoint_pair_windows.cc',
     'src/core/lib/iomgr/endpoint_pair_windows.cc',
     'src/core/lib/iomgr/error.cc',
     'src/core/lib/iomgr/error.cc',
+    'src/core/lib/iomgr/error_cfstream.cc',
     'src/core/lib/iomgr/ev_epoll1_linux.cc',
     'src/core/lib/iomgr/ev_epoll1_linux.cc',
     'src/core/lib/iomgr/ev_epollex_linux.cc',
     'src/core/lib/iomgr/ev_epollex_linux.cc',
     'src/core/lib/iomgr/ev_poll_posix.cc',
     'src/core/lib/iomgr/ev_poll_posix.cc',
@@ -110,6 +113,7 @@ CORE_SOURCE_FILES = [
     'src/core/lib/iomgr/iomgr_custom.cc',
     'src/core/lib/iomgr/iomgr_custom.cc',
     'src/core/lib/iomgr/iomgr_internal.cc',
     'src/core/lib/iomgr/iomgr_internal.cc',
     'src/core/lib/iomgr/iomgr_posix.cc',
     'src/core/lib/iomgr/iomgr_posix.cc',
+    'src/core/lib/iomgr/iomgr_posix_cfstream.cc',
     'src/core/lib/iomgr/iomgr_uv.cc',
     'src/core/lib/iomgr/iomgr_uv.cc',
     'src/core/lib/iomgr/iomgr_windows.cc',
     'src/core/lib/iomgr/iomgr_windows.cc',
     'src/core/lib/iomgr/is_epollexclusive_available.cc',
     'src/core/lib/iomgr/is_epollexclusive_available.cc',
@@ -138,6 +142,7 @@ CORE_SOURCE_FILES = [
     'src/core/lib/iomgr/socket_utils_windows.cc',
     'src/core/lib/iomgr/socket_utils_windows.cc',
     'src/core/lib/iomgr/socket_windows.cc',
     'src/core/lib/iomgr/socket_windows.cc',
     'src/core/lib/iomgr/tcp_client.cc',
     'src/core/lib/iomgr/tcp_client.cc',
+    'src/core/lib/iomgr/tcp_client_cfstream.cc',
     'src/core/lib/iomgr/tcp_client_custom.cc',
     'src/core/lib/iomgr/tcp_client_custom.cc',
     'src/core/lib/iomgr/tcp_client_posix.cc',
     'src/core/lib/iomgr/tcp_client_posix.cc',
     'src/core/lib/iomgr/tcp_client_windows.cc',
     'src/core/lib/iomgr/tcp_client_windows.cc',

+ 1 - 1
src/python/grpcio_tests/tests/health_check/_health_servicer_test.py

@@ -246,7 +246,7 @@ class HealthServicerTest(BaseWatchTests.WatchTests):
         resp = self._stub.Check(request)
         resp = self._stub.Check(request)
         self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status)
         self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status)
 
 
-    def test_check_unknown_serivce(self):
+    def test_check_unknown_service(self):
         request = health_pb2.HealthCheckRequest(service=_UNKNOWN_SERVICE)
         request = health_pb2.HealthCheckRequest(service=_UNKNOWN_SERVICE)
         resp = self._stub.Check(request)
         resp = self._stub.Check(request)
         self.assertEqual(health_pb2.HealthCheckResponse.UNKNOWN, resp.status)
         self.assertEqual(health_pb2.HealthCheckResponse.UNKNOWN, resp.status)

+ 2 - 10
templates/gRPC-Core.podspec.template

@@ -70,14 +70,6 @@
     excl = grpc_private_files(libs)
     excl = grpc_private_files(libs)
     return [file for file in out if not file in excl]
     return [file for file in out if not file in excl]
 
 
-  def cfstream_private_headers(libs):
-    out = grpc_lib_files(libs, ("grpc_cfstream",), ("own_headers",))
-    return out
-
-  def cfstream_private_files(libs):
-    out = grpc_lib_files(libs, ("grpc_cfstream",), ("own_src", "own_headers"))
-    return out
-
   def ruby_multiline_list(files, indent):
   def ruby_multiline_list(files, indent):
     return (',\n' + indent*' ').join('\'%s\'' % f for f in files)
     return (',\n' + indent*' ').join('\'%s\'' % f for f in files)
   %>
   %>
@@ -183,9 +175,9 @@
       ss.compiler_flags = '-DGRPC_SHADOW_BORINGSSL_SYMBOLS'
       ss.compiler_flags = '-DGRPC_SHADOW_BORINGSSL_SYMBOLS'
 
 
       # 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) + cfstream_private_files(filegroups), 22)}
+      ss.source_files = ${ruby_multiline_list(grpc_private_files(libs), 22)}
 
 
-      ss.private_header_files = ${ruby_multiline_list(grpc_private_headers(libs) + cfstream_private_headers(filegroups), 30)}
+      ss.private_header_files = ${ruby_multiline_list(grpc_private_headers(libs), 30)}
     end
     end
 
 
     # CFStream is now default. Leaving this subspec only for compatibility purpose.
     # CFStream is now default. Leaving this subspec only for compatibility purpose.

+ 0 - 1
templates/tools/dockerfile/debian_jessie_header.include

@@ -1,2 +1 @@
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list

+ 1 - 1
test/core/bad_client/bad_client.cc

@@ -257,7 +257,7 @@ bool client_connection_preface_validator(grpc_slice_buffer* incoming,
     return false;
     return false;
   }
   }
   grpc_slice slice = incoming->slices[0];
   grpc_slice slice = incoming->slices[0];
-  /* There should be atleast a settings frame present */
+  /* There should be at least one settings frame present */
   if (GRPC_SLICE_LENGTH(slice) < MIN_HTTP2_FRAME_SIZE) {
   if (GRPC_SLICE_LENGTH(slice) < MIN_HTTP2_FRAME_SIZE) {
     return false;
     return false;
   }
   }

+ 0 - 5
test/core/bad_connection/close_fd_test.cc

@@ -328,7 +328,6 @@ static void _test_close_before_server_recv(fd_type fdtype) {
    */
    */
   if (event.type == GRPC_QUEUE_TIMEOUT) {
   if (event.type == GRPC_QUEUE_TIMEOUT) {
     GPR_ASSERT(event.success == 0);
     GPR_ASSERT(event.success == 0);
-    GPR_ASSERT(event.tag == nullptr);
     /* status is not initialized */
     /* status is not initialized */
     GPR_ASSERT(status == GRPC_STATUS__DO_NOT_USE);
     GPR_ASSERT(status == GRPC_STATUS__DO_NOT_USE);
   } else {
   } else {
@@ -531,7 +530,6 @@ static void _test_close_before_server_send(fd_type fdtype) {
   } else {
   } else {
     GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT);
     GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT);
     GPR_ASSERT(event.success == 0);
     GPR_ASSERT(event.success == 0);
-    GPR_ASSERT(event.tag == nullptr);
     /* status is not initialized */
     /* status is not initialized */
     GPR_ASSERT(status == GRPC_STATUS__DO_NOT_USE);
     GPR_ASSERT(status == GRPC_STATUS__DO_NOT_USE);
   }
   }
@@ -664,7 +662,6 @@ static void _test_close_before_client_send(fd_type fdtype) {
       g_ctx.cq, grpc_timeout_milliseconds_to_deadline(100), nullptr);
       g_ctx.cq, grpc_timeout_milliseconds_to_deadline(100), nullptr);
   GPR_ASSERT(event.success == 0);
   GPR_ASSERT(event.success == 0);
   GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT);
   GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT);
-  GPR_ASSERT(event.tag == nullptr);
 
 
   grpc_slice_unref(details);
   grpc_slice_unref(details);
   grpc_metadata_array_destroy(&initial_metadata_recv);
   grpc_metadata_array_destroy(&initial_metadata_recv);
@@ -720,13 +717,11 @@ static void _test_close_before_call_create(fd_type fdtype) {
       g_ctx.client_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr);
       g_ctx.client_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr);
   GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT);
   GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT);
   GPR_ASSERT(event.success == 0);
   GPR_ASSERT(event.success == 0);
-  GPR_ASSERT(event.tag == nullptr);
 
 
   event = grpc_completion_queue_next(
   event = grpc_completion_queue_next(
       g_ctx.cq, grpc_timeout_milliseconds_to_deadline(100), nullptr);
       g_ctx.cq, grpc_timeout_milliseconds_to_deadline(100), nullptr);
   GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT);
   GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT);
   GPR_ASSERT(event.success == 0);
   GPR_ASSERT(event.success == 0);
-  GPR_ASSERT(event.tag == nullptr);
 
 
   grpc_call_unref(call);
   grpc_call_unref(call);
   end_test();
   end_test();

+ 11 - 9
test/core/gpr/arena_test.cc

@@ -16,7 +16,7 @@
  *
  *
  */
  */
 
 
-#include "src/core/lib/gpr/arena.h"
+#include "src/core/lib/gprpp/arena.h"
 
 
 #include <inttypes.h>
 #include <inttypes.h>
 #include <string.h>
 #include <string.h>
@@ -31,7 +31,9 @@
 #include "src/core/lib/gprpp/thd.h"
 #include "src/core/lib/gprpp/thd.h"
 #include "test/core/util/test_config.h"
 #include "test/core/util/test_config.h"
 
 
-static void test_noop(void) { gpr_arena_destroy(gpr_arena_create(1)); }
+using grpc_core::Arena;
+
+static void test_noop(void) { Arena::Create(1)->Destroy(); }
 
 
 static void test(const char* name, size_t init_size, const size_t* allocs,
 static void test(const char* name, size_t init_size, const size_t* allocs,
                  size_t nallocs) {
                  size_t nallocs) {
@@ -50,10 +52,10 @@ static void test(const char* name, size_t init_size, const size_t* allocs,
   gpr_log(GPR_INFO, "%s", s);
   gpr_log(GPR_INFO, "%s", s);
   gpr_free(s);
   gpr_free(s);
 
 
-  gpr_arena* a = gpr_arena_create(init_size);
+  Arena* a = Arena::Create(init_size);
   void** ps = static_cast<void**>(gpr_zalloc(sizeof(*ps) * nallocs));
   void** ps = static_cast<void**>(gpr_zalloc(sizeof(*ps) * nallocs));
   for (size_t i = 0; i < nallocs; i++) {
   for (size_t i = 0; i < nallocs; i++) {
-    ps[i] = gpr_arena_alloc(a, allocs[i]);
+    ps[i] = a->Alloc(allocs[i]);
     // ensure the returned address is aligned
     // ensure the returned address is aligned
     GPR_ASSERT(((intptr_t)ps[i] & 0xf) == 0);
     GPR_ASSERT(((intptr_t)ps[i] & 0xf) == 0);
     // ensure no duplicate results
     // ensure no duplicate results
@@ -63,7 +65,7 @@ static void test(const char* name, size_t init_size, const size_t* allocs,
     // ensure writable
     // ensure writable
     memset(ps[i], 1, allocs[i]);
     memset(ps[i], 1, allocs[i]);
   }
   }
-  gpr_arena_destroy(a);
+  a->Destroy();
   gpr_free(ps);
   gpr_free(ps);
 }
 }
 
 
@@ -80,14 +82,14 @@ size_t concurrent_test_iterations() {
 
 
 typedef struct {
 typedef struct {
   gpr_event ev_start;
   gpr_event ev_start;
-  gpr_arena* arena;
+  Arena* arena;
 } concurrent_test_args;
 } concurrent_test_args;
 
 
 static void concurrent_test_body(void* arg) {
 static void concurrent_test_body(void* arg) {
   concurrent_test_args* a = static_cast<concurrent_test_args*>(arg);
   concurrent_test_args* a = static_cast<concurrent_test_args*>(arg);
   gpr_event_wait(&a->ev_start, gpr_inf_future(GPR_CLOCK_REALTIME));
   gpr_event_wait(&a->ev_start, gpr_inf_future(GPR_CLOCK_REALTIME));
   for (size_t i = 0; i < concurrent_test_iterations(); i++) {
   for (size_t i = 0; i < concurrent_test_iterations(); i++) {
-    *static_cast<char*>(gpr_arena_alloc(a->arena, 1)) = static_cast<char>(i);
+    *static_cast<char*>(a->arena->Alloc(1)) = static_cast<char>(i);
   }
   }
 }
 }
 
 
@@ -96,7 +98,7 @@ static void concurrent_test(void) {
 
 
   concurrent_test_args args;
   concurrent_test_args args;
   gpr_event_init(&args.ev_start);
   gpr_event_init(&args.ev_start);
-  args.arena = gpr_arena_create(1024);
+  args.arena = Arena::Create(1024);
 
 
   grpc_core::Thread thds[CONCURRENT_TEST_THREADS];
   grpc_core::Thread thds[CONCURRENT_TEST_THREADS];
 
 
@@ -112,7 +114,7 @@ static void concurrent_test(void) {
     th.Join();
     th.Join();
   }
   }
 
 
-  gpr_arena_destroy(args.arena);
+  args.arena->Destroy();
 }
 }
 
 
 int main(int argc, char* argv[]) {
 int main(int argc, char* argv[]) {

+ 1 - 0
test/core/util/BUILD

@@ -132,6 +132,7 @@ grpc_cc_library(
     deps = [
     deps = [
         ":grpc_test_util",
         ":grpc_test_util",
         "//:grpc",
         "//:grpc",
+        "//test/cpp/util:test_config",
     ],
     ],
     tags = ["no_windows"],
     tags = ["no_windows"],
 )
 )

+ 2 - 1
test/core/util/fuzzer_corpus_test.cc

@@ -29,6 +29,7 @@
 #include "src/core/lib/gpr/env.h"
 #include "src/core/lib/gpr/env.h"
 #include "src/core/lib/iomgr/load_file.h"
 #include "src/core/lib/iomgr/load_file.h"
 #include "test/core/util/test_config.h"
 #include "test/core/util/test_config.h"
+#include "test/cpp/util/test_config.h"
 
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
 extern bool squelch;
 extern bool squelch;
@@ -145,8 +146,8 @@ INSTANTIATE_TEST_CASE_P(
 
 
 int main(int argc, char** argv) {
 int main(int argc, char** argv) {
   grpc::testing::TestEnvironment env(argc, argv);
   grpc::testing::TestEnvironment env(argc, argv);
-  ParseCommandLineFlags(&argc, &argv, true);
   ::testing::InitGoogleTest(&argc, argv);
   ::testing::InitGoogleTest(&argc, argv);
+  grpc::testing::InitTest(&argc, &argv, true);
 
 
   return RUN_ALL_TESTS();
   return RUN_ALL_TESTS();
 }
 }

+ 1 - 0
test/cpp/codegen/BUILD

@@ -66,6 +66,7 @@ grpc_cc_binary(
     deps = [
     deps = [
         "//:grpc++",
         "//:grpc++",
         "//test/core/util:grpc_test_util",
         "//test/core/util:grpc_test_util",
+        "//test/cpp/util:test_config",
     ],
     ],
 )
 )
 
 

+ 3 - 1
test/cpp/codegen/golden_file_test.cc

@@ -22,6 +22,8 @@
 #include <gflags/gflags.h>
 #include <gflags/gflags.h>
 #include <gtest/gtest.h>
 #include <gtest/gtest.h>
 
 
+#include "test/cpp/util/test_config.h"
+
 // In some distros, gflags is in the namespace google, and in some others,
 // In some distros, gflags is in the namespace google, and in some others,
 // in gflags. This hack is enabling us to find both.
 // in gflags. This hack is enabling us to find both.
 namespace google {}
 namespace google {}
@@ -67,7 +69,7 @@ TEST(GoldenMockFileTest, TestGeneratedMockFile) {
 
 
 int main(int argc, char** argv) {
 int main(int argc, char** argv) {
   ::testing::InitGoogleTest(&argc, argv);
   ::testing::InitGoogleTest(&argc, argv);
-  ParseCommandLineFlags(&argc, &argv, true);
+  grpc::testing::InitTest(&argc, &argv, true);
   if (FLAGS_generated_file_path.empty()) {
   if (FLAGS_generated_file_path.empty()) {
     FLAGS_generated_file_path = "gens/src/proto/grpc/testing/";
     FLAGS_generated_file_path = "gens/src/proto/grpc/testing/";
   }
   }

+ 2 - 0
test/cpp/end2end/BUILD

@@ -140,6 +140,7 @@ grpc_cc_binary(
         "//src/proto/grpc/testing:echo_proto",
         "//src/proto/grpc/testing:echo_proto",
         "//src/proto/grpc/testing/duplicate:echo_duplicate_proto",
         "//src/proto/grpc/testing/duplicate:echo_duplicate_proto",
         "//test/core/util:grpc_test_util",
         "//test/core/util:grpc_test_util",
+        "//test/cpp/util:test_config",
         "//test/cpp/util:test_util",
         "//test/cpp/util:test_util",
     ],
     ],
 )
 )
@@ -544,6 +545,7 @@ grpc_cc_binary(
         "//src/proto/grpc/testing:echo_proto",
         "//src/proto/grpc/testing:echo_proto",
         "//src/proto/grpc/testing/duplicate:echo_duplicate_proto",
         "//src/proto/grpc/testing/duplicate:echo_duplicate_proto",
         "//test/core/util:grpc_test_util",
         "//test/core/util:grpc_test_util",
+        "//test/cpp/util:test_config",
         "//test/cpp/util:test_util",
         "//test/cpp/util:test_util",
     ],
     ],
 )
 )

+ 2 - 1
test/cpp/end2end/client_crash_test_server.cc

@@ -27,6 +27,7 @@
 #include <grpcpp/server_context.h>
 #include <grpcpp/server_context.h>
 
 
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/cpp/util/test_config.h"
 
 
 DEFINE_string(address, "", "Address to bind to");
 DEFINE_string(address, "", "Address to bind to");
 
 
@@ -72,7 +73,7 @@ void RunServer() {
 }  // namespace grpc
 }  // namespace grpc
 
 
 int main(int argc, char** argv) {
 int main(int argc, char** argv) {
-  ParseCommandLineFlags(&argc, &argv, true);
+  grpc::testing::InitTest(&argc, &argv, true);
   grpc::testing::RunServer();
   grpc::testing::RunServer();
 
 
   return 0;
   return 0;

+ 2 - 8
test/cpp/end2end/server_crash_test_client.cc

@@ -28,6 +28,7 @@
 #include <grpcpp/create_channel.h>
 #include <grpcpp/create_channel.h>
 
 
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/cpp/util/test_config.h"
 
 
 DEFINE_string(address, "", "Address to connect to");
 DEFINE_string(address, "", "Address to connect to");
 DEFINE_string(mode, "", "Test mode to use");
 DEFINE_string(mode, "", "Test mode to use");
@@ -35,15 +36,8 @@ DEFINE_string(mode, "", "Test mode to use");
 using grpc::testing::EchoRequest;
 using grpc::testing::EchoRequest;
 using grpc::testing::EchoResponse;
 using grpc::testing::EchoResponse;
 
 
-// In some distros, gflags is in the namespace google, and in some others,
-// in gflags. This hack is enabling us to find both.
-namespace google {}
-namespace gflags {}
-using namespace google;
-using namespace gflags;
-
 int main(int argc, char** argv) {
 int main(int argc, char** argv) {
-  ParseCommandLineFlags(&argc, &argv, true);
+  grpc::testing::InitTest(&argc, &argv, true);
   auto stub = grpc::testing::EchoTestService::NewStub(
   auto stub = grpc::testing::EchoTestService::NewStub(
       grpc::CreateChannel(FLAGS_address, grpc::InsecureChannelCredentials()));
       grpc::CreateChannel(FLAGS_address, grpc::InsecureChannelCredentials()));
 
 

+ 12 - 10
test/cpp/microbenchmarks/bm_arena.cc

@@ -19,40 +19,42 @@
 /* Benchmark arenas */
 /* Benchmark arenas */
 
 
 #include <benchmark/benchmark.h>
 #include <benchmark/benchmark.h>
-#include "src/core/lib/gpr/arena.h"
+#include "src/core/lib/gprpp/arena.h"
 #include "test/cpp/microbenchmarks/helpers.h"
 #include "test/cpp/microbenchmarks/helpers.h"
 #include "test/cpp/util/test_config.h"
 #include "test/cpp/util/test_config.h"
 
 
+using grpc_core::Arena;
+
 static void BM_Arena_NoOp(benchmark::State& state) {
 static void BM_Arena_NoOp(benchmark::State& state) {
   while (state.KeepRunning()) {
   while (state.KeepRunning()) {
-    gpr_arena_destroy(gpr_arena_create(state.range(0)));
+    Arena::Create(state.range(0))->Destroy();
   }
   }
 }
 }
 BENCHMARK(BM_Arena_NoOp)->Range(1, 1024 * 1024);
 BENCHMARK(BM_Arena_NoOp)->Range(1, 1024 * 1024);
 
 
 static void BM_Arena_ManyAlloc(benchmark::State& state) {
 static void BM_Arena_ManyAlloc(benchmark::State& state) {
-  gpr_arena* a = gpr_arena_create(state.range(0));
+  Arena* a = Arena::Create(state.range(0));
   const size_t realloc_after =
   const size_t realloc_after =
       1024 * 1024 * 1024 / ((state.range(1) + 15) & 0xffffff0u);
       1024 * 1024 * 1024 / ((state.range(1) + 15) & 0xffffff0u);
   while (state.KeepRunning()) {
   while (state.KeepRunning()) {
-    gpr_arena_alloc(a, state.range(1));
+    a->Alloc(state.range(1));
     // periodically recreate arena to avoid OOM
     // periodically recreate arena to avoid OOM
     if (state.iterations() % realloc_after == 0) {
     if (state.iterations() % realloc_after == 0) {
-      gpr_arena_destroy(a);
-      a = gpr_arena_create(state.range(0));
+      a->Destroy();
+      a = Arena::Create(state.range(0));
     }
     }
   }
   }
-  gpr_arena_destroy(a);
+  a->Destroy();
 }
 }
 BENCHMARK(BM_Arena_ManyAlloc)->Ranges({{1, 1024 * 1024}, {1, 32 * 1024}});
 BENCHMARK(BM_Arena_ManyAlloc)->Ranges({{1, 1024 * 1024}, {1, 32 * 1024}});
 
 
 static void BM_Arena_Batch(benchmark::State& state) {
 static void BM_Arena_Batch(benchmark::State& state) {
   while (state.KeepRunning()) {
   while (state.KeepRunning()) {
-    gpr_arena* a = gpr_arena_create(state.range(0));
+    Arena* a = Arena::Create(state.range(0));
     for (int i = 0; i < state.range(1); i++) {
     for (int i = 0; i < state.range(1); i++) {
-      gpr_arena_alloc(a, state.range(2));
+      a->Alloc(state.range(2));
     }
     }
-    gpr_arena_destroy(a);
+    a->Destroy();
   }
   }
 }
 }
 BENCHMARK(BM_Arena_Batch)->Ranges({{1, 64 * 1024}, {1, 64}, {1, 1024}});
 BENCHMARK(BM_Arena_Batch)->Ranges({{1, 64 * 1024}, {1, 64}, {1, 1024}});

+ 5 - 5
test/cpp/microbenchmarks/bm_call_create.cc

@@ -405,7 +405,7 @@ const char* name;
 /* implementation of grpc_transport_init_stream */
 /* implementation of grpc_transport_init_stream */
 int InitStream(grpc_transport* self, grpc_stream* stream,
 int InitStream(grpc_transport* self, grpc_stream* stream,
                grpc_stream_refcount* refcount, const void* server_data,
                grpc_stream_refcount* refcount, const void* server_data,
-               gpr_arena* arena) {
+               grpc_core::Arena* arena) {
   return 0;
   return 0;
 }
 }
 
 
@@ -540,7 +540,7 @@ static void BM_IsolatedFilter(benchmark::State& state) {
                                    method,
                                    method,
                                    start_time,
                                    start_time,
                                    deadline,
                                    deadline,
-                                   gpr_arena_create(kArenaSize),
+                                   grpc_core::Arena::Create(kArenaSize),
                                    nullptr};
                                    nullptr};
   while (state.KeepRunning()) {
   while (state.KeepRunning()) {
     GPR_TIMER_SCOPE("BenchmarkCycle", 0);
     GPR_TIMER_SCOPE("BenchmarkCycle", 0);
@@ -552,11 +552,11 @@ static void BM_IsolatedFilter(benchmark::State& state) {
     grpc_core::ExecCtx::Get()->Flush();
     grpc_core::ExecCtx::Get()->Flush();
     // recreate arena every 64k iterations to avoid oom
     // recreate arena every 64k iterations to avoid oom
     if (0 == (state.iterations() & 0xffff)) {
     if (0 == (state.iterations() & 0xffff)) {
-      gpr_arena_destroy(call_args.arena);
-      call_args.arena = gpr_arena_create(kArenaSize);
+      call_args.arena->Destroy();
+      call_args.arena = grpc_core::Arena::Create(kArenaSize);
     }
     }
   }
   }
-  gpr_arena_destroy(call_args.arena);
+  call_args.arena->Destroy();
   grpc_channel_stack_destroy(channel_stack);
   grpc_channel_stack_destroy(channel_stack);
   grpc_core::ExecCtx::Get()->Flush();
   grpc_core::ExecCtx::Get()->Flush();
 
 

+ 6 - 5
test/cpp/microbenchmarks/bm_chttp2_hpack.cc

@@ -458,7 +458,7 @@ static void BM_HpackParserParseHeader(benchmark::State& state) {
   grpc_chttp2_hpack_parser p;
   grpc_chttp2_hpack_parser p;
   grpc_chttp2_hpack_parser_init(&p);
   grpc_chttp2_hpack_parser_init(&p);
   const int kArenaSize = 4096 * 4096;
   const int kArenaSize = 4096 * 4096;
-  p.on_header_user_data = gpr_arena_create(kArenaSize);
+  p.on_header_user_data = grpc_core::Arena::Create(kArenaSize);
   p.on_header = OnHeader;
   p.on_header = OnHeader;
   for (auto slice : init_slices) {
   for (auto slice : init_slices) {
     GPR_ASSERT(GRPC_ERROR_NONE == grpc_chttp2_hpack_parser_parse(&p, slice));
     GPR_ASSERT(GRPC_ERROR_NONE == grpc_chttp2_hpack_parser_parse(&p, slice));
@@ -470,12 +470,12 @@ static void BM_HpackParserParseHeader(benchmark::State& state) {
     grpc_core::ExecCtx::Get()->Flush();
     grpc_core::ExecCtx::Get()->Flush();
     // Recreate arena every 4k iterations to avoid oom
     // Recreate arena every 4k iterations to avoid oom
     if (0 == (state.iterations() & 0xfff)) {
     if (0 == (state.iterations() & 0xfff)) {
-      gpr_arena_destroy((gpr_arena*)p.on_header_user_data);
-      p.on_header_user_data = gpr_arena_create(kArenaSize);
+      static_cast<grpc_core::Arena*>(p.on_header_user_data)->Destroy();
+      p.on_header_user_data = grpc_core::Arena::Create(kArenaSize);
     }
     }
   }
   }
   // Clean up
   // Clean up
-  gpr_arena_destroy((gpr_arena*)p.on_header_user_data);
+  static_cast<grpc_core::Arena*>(p.on_header_user_data)->Destroy();
   for (auto slice : init_slices) grpc_slice_unref(slice);
   for (auto slice : init_slices) grpc_slice_unref(slice);
   for (auto slice : benchmark_slices) grpc_slice_unref(slice);
   for (auto slice : benchmark_slices) grpc_slice_unref(slice);
   grpc_chttp2_hpack_parser_destroy(&p);
   grpc_chttp2_hpack_parser_destroy(&p);
@@ -778,7 +778,8 @@ static void free_timeout(void* p) { gpr_free(p); }
 // Benchmark the current on_initial_header implementation
 // Benchmark the current on_initial_header implementation
 static void OnInitialHeader(void* user_data, grpc_mdelem md) {
 static void OnInitialHeader(void* user_data, grpc_mdelem md) {
   // Setup for benchmark. This will bloat the absolute values of this benchmark
   // Setup for benchmark. This will bloat the absolute values of this benchmark
-  grpc_chttp2_incoming_metadata_buffer buffer((gpr_arena*)user_data);
+  grpc_chttp2_incoming_metadata_buffer buffer(
+      static_cast<grpc_core::Arena*>(user_data));
   bool seen_error = false;
   bool seen_error = false;
 
 
   // Below here is the code we actually care about benchmarking
   // Below here is the code we actually care about benchmarking

+ 5 - 5
test/cpp/microbenchmarks/bm_chttp2_transport.cc

@@ -193,13 +193,13 @@ class Stream {
   Stream(Fixture* f) : f_(f) {
   Stream(Fixture* f) : f_(f) {
     stream_size_ = grpc_transport_stream_size(f->transport());
     stream_size_ = grpc_transport_stream_size(f->transport());
     stream_ = gpr_malloc(stream_size_);
     stream_ = gpr_malloc(stream_size_);
-    arena_ = gpr_arena_create(4096);
+    arena_ = grpc_core::Arena::Create(4096);
   }
   }
 
 
   ~Stream() {
   ~Stream() {
     gpr_event_wait(&done_, gpr_inf_future(GPR_CLOCK_REALTIME));
     gpr_event_wait(&done_, gpr_inf_future(GPR_CLOCK_REALTIME));
     gpr_free(stream_);
     gpr_free(stream_);
-    gpr_arena_destroy(arena_);
+    arena_->Destroy();
   }
   }
 
 
   void Init(benchmark::State& state) {
   void Init(benchmark::State& state) {
@@ -208,8 +208,8 @@ class Stream {
     gpr_event_init(&done_);
     gpr_event_init(&done_);
     memset(stream_, 0, stream_size_);
     memset(stream_, 0, stream_size_);
     if ((state.iterations() & 0xffff) == 0) {
     if ((state.iterations() & 0xffff) == 0) {
-      gpr_arena_destroy(arena_);
-      arena_ = gpr_arena_create(4096);
+      arena_->Destroy();
+      arena_ = grpc_core::Arena::Create(4096);
     }
     }
     grpc_transport_init_stream(f_->transport(),
     grpc_transport_init_stream(f_->transport(),
                                static_cast<grpc_stream*>(stream_), &refcount_,
                                static_cast<grpc_stream*>(stream_), &refcount_,
@@ -245,7 +245,7 @@ class Stream {
 
 
   Fixture* f_;
   Fixture* f_;
   grpc_stream_refcount refcount_;
   grpc_stream_refcount refcount_;
-  gpr_arena* arena_;
+  grpc_core::Arena* arena_;
   size_t stream_size_;
   size_t stream_size_;
   void* stream_;
   void* stream_;
   grpc_closure* destroy_closure_ = nullptr;
   grpc_closure* destroy_closure_ = nullptr;

+ 1 - 1
test/cpp/microbenchmarks/bm_cq_multiple_threads.cc

@@ -138,7 +138,7 @@ static void teardown() {
  Setup:
  Setup:
   The benchmark framework ensures that none of the threads proceed beyond the
   The benchmark framework ensures that none of the threads proceed beyond the
   state.KeepRunning() call unless all the threads have called state.keepRunning
   state.KeepRunning() call unless all the threads have called state.keepRunning
-  atleast once.  So it is safe to do the initialization in one of the threads
+  at least once.  So it is safe to do the initialization in one of the threads
   before state.KeepRunning() is called.
   before state.KeepRunning() is called.
 
 
  Teardown:
  Teardown:

+ 1 - 1
test/cpp/naming/resolver_component_test.cc

@@ -554,7 +554,7 @@ int main(int argc, char** argv) {
   grpc_init();
   grpc_init();
   grpc::testing::TestEnvironment env(argc, argv);
   grpc::testing::TestEnvironment env(argc, argv);
   ::testing::InitGoogleTest(&argc, argv);
   ::testing::InitGoogleTest(&argc, argv);
-  ParseCommandLineFlags(&argc, &argv, true);
+  grpc::testing::InitTest(&argc, &argv, true);
   if (FLAGS_target_name == "") {
   if (FLAGS_target_name == "") {
     gpr_log(GPR_ERROR, "Missing target_name param.");
     gpr_log(GPR_ERROR, "Missing target_name param.");
     abort();
     abort();

+ 12 - 2
test/cpp/qps/client_callback.cc

@@ -285,8 +285,18 @@ class CallbackStreamingPingPongReactor final
       }
       }
       return;
       return;
     }
     }
-    write_time_ = UsageTimer::Now();
-    StartWrite(client_->request());
+    if (!client_->IsClosedLoop()) {
+      gpr_timespec next_issue_time = client_->NextRPCIssueTime();
+      // Start an alarm callback to run the internal callback after
+      // next_issue_time
+      ctx_->alarm_.experimental().Set(next_issue_time, [this](bool ok) {
+        write_time_ = UsageTimer::Now();
+        StartWrite(client_->request());
+      });
+    } else {
+      write_time_ = UsageTimer::Now();
+      StartWrite(client_->request());
+    }
   }
   }
 
 
   void OnDone(const Status& s) override {
   void OnDone(const Status& s) override {

+ 0 - 1
tools/dockerfile/grpc_clang_format/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 RUN apt-get update && apt-get -y install wget xz-utils
 RUN apt-get update && apt-get -y install wget xz-utils

+ 0 - 1
tools/dockerfile/grpc_clang_tidy/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 RUN apt-get update && apt-get -y install wget xz-utils
 RUN apt-get update && apt-get -y install wget xz-utils

+ 0 - 1
tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 # Install Git and basic packages.
 # Install Git and basic packages.

+ 0 - 1
tools/dockerfile/interoptest/grpc_interop_java/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 # Install JDK 8
 # Install JDK 8

+ 0 - 1
tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 # Install JDK 8
 # Install JDK 8

+ 0 - 1
tools/dockerfile/interoptest/grpc_interop_node/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 # Install Git and basic packages.
 # Install Git and basic packages.

+ 0 - 1
tools/dockerfile/interoptest/grpc_interop_nodepurejs/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 # Install Git and basic packages.
 # Install Git and basic packages.

+ 0 - 1
tools/dockerfile/interoptest/grpc_interop_php/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 # Install Git and basic packages.
 # Install Git and basic packages.

+ 0 - 1
tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 #=================
 #=================

+ 0 - 1
tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 # Install Git and basic packages.
 # Install Git and basic packages.

+ 0 - 1
tools/dockerfile/test/cxx_jessie_x64/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 # Install Git and basic packages.
 # Install Git and basic packages.

+ 0 - 1
tools/dockerfile/test/fuzzer/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 # Install Git and basic packages.
 # Install Git and basic packages.

+ 0 - 1
tools/dockerfile/test/node_jessie_x64/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 # Install Git and basic packages.
 # Install Git and basic packages.

+ 0 - 1
tools/dockerfile/test/php7_jessie_x64/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 #=================
 #=================

+ 0 - 1
tools/dockerfile/test/php_jessie_x64/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 # Install Git and basic packages.
 # Install Git and basic packages.

+ 0 - 1
tools/dockerfile/test/python_jessie_x64/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 # Install Git and basic packages.
 # Install Git and basic packages.

+ 0 - 1
tools/dockerfile/test/ruby_jessie_x64/Dockerfile

@@ -13,7 +13,6 @@
 # limitations under the License.
 # limitations under the License.
 
 
 FROM debian:jessie
 FROM debian:jessie
-RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list
 
 
 
 
 # Install Git and basic packages.
 # Install Git and basic packages.

+ 4 - 0
tools/doxygen/Doxyfile.c++.internal

@@ -1082,6 +1082,7 @@ src/core/lib/gpr/tls_pthread.h \
 src/core/lib/gpr/tmpfile.h \
 src/core/lib/gpr/tmpfile.h \
 src/core/lib/gpr/useful.h \
 src/core/lib/gpr/useful.h \
 src/core/lib/gprpp/abstract.h \
 src/core/lib/gprpp/abstract.h \
+src/core/lib/gprpp/arena.h \
 src/core/lib/gprpp/atomic.h \
 src/core/lib/gprpp/atomic.h \
 src/core/lib/gprpp/debug_location.h \
 src/core/lib/gprpp/debug_location.h \
 src/core/lib/gprpp/fork.h \
 src/core/lib/gprpp/fork.h \
@@ -1102,12 +1103,15 @@ src/core/lib/http/parser.h \
 src/core/lib/iomgr/block_annotate.h \
 src/core/lib/iomgr/block_annotate.h \
 src/core/lib/iomgr/buffer_list.h \
 src/core/lib/iomgr/buffer_list.h \
 src/core/lib/iomgr/call_combiner.h \
 src/core/lib/iomgr/call_combiner.h \
+src/core/lib/iomgr/cfstream_handle.h \
 src/core/lib/iomgr/closure.h \
 src/core/lib/iomgr/closure.h \
 src/core/lib/iomgr/combiner.h \
 src/core/lib/iomgr/combiner.h \
 src/core/lib/iomgr/dynamic_annotations.h \
 src/core/lib/iomgr/dynamic_annotations.h \
 src/core/lib/iomgr/endpoint.h \
 src/core/lib/iomgr/endpoint.h \
+src/core/lib/iomgr/endpoint_cfstream.h \
 src/core/lib/iomgr/endpoint_pair.h \
 src/core/lib/iomgr/endpoint_pair.h \
 src/core/lib/iomgr/error.h \
 src/core/lib/iomgr/error.h \
+src/core/lib/iomgr/error_cfstream.h \
 src/core/lib/iomgr/error_internal.h \
 src/core/lib/iomgr/error_internal.h \
 src/core/lib/iomgr/ev_epoll1_linux.h \
 src/core/lib/iomgr/ev_epoll1_linux.h \
 src/core/lib/iomgr/ev_epollex_linux.h \
 src/core/lib/iomgr/ev_epollex_linux.h \

+ 10 - 1
tools/doxygen/Doxyfile.core.internal

@@ -1110,7 +1110,6 @@ src/core/lib/debug/trace.h \
 src/core/lib/gpr/README.md \
 src/core/lib/gpr/README.md \
 src/core/lib/gpr/alloc.cc \
 src/core/lib/gpr/alloc.cc \
 src/core/lib/gpr/alloc.h \
 src/core/lib/gpr/alloc.h \
-src/core/lib/gpr/arena.cc \
 src/core/lib/gpr/arena.h \
 src/core/lib/gpr/arena.h \
 src/core/lib/gpr/atm.cc \
 src/core/lib/gpr/atm.cc \
 src/core/lib/gpr/cpu_iphone.cc \
 src/core/lib/gpr/cpu_iphone.cc \
@@ -1160,6 +1159,8 @@ src/core/lib/gpr/useful.h \
 src/core/lib/gpr/wrap_memcpy.cc \
 src/core/lib/gpr/wrap_memcpy.cc \
 src/core/lib/gprpp/README.md \
 src/core/lib/gprpp/README.md \
 src/core/lib/gprpp/abstract.h \
 src/core/lib/gprpp/abstract.h \
+src/core/lib/gprpp/arena.cc \
+src/core/lib/gprpp/arena.h \
 src/core/lib/gprpp/atomic.h \
 src/core/lib/gprpp/atomic.h \
 src/core/lib/gprpp/debug_location.h \
 src/core/lib/gprpp/debug_location.h \
 src/core/lib/gprpp/fork.cc \
 src/core/lib/gprpp/fork.cc \
@@ -1190,18 +1191,24 @@ src/core/lib/iomgr/buffer_list.cc \
 src/core/lib/iomgr/buffer_list.h \
 src/core/lib/iomgr/buffer_list.h \
 src/core/lib/iomgr/call_combiner.cc \
 src/core/lib/iomgr/call_combiner.cc \
 src/core/lib/iomgr/call_combiner.h \
 src/core/lib/iomgr/call_combiner.h \
+src/core/lib/iomgr/cfstream_handle.cc \
+src/core/lib/iomgr/cfstream_handle.h \
 src/core/lib/iomgr/closure.h \
 src/core/lib/iomgr/closure.h \
 src/core/lib/iomgr/combiner.cc \
 src/core/lib/iomgr/combiner.cc \
 src/core/lib/iomgr/combiner.h \
 src/core/lib/iomgr/combiner.h \
 src/core/lib/iomgr/dynamic_annotations.h \
 src/core/lib/iomgr/dynamic_annotations.h \
 src/core/lib/iomgr/endpoint.cc \
 src/core/lib/iomgr/endpoint.cc \
 src/core/lib/iomgr/endpoint.h \
 src/core/lib/iomgr/endpoint.h \
+src/core/lib/iomgr/endpoint_cfstream.cc \
+src/core/lib/iomgr/endpoint_cfstream.h \
 src/core/lib/iomgr/endpoint_pair.h \
 src/core/lib/iomgr/endpoint_pair.h \
 src/core/lib/iomgr/endpoint_pair_posix.cc \
 src/core/lib/iomgr/endpoint_pair_posix.cc \
 src/core/lib/iomgr/endpoint_pair_uv.cc \
 src/core/lib/iomgr/endpoint_pair_uv.cc \
 src/core/lib/iomgr/endpoint_pair_windows.cc \
 src/core/lib/iomgr/endpoint_pair_windows.cc \
 src/core/lib/iomgr/error.cc \
 src/core/lib/iomgr/error.cc \
 src/core/lib/iomgr/error.h \
 src/core/lib/iomgr/error.h \
+src/core/lib/iomgr/error_cfstream.cc \
+src/core/lib/iomgr/error_cfstream.h \
 src/core/lib/iomgr/error_internal.h \
 src/core/lib/iomgr/error_internal.h \
 src/core/lib/iomgr/ev_epoll1_linux.cc \
 src/core/lib/iomgr/ev_epoll1_linux.cc \
 src/core/lib/iomgr/ev_epoll1_linux.h \
 src/core/lib/iomgr/ev_epoll1_linux.h \
@@ -1237,6 +1244,7 @@ src/core/lib/iomgr/iomgr_internal.cc \
 src/core/lib/iomgr/iomgr_internal.h \
 src/core/lib/iomgr/iomgr_internal.h \
 src/core/lib/iomgr/iomgr_posix.cc \
 src/core/lib/iomgr/iomgr_posix.cc \
 src/core/lib/iomgr/iomgr_posix.h \
 src/core/lib/iomgr/iomgr_posix.h \
+src/core/lib/iomgr/iomgr_posix_cfstream.cc \
 src/core/lib/iomgr/iomgr_uv.cc \
 src/core/lib/iomgr/iomgr_uv.cc \
 src/core/lib/iomgr/iomgr_windows.cc \
 src/core/lib/iomgr/iomgr_windows.cc \
 src/core/lib/iomgr/is_epollexclusive_available.cc \
 src/core/lib/iomgr/is_epollexclusive_available.cc \
@@ -1292,6 +1300,7 @@ src/core/lib/iomgr/socket_windows.h \
 src/core/lib/iomgr/sys_epoll_wrapper.h \
 src/core/lib/iomgr/sys_epoll_wrapper.h \
 src/core/lib/iomgr/tcp_client.cc \
 src/core/lib/iomgr/tcp_client.cc \
 src/core/lib/iomgr/tcp_client.h \
 src/core/lib/iomgr/tcp_client.h \
+src/core/lib/iomgr/tcp_client_cfstream.cc \
 src/core/lib/iomgr/tcp_client_custom.cc \
 src/core/lib/iomgr/tcp_client_custom.cc \
 src/core/lib/iomgr/tcp_client_posix.cc \
 src/core/lib/iomgr/tcp_client_posix.cc \
 src/core/lib/iomgr/tcp_client_posix.h \
 src/core/lib/iomgr/tcp_client_posix.h \

+ 2 - 0
tools/internal_ci/linux/grpc_publish_packages.cfg

@@ -24,3 +24,5 @@ action {
     regex: "github/grpc/artifacts/**"
     regex: "github/grpc/artifacts/**"
   }
   }
 }
 }
+
+gfile_resources: "/bigstore/grpc-testing-secrets/nuget_credentials/artifactory_grpc_nuget_dev_api_key"

+ 13 - 0
tools/internal_ci/linux/grpc_publish_packages.sh

@@ -233,3 +233,16 @@ gsutil -m cp -r "$LOCAL_STAGING_TEMPDIR/${BUILD_RELPATH%%/*}" "$GCS_ARCHIVE_ROOT
 )
 )
 # Upload the new /index.xml
 # Upload the new /index.xml
 gsutil -h "Content-Type:application/xml" cp "$NEW_INDEX" "$GCS_INDEX"
 gsutil -h "Content-Type:application/xml" cp "$NEW_INDEX" "$GCS_INDEX"
+
+# Upload C# nugets to the dev nuget feed
+pushd "$UNZIPPED_CSHARP_PACKAGES"
+docker pull mcr.microsoft.com/dotnet/core/sdk:2.1
+for nugetfile in *.nupkg
+do
+  echo "Going to push $nugetfile"
+  # use nuget from a docker container to push the nupkg
+  set +x  # IMPORTANT: avoid revealing the nuget api key by the command echo
+  docker run -v "$(pwd):/nugets:ro" --rm=true mcr.microsoft.com/dotnet/core/sdk:2.1 bash -c "dotnet nuget push /nugets/$nugetfile -k $(cat ${KOKORO_GFILE_DIR}/artifactory_grpc_nuget_dev_api_key) --source https://grpc.jfrog.io/grpc/api/nuget/v3/grpc-nuget-dev"
+  set -ex
+done
+popd

+ 5 - 2
tools/interop_matrix/client_matrix.py

@@ -100,6 +100,7 @@ LANG_RELEASE_MATRIX = {
         ('v1.17.1', ReleaseInfo()),
         ('v1.17.1', ReleaseInfo()),
         ('v1.18.0', ReleaseInfo()),
         ('v1.18.0', ReleaseInfo()),
         ('v1.19.0', ReleaseInfo()),
         ('v1.19.0', ReleaseInfo()),
+        ('v1.20.0', ReleaseInfo()),
     ]),
     ]),
     'go':
     'go':
     OrderedDict([
     OrderedDict([
@@ -169,6 +170,7 @@ LANG_RELEASE_MATRIX = {
         ('v1.17.1', ReleaseInfo(testcases_file='python__v1.11.1')),
         ('v1.17.1', ReleaseInfo(testcases_file='python__v1.11.1')),
         ('v1.18.0', ReleaseInfo()),
         ('v1.18.0', ReleaseInfo()),
         ('v1.19.0', ReleaseInfo()),
         ('v1.19.0', ReleaseInfo()),
+        ('v1.20.0', ReleaseInfo()),
     ]),
     ]),
     'node':
     'node':
     OrderedDict([
     OrderedDict([
@@ -267,7 +269,8 @@ LANG_RELEASE_MATRIX = {
         ('v1.15.0', ReleaseInfo(testcases_file='csharp__v1.3.9')),
         ('v1.15.0', ReleaseInfo(testcases_file='csharp__v1.3.9')),
         ('v1.16.0', ReleaseInfo(testcases_file='csharp__v1.3.9')),
         ('v1.16.0', ReleaseInfo(testcases_file='csharp__v1.3.9')),
         ('v1.17.1', ReleaseInfo(testcases_file='csharp__v1.3.9')),
         ('v1.17.1', ReleaseInfo(testcases_file='csharp__v1.3.9')),
-        ('v1.18.0', ReleaseInfo()),
-        ('v1.19.0', ReleaseInfo()),
+        ('v1.18.0', ReleaseInfo(testcases_file='csharp__v1.18.0')),
+        ('v1.19.0', ReleaseInfo(testcases_file='csharp__v1.18.0')),
+        ('v1.20.0', ReleaseInfo()),
     ]),
     ]),
 }
 }

+ 1 - 1
tools/interop_matrix/testcases/csharp__master

@@ -1,7 +1,7 @@
 #!/bin/bash
 #!/bin/bash
 # DO NOT MODIFY
 # DO NOT MODIFY
 # This file is generated by run_interop_tests.py/create_testcases.sh
 # This file is generated by run_interop_tests.py/create_testcases.sh
-echo "Testing ${docker_image:=grpc_interop_csharp:71b05977-476b-4e57-9752-dd211c9e3741}"
+echo "Testing ${docker_image:=grpc_interop_csharp:9296f21a-f657-4bb0-82a7-24fc527abcbd}"
 docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
 docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
 docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
 docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
 docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"
 docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"

+ 23 - 0
tools/interop_matrix/testcases/csharp__v1.18.0

@@ -0,0 +1,23 @@
+#!/bin/bash
+# DO NOT MODIFY
+# This file is generated by run_interop_tests.py/create_testcases.sh
+echo "Testing ${docker_image:=grpc_interop_csharp:71b05977-476b-4e57-9752-dd211c9e3741}"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true"
+

+ 19 - 19
tools/interop_matrix/testcases/csharpcoreclr__master

@@ -1,22 +1,22 @@
 #!/bin/bash
 #!/bin/bash
 # DO NOT MODIFY
 # DO NOT MODIFY
 # This file is generated by run_interop_tests.py/create_testcases.sh
 # This file is generated by run_interop_tests.py/create_testcases.sh
-echo "Testing ${docker_image:=grpc_interop_csharpcoreclr:bae17a7e-5450-4781-8982-e82cb89db6dd}"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true"
-docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true"
+echo "Testing ${docker_image:=grpc_interop_csharpcoreclr:33395965-11d7-4b12-bcd6-a272d4015207}"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true"

+ 22 - 0
tools/interop_matrix/testcases/csharpcoreclr__v1.18.0

@@ -0,0 +1,22 @@
+#!/bin/bash
+# DO NOT MODIFY
+# This file is generated by run_interop_tests.py/create_testcases.sh
+echo "Testing ${docker_image:=grpc_interop_csharpcoreclr:bae17a7e-5450-4781-8982-e82cb89db6dd}"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true"

+ 18 - 29
tools/run_tests/generated/sources_and_headers.json

@@ -3335,6 +3335,7 @@
       "gpr", 
       "gpr", 
       "grpc", 
       "grpc", 
       "grpc++", 
       "grpc++", 
+      "grpc++_test_config", 
       "grpc++_test_util", 
       "grpc++_test_util", 
       "grpc_test_util"
       "grpc_test_util"
     ], 
     ], 
@@ -3665,7 +3666,8 @@
     "deps": [
     "deps": [
       "gpr", 
       "gpr", 
       "grpc", 
       "grpc", 
-      "grpc++"
+      "grpc++", 
+      "grpc++_test_config"
     ], 
     ], 
     "headers": [
     "headers": [
       "src/proto/grpc/testing/compiler_test.grpc.pb.h", 
       "src/proto/grpc/testing/compiler_test.grpc.pb.h", 
@@ -4684,6 +4686,7 @@
       "gpr", 
       "gpr", 
       "grpc", 
       "grpc", 
       "grpc++", 
       "grpc++", 
+      "grpc++_test_config", 
       "grpc++_test_util", 
       "grpc++_test_util", 
       "grpc_test_util"
       "grpc_test_util"
     ], 
     ], 
@@ -7982,7 +7985,6 @@
     "name": "gpr_base", 
     "name": "gpr_base", 
     "src": [
     "src": [
       "src/core/lib/gpr/alloc.cc", 
       "src/core/lib/gpr/alloc.cc", 
-      "src/core/lib/gpr/arena.cc", 
       "src/core/lib/gpr/atm.cc", 
       "src/core/lib/gpr/atm.cc", 
       "src/core/lib/gpr/cpu_iphone.cc", 
       "src/core/lib/gpr/cpu_iphone.cc", 
       "src/core/lib/gpr/cpu_linux.cc", 
       "src/core/lib/gpr/cpu_linux.cc", 
@@ -8015,6 +8017,7 @@
       "src/core/lib/gpr/tmpfile_posix.cc", 
       "src/core/lib/gpr/tmpfile_posix.cc", 
       "src/core/lib/gpr/tmpfile_windows.cc", 
       "src/core/lib/gpr/tmpfile_windows.cc", 
       "src/core/lib/gpr/wrap_memcpy.cc", 
       "src/core/lib/gpr/wrap_memcpy.cc", 
+      "src/core/lib/gprpp/arena.cc", 
       "src/core/lib/gprpp/fork.cc", 
       "src/core/lib/gprpp/fork.cc", 
       "src/core/lib/gprpp/thd_posix.cc", 
       "src/core/lib/gprpp/thd_posix.cc", 
       "src/core/lib/gprpp/thd_windows.cc", 
       "src/core/lib/gprpp/thd_windows.cc", 
@@ -8063,6 +8066,7 @@
       "src/core/lib/gpr/tmpfile.h", 
       "src/core/lib/gpr/tmpfile.h", 
       "src/core/lib/gpr/useful.h", 
       "src/core/lib/gpr/useful.h", 
       "src/core/lib/gprpp/abstract.h", 
       "src/core/lib/gprpp/abstract.h", 
+      "src/core/lib/gprpp/arena.h", 
       "src/core/lib/gprpp/atomic.h", 
       "src/core/lib/gprpp/atomic.h", 
       "src/core/lib/gprpp/fork.h", 
       "src/core/lib/gprpp/fork.h", 
       "src/core/lib/gprpp/manual_constructor.h", 
       "src/core/lib/gprpp/manual_constructor.h", 
@@ -8111,6 +8115,7 @@
       "src/core/lib/gpr/tmpfile.h", 
       "src/core/lib/gpr/tmpfile.h", 
       "src/core/lib/gpr/useful.h", 
       "src/core/lib/gpr/useful.h", 
       "src/core/lib/gprpp/abstract.h", 
       "src/core/lib/gprpp/abstract.h", 
+      "src/core/lib/gprpp/arena.h", 
       "src/core/lib/gprpp/atomic.h", 
       "src/core/lib/gprpp/atomic.h", 
       "src/core/lib/gprpp/fork.h", 
       "src/core/lib/gprpp/fork.h", 
       "src/core/lib/gprpp/manual_constructor.h", 
       "src/core/lib/gprpp/manual_constructor.h", 
@@ -8232,12 +8237,15 @@
       "src/core/lib/http/parser.cc", 
       "src/core/lib/http/parser.cc", 
       "src/core/lib/iomgr/buffer_list.cc", 
       "src/core/lib/iomgr/buffer_list.cc", 
       "src/core/lib/iomgr/call_combiner.cc", 
       "src/core/lib/iomgr/call_combiner.cc", 
+      "src/core/lib/iomgr/cfstream_handle.cc", 
       "src/core/lib/iomgr/combiner.cc", 
       "src/core/lib/iomgr/combiner.cc", 
       "src/core/lib/iomgr/endpoint.cc", 
       "src/core/lib/iomgr/endpoint.cc", 
+      "src/core/lib/iomgr/endpoint_cfstream.cc", 
       "src/core/lib/iomgr/endpoint_pair_posix.cc", 
       "src/core/lib/iomgr/endpoint_pair_posix.cc", 
       "src/core/lib/iomgr/endpoint_pair_uv.cc", 
       "src/core/lib/iomgr/endpoint_pair_uv.cc", 
       "src/core/lib/iomgr/endpoint_pair_windows.cc", 
       "src/core/lib/iomgr/endpoint_pair_windows.cc", 
       "src/core/lib/iomgr/error.cc", 
       "src/core/lib/iomgr/error.cc", 
+      "src/core/lib/iomgr/error_cfstream.cc", 
       "src/core/lib/iomgr/ev_epoll1_linux.cc", 
       "src/core/lib/iomgr/ev_epoll1_linux.cc", 
       "src/core/lib/iomgr/ev_epollex_linux.cc", 
       "src/core/lib/iomgr/ev_epollex_linux.cc", 
       "src/core/lib/iomgr/ev_poll_posix.cc", 
       "src/core/lib/iomgr/ev_poll_posix.cc", 
@@ -8258,6 +8266,7 @@
       "src/core/lib/iomgr/iomgr_custom.cc", 
       "src/core/lib/iomgr/iomgr_custom.cc", 
       "src/core/lib/iomgr/iomgr_internal.cc", 
       "src/core/lib/iomgr/iomgr_internal.cc", 
       "src/core/lib/iomgr/iomgr_posix.cc", 
       "src/core/lib/iomgr/iomgr_posix.cc", 
+      "src/core/lib/iomgr/iomgr_posix_cfstream.cc", 
       "src/core/lib/iomgr/iomgr_uv.cc", 
       "src/core/lib/iomgr/iomgr_uv.cc", 
       "src/core/lib/iomgr/iomgr_windows.cc", 
       "src/core/lib/iomgr/iomgr_windows.cc", 
       "src/core/lib/iomgr/is_epollexclusive_available.cc", 
       "src/core/lib/iomgr/is_epollexclusive_available.cc", 
@@ -8286,6 +8295,7 @@
       "src/core/lib/iomgr/socket_utils_windows.cc", 
       "src/core/lib/iomgr/socket_utils_windows.cc", 
       "src/core/lib/iomgr/socket_windows.cc", 
       "src/core/lib/iomgr/socket_windows.cc", 
       "src/core/lib/iomgr/tcp_client.cc", 
       "src/core/lib/iomgr/tcp_client.cc", 
+      "src/core/lib/iomgr/tcp_client_cfstream.cc", 
       "src/core/lib/iomgr/tcp_client_custom.cc", 
       "src/core/lib/iomgr/tcp_client_custom.cc", 
       "src/core/lib/iomgr/tcp_client_posix.cc", 
       "src/core/lib/iomgr/tcp_client_posix.cc", 
       "src/core/lib/iomgr/tcp_client_windows.cc", 
       "src/core/lib/iomgr/tcp_client_windows.cc", 
@@ -8414,12 +8424,15 @@
       "src/core/lib/iomgr/block_annotate.h", 
       "src/core/lib/iomgr/block_annotate.h", 
       "src/core/lib/iomgr/buffer_list.h", 
       "src/core/lib/iomgr/buffer_list.h", 
       "src/core/lib/iomgr/call_combiner.h", 
       "src/core/lib/iomgr/call_combiner.h", 
+      "src/core/lib/iomgr/cfstream_handle.h", 
       "src/core/lib/iomgr/closure.h", 
       "src/core/lib/iomgr/closure.h", 
       "src/core/lib/iomgr/combiner.h", 
       "src/core/lib/iomgr/combiner.h", 
       "src/core/lib/iomgr/dynamic_annotations.h", 
       "src/core/lib/iomgr/dynamic_annotations.h", 
       "src/core/lib/iomgr/endpoint.h", 
       "src/core/lib/iomgr/endpoint.h", 
+      "src/core/lib/iomgr/endpoint_cfstream.h", 
       "src/core/lib/iomgr/endpoint_pair.h", 
       "src/core/lib/iomgr/endpoint_pair.h", 
       "src/core/lib/iomgr/error.h", 
       "src/core/lib/iomgr/error.h", 
+      "src/core/lib/iomgr/error_cfstream.h", 
       "src/core/lib/iomgr/error_internal.h", 
       "src/core/lib/iomgr/error_internal.h", 
       "src/core/lib/iomgr/ev_epoll1_linux.h", 
       "src/core/lib/iomgr/ev_epoll1_linux.h", 
       "src/core/lib/iomgr/ev_epollex_linux.h", 
       "src/core/lib/iomgr/ev_epollex_linux.h", 
@@ -8567,12 +8580,15 @@
       "src/core/lib/iomgr/block_annotate.h", 
       "src/core/lib/iomgr/block_annotate.h", 
       "src/core/lib/iomgr/buffer_list.h", 
       "src/core/lib/iomgr/buffer_list.h", 
       "src/core/lib/iomgr/call_combiner.h", 
       "src/core/lib/iomgr/call_combiner.h", 
+      "src/core/lib/iomgr/cfstream_handle.h", 
       "src/core/lib/iomgr/closure.h", 
       "src/core/lib/iomgr/closure.h", 
       "src/core/lib/iomgr/combiner.h", 
       "src/core/lib/iomgr/combiner.h", 
       "src/core/lib/iomgr/dynamic_annotations.h", 
       "src/core/lib/iomgr/dynamic_annotations.h", 
       "src/core/lib/iomgr/endpoint.h", 
       "src/core/lib/iomgr/endpoint.h", 
+      "src/core/lib/iomgr/endpoint_cfstream.h", 
       "src/core/lib/iomgr/endpoint_pair.h", 
       "src/core/lib/iomgr/endpoint_pair.h", 
       "src/core/lib/iomgr/error.h", 
       "src/core/lib/iomgr/error.h", 
+      "src/core/lib/iomgr/error_cfstream.h", 
       "src/core/lib/iomgr/error_internal.h", 
       "src/core/lib/iomgr/error_internal.h", 
       "src/core/lib/iomgr/ev_epoll1_linux.h", 
       "src/core/lib/iomgr/ev_epoll1_linux.h", 
       "src/core/lib/iomgr/ev_epollex_linux.h", 
       "src/core/lib/iomgr/ev_epollex_linux.h", 
@@ -8672,33 +8688,6 @@
     "third_party": false, 
     "third_party": false, 
     "type": "filegroup"
     "type": "filegroup"
   }, 
   }, 
-  {
-    "deps": [
-      "gpr", 
-      "gpr_base_headers", 
-      "grpc_base_headers"
-    ], 
-    "headers": [
-      "src/core/lib/iomgr/cfstream_handle.h", 
-      "src/core/lib/iomgr/endpoint_cfstream.h", 
-      "src/core/lib/iomgr/error_cfstream.h"
-    ], 
-    "is_filegroup": true, 
-    "language": "c", 
-    "name": "grpc_cfstream", 
-    "src": [
-      "src/core/lib/iomgr/cfstream_handle.cc", 
-      "src/core/lib/iomgr/cfstream_handle.h", 
-      "src/core/lib/iomgr/endpoint_cfstream.cc", 
-      "src/core/lib/iomgr/endpoint_cfstream.h", 
-      "src/core/lib/iomgr/error_cfstream.cc", 
-      "src/core/lib/iomgr/error_cfstream.h", 
-      "src/core/lib/iomgr/iomgr_posix_cfstream.cc", 
-      "src/core/lib/iomgr/tcp_client_cfstream.cc"
-    ], 
-    "third_party": false, 
-    "type": "filegroup"
-  }, 
   {
   {
     "deps": [
     "deps": [
       "gpr", 
       "gpr",