aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/csharp_generator.cc16
-rw-r--r--src/core/ext/filters/client_channel/client_channel.cc591
-rw-r--r--src/core/ext/filters/client_channel/http_connect_handshaker.cc9
-rw-r--r--src/core/ext/filters/client_channel/http_proxy.cc11
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc38
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc7
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc8
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc8
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_factory.cc7
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc17
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h14
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc148
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc155
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h4
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc11
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc7
-rw-r--r--src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc15
-rw-r--r--src/core/ext/filters/client_channel/subchannel.cc5
-rw-r--r--src/core/ext/filters/deadline/deadline_filter.cc9
-rw-r--r--src/core/ext/filters/http/client/http_client_filter.cc74
-rw-r--r--src/core/ext/filters/http/http_filters_plugin.cc4
-rw-r--r--src/core/ext/filters/load_reporting/server_load_reporting_filter.cc4
-rw-r--r--src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc3
-rw-r--r--src/core/ext/filters/max_age/max_age_filter.cc13
-rw-r--r--src/core/ext/filters/message_size/message_size_filter.cc5
-rw-r--r--src/core/ext/transport/chttp2/client/authority.cc5
-rw-r--r--src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc2
-rw-r--r--src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc5
-rw-r--r--src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc5
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.cc29
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_encoder.cc16
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_encoder.h7
-rw-r--r--src/core/ext/transport/cronet/transport/cronet_transport.cc16
-rw-r--r--src/core/ext/transport/inproc/inproc_transport.cc7
-rw-r--r--src/core/lib/channel/channel_args.h37
-rw-r--r--src/core/lib/channel/handshaker.cc29
-rw-r--r--src/core/lib/iomgr/cfstream_handle.cc185
-rw-r--r--src/core/lib/iomgr/cfstream_handle.h80
-rw-r--r--src/core/lib/iomgr/endpoint_cfstream.cc372
-rw-r--r--src/core/lib/iomgr/endpoint_cfstream.h49
-rw-r--r--src/core/lib/iomgr/endpoint_pair_posix.cc4
-rw-r--r--src/core/lib/iomgr/error.cc12
-rw-r--r--src/core/lib/iomgr/error.h5
-rw-r--r--src/core/lib/iomgr/error_cfstream.cc52
-rw-r--r--src/core/lib/iomgr/error_cfstream.h31
-rw-r--r--src/core/lib/iomgr/ev_epoll1_linux.cc49
-rw-r--r--src/core/lib/iomgr/ev_epollex_linux.cc121
-rw-r--r--src/core/lib/iomgr/ev_epollsig_linux.cc70
-rw-r--r--src/core/lib/iomgr/ev_poll_posix.cc18
-rw-r--r--src/core/lib/iomgr/ev_posix.cc30
-rw-r--r--src/core/lib/iomgr/ev_posix.h24
-rw-r--r--src/core/lib/iomgr/iomgr_posix.cc4
-rw-r--r--src/core/lib/iomgr/polling_entity.cc13
-rw-r--r--src/core/lib/iomgr/port.h39
-rw-r--r--src/core/lib/iomgr/resolve_address.h2
-rw-r--r--src/core/lib/iomgr/resolve_address_posix.cc2
-rw-r--r--src/core/lib/iomgr/resource_quota.cc16
-rw-r--r--src/core/lib/iomgr/sockaddr_posix.h2
-rw-r--r--src/core/lib/iomgr/socket_factory_posix.cc2
-rw-r--r--src/core/lib/iomgr/socket_utils_common_posix.cc2
-rw-r--r--src/core/lib/iomgr/tcp_client_cfstream.cc216
-rw-r--r--src/core/lib/iomgr/tcp_client_custom.cc6
-rw-r--r--src/core/lib/iomgr/tcp_client_posix.cc26
-rw-r--r--src/core/lib/iomgr/tcp_posix.cc26
-rw-r--r--src/core/lib/iomgr/tcp_server_custom.cc19
-rw-r--r--src/core/lib/iomgr/tcp_server_posix.cc29
-rw-r--r--src/core/lib/iomgr/tcp_server_utils_posix_common.cc24
-rw-r--r--src/core/lib/iomgr/udp_server.cc15
-rw-r--r--src/core/lib/security/context/security_context.cc21
-rw-r--r--src/core/lib/security/context/security_context.h1
-rw-r--r--src/core/lib/security/credentials/credentials.cc45
-rw-r--r--src/core/lib/security/credentials/credentials.h5
-rw-r--r--src/core/lib/security/credentials/fake/fake_credentials.cc5
-rw-r--r--src/core/lib/security/credentials/google_default/google_default_credentials.cc11
-rw-r--r--src/core/lib/security/credentials/oauth2/oauth2_credentials.cc16
-rw-r--r--src/core/lib/security/credentials/oauth2/oauth2_credentials.h2
-rw-r--r--src/core/lib/security/credentials/ssl/ssl_credentials.cc10
-rw-r--r--src/core/lib/security/security_connector/security_connector.cc22
-rw-r--r--src/core/lib/security/security_connector/security_connector.h3
-rw-r--r--src/core/lib/security/transport/target_authority_table.cc13
-rw-r--r--src/core/lib/security/util/json_util.cc4
-rw-r--r--src/core/lib/slice/slice_buffer.cc18
-rw-r--r--src/core/lib/surface/call.cc1
-rw-r--r--src/core/lib/transport/transport.cc3
-rw-r--r--src/core/lib/transport/transport.h12
-rw-r--r--src/core/tsi/ssl_transport_security.cc5
-rw-r--r--src/cpp/server/server_builder.cc8
-rw-r--r--src/csharp/Grpc.Core.NativeDebug.nuspec25
-rw-r--r--src/csharp/Grpc.Core.Testing/TestCalls.cs2
-rwxr-xr-xsrc/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj2
-rw-r--r--src/csharp/Grpc.Examples.Tests/MathClientMockableTest.cs101
-rw-r--r--src/csharp/Grpc.Examples.Tests/MathServiceImplTestabilityTest.cs47
-rw-r--r--src/csharp/Grpc.Examples/MathGrpc.cs24
-rw-r--r--src/csharp/Grpc.HealthCheck/HealthGrpc.cs8
-rw-r--r--src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs24
-rw-r--r--src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs23
-rwxr-xr-xsrc/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj1
-rw-r--r--src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs14
-rw-r--r--src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs8
-rw-r--r--src/csharp/Grpc.IntegrationTesting/TestGrpc.cs66
-rw-r--r--src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs30
-rw-r--r--src/csharp/Grpc.Reflection/ReflectionGrpc.cs8
-rwxr-xr-xsrc/csharp/build_packages_dotnetcli.bat1
-rwxr-xr-xsrc/csharp/build_packages_dotnetcli.sh1
-rw-r--r--src/csharp/tests.json4
-rw-r--r--src/objective-c/BoringSSL.podspec5
-rw-r--r--src/objective-c/GRPCClient/GRPCCall+MobileLog.h30
-rw-r--r--src/objective-c/GRPCClient/GRPCCall+MobileLog.m33
-rw-r--r--src/objective-c/GRPCClient/GRPCCall.m5
-rw-r--r--src/objective-c/GRPCClient/private/GRPCCompletionQueue.m11
-rw-r--r--src/objective-c/GRPCClient/private/GRPCHost.h1
-rw-r--r--src/objective-c/GRPCClient/private/GRPCHost.m30
-rw-r--r--src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj2
-rw-r--r--src/objective-c/examples/Sample/Sample.xcodeproj/xcshareddata/xcschemes/Sample.xcscheme2
-rw-r--r--src/objective-c/tests/Connectivity/ConnectivityTestingApp.xcodeproj/project.pbxproj17
-rw-r--r--src/objective-c/tests/Connectivity/ConnectivityTestingApp/ViewController.m2
-rw-r--r--src/objective-c/tests/Connectivity/Podfile6
-rw-r--r--src/objective-c/tests/GRPCClientTests.m3
-rw-r--r--src/objective-c/tests/Podfile31
-rw-r--r--src/objective-c/tests/Tests.xcodeproj/project.pbxproj773
-rw-r--r--src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme2
-rw-r--r--src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme2
-rw-r--r--src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartextCFStream.xcscheme63
-rw-r--r--src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSLCFStream.xcscheme63
-rw-r--r--src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme2
-rw-r--r--src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteCFStream.xcscheme61
-rwxr-xr-xsrc/objective-c/tests/analyze_link_map.py78
-rwxr-xr-xsrc/objective-c/tests/build_one_example.sh5
-rwxr-xr-xsrc/objective-c/tests/run_tests.sh41
-rw-r--r--src/php/README.md196
-rw-r--r--src/proto/grpc/testing/messages.proto4
-rw-r--r--src/python/grpcio/grpc/__init__.py37
-rw-r--r--src/python/grpcio/grpc/_channel.py11
-rw-r--r--src/python/grpcio/grpc/_common.py6
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi2
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi3
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi2
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi5
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi32
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi9
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi (renamed from src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd)0
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi (renamed from src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx)5
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi3
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi1
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi1
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi6
-rw-r--r--src/python/grpcio/grpc/_cython/cygrpc.pxd2
-rw-r--r--src/python/grpcio/grpc/_cython/cygrpc.pyx2
-rw-r--r--src/python/grpcio/grpc/_interceptor.py17
-rw-r--r--src/python/grpcio/grpc/_plugin_wrapping.py4
-rw-r--r--src/python/grpcio/grpc/_server.py31
-rw-r--r--src/python/grpcio/grpc/_utilities.py2
-rw-r--r--src/python/grpcio/grpc/beta/_server_adaptations.py1
-rw-r--r--src/python/grpcio/grpc/beta/utilities.py2
-rw-r--r--src/python/grpcio/grpc/experimental/session_cache.py45
-rw-r--r--src/python/grpcio/grpc/framework/foundation/callable_util.py4
-rw-r--r--src/python/grpcio/grpc/framework/foundation/logging_pool.py4
-rw-r--r--src/python/grpcio/grpc/framework/foundation/stream_util.py11
-rw-r--r--src/python/grpcio_testing/grpc_testing/__init__.py2
-rw-r--r--src/python/grpcio_testing/grpc_testing/_channel/_invocation.py3
-rw-r--r--src/python/grpcio_testing/grpc_testing/_server/_handler.py4
-rw-r--r--src/python/grpcio_testing/grpc_testing/_server/_rpc.py6
-rw-r--r--src/python/grpcio_testing/grpc_testing/_time.py4
-rw-r--r--src/python/grpcio_tests/commands.py2
-rw-r--r--src/python/grpcio_tests/tests/_loader.py11
-rw-r--r--src/python/grpcio_tests/tests/_result.py41
-rw-r--r--src/python/grpcio_tests/tests/interop/methods.py4
-rw-r--r--src/python/grpcio_tests/tests/interop/server.py7
-rw-r--r--src/python/grpcio_tests/tests/tests.json2
-rw-r--r--src/python/grpcio_tests/tests/unit/_auth_context_test.py45
-rw-r--r--src/python/grpcio_tests/tests/unit/_junkdrawer/__init__.py13
-rw-r--r--src/python/grpcio_tests/tests/unit/_junkdrawer/stock_pb2.py164
-rw-r--r--src/python/grpcio_tests/tests/unit/_server_test.py52
-rw-r--r--src/python/grpcio_tests/tests/unit/_session_cache_test.py145
-rw-r--r--src/ruby/bin/apis/google/protobuf/empty.rb29
-rwxr-xr-xsrc/ruby/bin/apis/pubsub_demo.rb241
-rw-r--r--src/ruby/bin/apis/tech/pubsub/proto/pubsub.rb159
-rw-r--r--src/ruby/bin/apis/tech/pubsub/proto/pubsub_services.rb88
178 files changed, 3942 insertions, 2276 deletions
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index 14173e0794..a923ce8e38 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -202,7 +202,8 @@ std::string GetCSharpMethodType(MethodType method_type) {
std::string GetServiceNameFieldName() { return "__ServiceName"; }
std::string GetMarshallerFieldName(const Descriptor* message) {
- return "__Marshaller_" + message->name();
+ return "__Marshaller_" +
+ grpc_generator::StringReplace(message->full_name(), ".", "_", true);
}
std::string GetMethodFieldName(const MethodDescriptor* method) {
@@ -680,14 +681,19 @@ grpc::string GetServices(const FileDescriptor* file, bool generate_client,
out.Print("using grpc = global::Grpc.Core;\n");
out.Print("\n");
- out.Print("namespace $namespace$ {\n", "namespace", GetFileNamespace(file));
- out.Indent();
+ grpc::string file_namespace = GetFileNamespace(file);
+ if (file_namespace != "") {
+ out.Print("namespace $namespace$ {\n", "namespace", file_namespace);
+ out.Indent();
+ }
for (int i = 0; i < file->service_count(); i++) {
GenerateService(&out, file->service(i), generate_client, generate_server,
internal_access);
}
- out.Outdent();
- out.Print("}\n");
+ if (file_namespace != "") {
+ out.Outdent();
+ out.Print("}\n");
+ }
out.Print("#endregion\n");
}
return output;
diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc
index 936d70b959..f141aabe70 100644
--- a/src/core/ext/filters/client_channel/client_channel.cc
+++ b/src/core/ext/filters/client_channel/client_channel.cc
@@ -327,16 +327,14 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
if (chand->resolver_result != nullptr) {
if (chand->resolver != nullptr) {
// Find LB policy name.
- const grpc_arg* channel_arg = grpc_channel_args_find(
+ const char* lb_policy_name = grpc_channel_args_get_string(
chand->resolver_result, GRPC_ARG_LB_POLICY_NAME);
- const char* lb_policy_name = grpc_channel_arg_get_string(channel_arg);
// Special case: If at least one balancer address is present, we use
// the grpclb policy, regardless of what the resolver actually specified.
- channel_arg =
- grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES);
- if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) {
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(channel_arg->value.pointer.p);
+ grpc_lb_addresses* addresses =
+ grpc_channel_args_get_pointer<grpc_lb_addresses>(
+ chand->resolver_result, GRPC_ARG_LB_ADDRESSES);
+ if (addresses != nullptr) {
bool found_balancer_address = false;
for (size_t i = 0; i < addresses->num_addresses; ++i) {
if (addresses->addresses[i].is_balancer) {
@@ -400,18 +398,15 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
// The copy will be saved in chand->lb_policy_name below.
lb_policy_name_dup = gpr_strdup(lb_policy_name);
// Find service config.
- channel_arg = grpc_channel_args_find(chand->resolver_result,
- GRPC_ARG_SERVICE_CONFIG);
- service_config_json =
- gpr_strdup(grpc_channel_arg_get_string(channel_arg));
+ service_config_json = gpr_strdup(grpc_channel_args_get_string(
+ chand->resolver_result, GRPC_ARG_SERVICE_CONFIG));
if (service_config_json != nullptr) {
grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config =
grpc_core::ServiceConfig::Create(service_config_json);
if (service_config != nullptr) {
if (chand->enable_retries) {
- channel_arg = grpc_channel_args_find(chand->resolver_result,
- GRPC_ARG_SERVER_URI);
- const char* server_uri = grpc_channel_arg_get_string(channel_arg);
+ const char* server_uri = grpc_channel_args_get_string(
+ chand->resolver_result, GRPC_ARG_SERVER_URI);
GPR_ASSERT(server_uri != nullptr);
grpc_uri* uri = grpc_uri_parse(server_uri, true);
GPR_ASSERT(uri->path[0] != '\0');
@@ -648,45 +643,37 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem,
"client_channel");
grpc_client_channel_start_backup_polling(chand->interested_parties);
// Record max per-RPC retry buffer size.
- const grpc_arg* arg = grpc_channel_args_find(
- args->channel_args, GRPC_ARG_PER_RPC_RETRY_BUFFER_SIZE);
- chand->per_rpc_retry_buffer_size = (size_t)grpc_channel_arg_get_integer(
- arg, {DEFAULT_PER_RPC_RETRY_BUFFER_SIZE, 0, INT_MAX});
+ chand->per_rpc_retry_buffer_size = (size_t)grpc_channel_args_get_integer(
+ args->channel_args, GRPC_ARG_PER_RPC_RETRY_BUFFER_SIZE,
+ {DEFAULT_PER_RPC_RETRY_BUFFER_SIZE, 0, INT_MAX});
// Record enable_retries.
- arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_ENABLE_RETRIES);
- chand->enable_retries = grpc_channel_arg_get_bool(arg, true);
+ chand->enable_retries = grpc_channel_args_get_bool(
+ args->channel_args, GRPC_ARG_ENABLE_RETRIES, true);
// Record client channel factory.
- arg = grpc_channel_args_find(args->channel_args,
- GRPC_ARG_CLIENT_CHANNEL_FACTORY);
- if (arg == nullptr) {
+ grpc_client_channel_factory* client_channel_factory =
+ grpc_channel_args_get_pointer<grpc_client_channel_factory>(
+ args->channel_args, GRPC_ARG_CLIENT_CHANNEL_FACTORY);
+ if (client_channel_factory == nullptr) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "Missing client channel factory in args for client channel filter");
+ "Missing or malformed client channel factory in args for client "
+ "channel filter");
}
- if (arg->type != GRPC_ARG_POINTER) {
- return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "client channel factory arg must be a pointer");
- }
- grpc_client_channel_factory_ref(
- static_cast<grpc_client_channel_factory*>(arg->value.pointer.p));
- chand->client_channel_factory =
- static_cast<grpc_client_channel_factory*>(arg->value.pointer.p);
+ grpc_client_channel_factory_ref(client_channel_factory);
+ chand->client_channel_factory = client_channel_factory;
// Get server name to resolve, using proxy mapper if needed.
- arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI);
- if (arg == nullptr) {
+ char* server_uri =
+ grpc_channel_args_get_string(args->channel_args, GRPC_ARG_SERVER_URI);
+ if (server_uri == nullptr) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "Missing server uri in args for client channel filter");
- }
- if (arg->type != GRPC_ARG_STRING) {
- return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "server uri arg must be a string");
+ "Missing or malformed server uri in args for client channel filter");
}
char* proxy_name = nullptr;
grpc_channel_args* new_args = nullptr;
- grpc_proxy_mappers_map_name(arg->value.string, args->channel_args,
- &proxy_name, &new_args);
+ grpc_proxy_mappers_map_name(server_uri, args->channel_args, &proxy_name,
+ &new_args);
// Instantiate resolver.
chand->resolver = grpc_core::ResolverRegistry::CreateResolver(
- proxy_name != nullptr ? proxy_name : arg->value.string,
+ proxy_name != nullptr ? proxy_name : server_uri,
new_args != nullptr ? new_args : args->channel_args,
chand->interested_parties, chand->combiner);
if (proxy_name != nullptr) gpr_free(proxy_name);
@@ -891,6 +878,7 @@ typedef struct client_channel_call_data {
grpc_closure pick_cancel_closure;
grpc_polling_entity* pollent;
+ bool pollent_added_to_interested_parties;
// Batches are added to this list when received from above.
// They are removed when we are done handling the batch (i.e., when
@@ -949,7 +937,6 @@ static void retry_commit(grpc_call_element* elem,
static void start_internal_recv_trailing_metadata(grpc_call_element* elem);
static void on_complete(void* arg, grpc_error* error);
static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored);
-static void pick_after_resolver_result_start_locked(grpc_call_element* elem);
static void start_pick_locked(void* arg, grpc_error* ignored);
//
@@ -2684,59 +2671,133 @@ static void pick_done(void* arg, grpc_error* error) {
}
}
+static void maybe_add_call_to_channel_interested_parties_locked(
+ grpc_call_element* elem) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ if (!calld->pollent_added_to_interested_parties) {
+ calld->pollent_added_to_interested_parties = true;
+ grpc_polling_entity_add_to_pollset_set(calld->pollent,
+ chand->interested_parties);
+ }
+}
+
+static void maybe_del_call_from_channel_interested_parties_locked(
+ grpc_call_element* elem) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ if (calld->pollent_added_to_interested_parties) {
+ calld->pollent_added_to_interested_parties = false;
+ grpc_polling_entity_del_from_pollset_set(calld->pollent,
+ chand->interested_parties);
+ }
+}
+
// Invoked when a pick is completed to leave the client_channel combiner
// and continue processing in the call combiner.
+// If needed, removes the call's polling entity from chand->interested_parties.
static void pick_done_locked(grpc_call_element* elem, grpc_error* error) {
call_data* calld = static_cast<call_data*>(elem->call_data);
+ maybe_del_call_from_channel_interested_parties_locked(elem);
GRPC_CLOSURE_INIT(&calld->pick_closure, pick_done, elem,
grpc_schedule_on_exec_ctx);
GRPC_CLOSURE_SCHED(&calld->pick_closure, error);
}
-// A wrapper around pick_done_locked() that is used in cases where
-// either (a) the pick was deferred pending a resolver result or (b) the
-// pick was done asynchronously. Removes the call's polling entity from
-// chand->interested_parties before invoking pick_done_locked().
-static void async_pick_done_locked(grpc_call_element* elem, grpc_error* error) {
- channel_data* chand = static_cast<channel_data*>(elem->channel_data);
- call_data* calld = static_cast<call_data*>(elem->call_data);
- grpc_polling_entity_del_from_pollset_set(calld->pollent,
- chand->interested_parties);
- pick_done_locked(elem, error);
-}
+namespace grpc_core {
-// Note: This runs under the client_channel combiner, but will NOT be
-// holding the call combiner.
-static void pick_callback_cancel_locked(void* arg, grpc_error* error) {
- grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
- channel_data* chand = static_cast<channel_data*>(elem->channel_data);
- call_data* calld = static_cast<call_data*>(elem->call_data);
- // Note: chand->lb_policy may have changed since we started our pick,
- // in which case we will be cancelling the pick on a policy other than
- // the one we started it on. However, this will just be a no-op.
- if (GPR_LIKELY(error != GRPC_ERROR_NONE && chand->lb_policy != nullptr)) {
+// Performs subchannel pick via LB policy.
+class LbPicker {
+ public:
+ // Starts a pick on chand->lb_policy.
+ static void StartLocked(grpc_call_element* elem) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_INFO, "chand=%p calld=%p: cancelling pick from LB policy %p",
+ gpr_log(GPR_INFO, "chand=%p calld=%p: starting pick on lb_policy=%p",
chand, calld, chand->lb_policy.get());
}
- chand->lb_policy->CancelPickLocked(&calld->pick, GRPC_ERROR_REF(error));
+ // If this is a retry, use the send_initial_metadata payload that
+ // we've cached; otherwise, use the pending batch. The
+ // send_initial_metadata batch will be the first pending batch in the
+ // list, as set by get_batch_index() above.
+ calld->pick.initial_metadata =
+ calld->seen_send_initial_metadata
+ ? &calld->send_initial_metadata
+ : calld->pending_batches[0]
+ .batch->payload->send_initial_metadata.send_initial_metadata;
+ calld->pick.initial_metadata_flags =
+ calld->seen_send_initial_metadata
+ ? calld->send_initial_metadata_flags
+ : calld->pending_batches[0]
+ .batch->payload->send_initial_metadata
+ .send_initial_metadata_flags;
+ GRPC_CLOSURE_INIT(&calld->pick_closure, &LbPicker::DoneLocked, elem,
+ grpc_combiner_scheduler(chand->combiner));
+ calld->pick.on_complete = &calld->pick_closure;
+ GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback");
+ const bool pick_done = chand->lb_policy->PickLocked(&calld->pick);
+ if (GPR_LIKELY(pick_done)) {
+ // Pick completed synchronously.
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO, "chand=%p calld=%p: pick completed synchronously",
+ chand, calld);
+ }
+ pick_done_locked(elem, GRPC_ERROR_NONE);
+ GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback");
+ } else {
+ // Pick will be returned asynchronously.
+ // Add the polling entity from call_data to the channel_data's
+ // interested_parties, so that the I/O of the LB policy can be done
+ // under it. It will be removed in pick_done_locked().
+ maybe_add_call_to_channel_interested_parties_locked(elem);
+ // Request notification on call cancellation.
+ GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback_cancel");
+ grpc_call_combiner_set_notify_on_cancel(
+ calld->call_combiner,
+ GRPC_CLOSURE_INIT(&calld->pick_cancel_closure,
+ &LbPicker::CancelLocked, elem,
+ grpc_combiner_scheduler(chand->combiner)));
+ }
}
- GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback_cancel");
-}
-// Callback invoked by LoadBalancingPolicy::PickLocked() for async picks.
-// Unrefs the LB policy and invokes async_pick_done_locked().
-static void pick_callback_done_locked(void* arg, grpc_error* error) {
- grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
- channel_data* chand = static_cast<channel_data*>(elem->channel_data);
- call_data* calld = static_cast<call_data*>(elem->call_data);
- if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_INFO, "chand=%p calld=%p: pick completed asynchronously", chand,
- calld);
+ private:
+ // Callback invoked by LoadBalancingPolicy::PickLocked() for async picks.
+ // Unrefs the LB policy and invokes pick_done_locked().
+ static void DoneLocked(void* arg, grpc_error* error) {
+ grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO, "chand=%p calld=%p: pick completed asynchronously",
+ chand, calld);
+ }
+ pick_done_locked(elem, GRPC_ERROR_REF(error));
+ GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback");
}
- async_pick_done_locked(elem, GRPC_ERROR_REF(error));
- GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback");
-}
+
+ // Note: This runs under the client_channel combiner, but will NOT be
+ // holding the call combiner.
+ static void CancelLocked(void* arg, grpc_error* error) {
+ grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ // Note: chand->lb_policy may have changed since we started our pick,
+ // in which case we will be cancelling the pick on a policy other than
+ // the one we started it on. However, this will just be a no-op.
+ if (GPR_UNLIKELY(error != GRPC_ERROR_NONE && chand->lb_policy != nullptr)) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "chand=%p calld=%p: cancelling pick from LB policy %p", chand,
+ calld, chand->lb_policy.get());
+ }
+ chand->lb_policy->CancelPickLocked(&calld->pick, GRPC_ERROR_REF(error));
+ }
+ GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback_cancel");
+ }
+};
+
+} // namespace grpc_core
// Applies service config to the call. Must be invoked once we know
// that the resolver has returned results to the channel.
@@ -2766,6 +2827,24 @@ static void apply_service_config_to_call_locked(grpc_call_element* elem) {
grpc_deadline_state_reset(elem, calld->deadline);
}
}
+ // If the service config set wait_for_ready and the application
+ // did not explicitly set it, use the value from the service config.
+ uint32_t* send_initial_metadata_flags =
+ &calld->pending_batches[0]
+ .batch->payload->send_initial_metadata
+ .send_initial_metadata_flags;
+ if (GPR_UNLIKELY(
+ calld->method_params->wait_for_ready() !=
+ ClientChannelMethodParams::WAIT_FOR_READY_UNSET &&
+ !(*send_initial_metadata_flags &
+ GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET))) {
+ if (calld->method_params->wait_for_ready() ==
+ ClientChannelMethodParams::WAIT_FOR_READY_TRUE) {
+ *send_initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY;
+ } else {
+ *send_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY;
+ }
+ }
}
}
// If no retry policy, disable retries.
@@ -2776,215 +2855,164 @@ static void apply_service_config_to_call_locked(grpc_call_element* elem) {
}
}
-// Starts a pick on chand->lb_policy.
-// Returns true if pick is completed synchronously.
-static bool pick_callback_start_locked(grpc_call_element* elem) {
- channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+// Invoked once resolver results are available.
+static void process_service_config_and_start_lb_pick_locked(
+ grpc_call_element* elem) {
call_data* calld = static_cast<call_data*>(elem->call_data);
- if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_INFO, "chand=%p calld=%p: starting pick on lb_policy=%p", chand,
- calld, chand->lb_policy.get());
- }
// Only get service config data on the first attempt.
if (GPR_LIKELY(calld->num_attempts_completed == 0)) {
apply_service_config_to_call_locked(elem);
}
- // If the application explicitly set wait_for_ready, use that.
- // Otherwise, if the service config specified a value for this
- // method, use that.
- //
- // The send_initial_metadata batch will be the first one in the list,
- // as set by get_batch_index() above.
- calld->pick.initial_metadata =
- calld->seen_send_initial_metadata
- ? &calld->send_initial_metadata
- : calld->pending_batches[0]
- .batch->payload->send_initial_metadata.send_initial_metadata;
- uint32_t send_initial_metadata_flags =
- calld->seen_send_initial_metadata
- ? calld->send_initial_metadata_flags
- : calld->pending_batches[0]
- .batch->payload->send_initial_metadata
- .send_initial_metadata_flags;
- const bool wait_for_ready_set_from_api =
- send_initial_metadata_flags &
- GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET;
- const bool wait_for_ready_set_from_service_config =
- calld->method_params != nullptr &&
- calld->method_params->wait_for_ready() !=
- ClientChannelMethodParams::WAIT_FOR_READY_UNSET;
- if (GPR_UNLIKELY(!wait_for_ready_set_from_api &&
- wait_for_ready_set_from_service_config)) {
- if (calld->method_params->wait_for_ready() ==
- ClientChannelMethodParams::WAIT_FOR_READY_TRUE) {
- send_initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY;
- } else {
- send_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY;
- }
- }
- calld->pick.initial_metadata_flags = send_initial_metadata_flags;
- GRPC_CLOSURE_INIT(&calld->pick_closure, pick_callback_done_locked, elem,
- grpc_combiner_scheduler(chand->combiner));
- calld->pick.on_complete = &calld->pick_closure;
- GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback");
- const bool pick_done = chand->lb_policy->PickLocked(&calld->pick);
- if (GPR_LIKELY(pick_done)) {
- // Pick completed synchronously.
- if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_INFO, "chand=%p calld=%p: pick completed synchronously",
- chand, calld);
- }
- GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback");
- } else {
- GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback_cancel");
- grpc_call_combiner_set_notify_on_cancel(
- calld->call_combiner,
- GRPC_CLOSURE_INIT(&calld->pick_cancel_closure,
- pick_callback_cancel_locked, elem,
- grpc_combiner_scheduler(chand->combiner)));
- }
- return pick_done;
+ // Start LB pick.
+ grpc_core::LbPicker::StartLocked(elem);
}
-typedef struct {
- grpc_call_element* elem;
- bool finished;
- grpc_closure closure;
- grpc_closure cancel_closure;
-} pick_after_resolver_result_args;
-
-// Note: This runs under the client_channel combiner, but will NOT be
-// holding the call combiner.
-static void pick_after_resolver_result_cancel_locked(void* arg,
- grpc_error* error) {
- pick_after_resolver_result_args* args =
- static_cast<pick_after_resolver_result_args*>(arg);
- if (GPR_LIKELY(args->finished)) {
- gpr_free(args);
- return;
- }
- // If we don't yet have a resolver result, then a closure for
- // pick_after_resolver_result_done_locked() will have been added to
- // chand->waiting_for_resolver_result_closures, and it may not be invoked
- // until after this call has been destroyed. We mark the operation as
- // finished, so that when pick_after_resolver_result_done_locked()
- // is called, it will be a no-op. We also immediately invoke
- // async_pick_done_locked() to propagate the error back to the caller.
- args->finished = true;
- grpc_call_element* elem = args->elem;
- channel_data* chand = static_cast<channel_data*>(elem->channel_data);
- call_data* calld = static_cast<call_data*>(elem->call_data);
- if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_INFO,
- "chand=%p calld=%p: cancelling pick waiting for resolver result",
- chand, calld);
- }
- // Note: Although we are not in the call combiner here, we are
- // basically stealing the call combiner from the pending pick, so
- // it's safe to call async_pick_done_locked() here -- we are
- // essentially calling it here instead of calling it in
- // pick_after_resolver_result_done_locked().
- async_pick_done_locked(elem, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
- "Pick cancelled", &error, 1));
-}
-
-static void pick_after_resolver_result_done_locked(void* arg,
- grpc_error* error) {
- pick_after_resolver_result_args* args =
- static_cast<pick_after_resolver_result_args*>(arg);
- if (GPR_UNLIKELY(args->finished)) {
- /* cancelled, do nothing */
- if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_INFO, "call cancelled before resolver result");
- }
- gpr_free(args);
- return;
- }
- args->finished = true;
- grpc_call_element* elem = args->elem;
- channel_data* chand = static_cast<channel_data*>(elem->channel_data);
- call_data* calld = static_cast<call_data*>(elem->call_data);
- if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) {
+namespace grpc_core {
+
+// Handles waiting for a resolver result.
+// Used only for the first call on an idle channel.
+class ResolverResultWaiter {
+ public:
+ explicit ResolverResultWaiter(grpc_call_element* elem) : elem_(elem) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_INFO, "chand=%p calld=%p: resolver failed to return data",
+ gpr_log(GPR_INFO,
+ "chand=%p calld=%p: deferring pick pending resolver result",
chand, calld);
}
- async_pick_done_locked(elem, GRPC_ERROR_REF(error));
- } else if (GPR_UNLIKELY(chand->resolver == nullptr)) {
- // Shutting down.
- if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_INFO, "chand=%p calld=%p: resolver disconnected", chand,
- calld);
+ // Add closure to be run when a resolver result is available.
+ GRPC_CLOSURE_INIT(&done_closure_, &ResolverResultWaiter::DoneLocked, this,
+ grpc_combiner_scheduler(chand->combiner));
+ AddToWaitingList();
+ // Set cancellation closure, so that we abort if the call is cancelled.
+ GRPC_CLOSURE_INIT(&cancel_closure_, &ResolverResultWaiter::CancelLocked,
+ this, grpc_combiner_scheduler(chand->combiner));
+ grpc_call_combiner_set_notify_on_cancel(calld->call_combiner,
+ &cancel_closure_);
+ }
+
+ private:
+ // Adds closure_ to chand->waiting_for_resolver_result_closures.
+ void AddToWaitingList() {
+ channel_data* chand = static_cast<channel_data*>(elem_->channel_data);
+ grpc_closure_list_append(&chand->waiting_for_resolver_result_closures,
+ &done_closure_, GRPC_ERROR_NONE);
+ }
+
+ // Invoked when a resolver result is available.
+ static void DoneLocked(void* arg, grpc_error* error) {
+ ResolverResultWaiter* self = static_cast<ResolverResultWaiter*>(arg);
+ // If CancelLocked() has already run, delete ourselves without doing
+ // anything. Note that the call stack may have already been destroyed,
+ // so it's not safe to access anything in elem_.
+ if (GPR_UNLIKELY(self->finished_)) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO, "call cancelled before resolver result");
+ }
+ Delete(self);
+ return;
}
- async_pick_done_locked(
- elem, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected"));
- } else if (GPR_UNLIKELY(chand->lb_policy == nullptr)) {
- // Transient resolver failure.
- // If call has wait_for_ready=true, try again; otherwise, fail.
- uint32_t send_initial_metadata_flags =
- calld->seen_send_initial_metadata
- ? calld->send_initial_metadata_flags
- : calld->pending_batches[0]
- .batch->payload->send_initial_metadata
- .send_initial_metadata_flags;
- if (send_initial_metadata_flags & GRPC_INITIAL_METADATA_WAIT_FOR_READY) {
+ // Otherwise, process the resolver result.
+ grpc_call_element* elem = self->elem_;
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_INFO,
- "chand=%p calld=%p: resolver returned but no LB policy; "
- "wait_for_ready=true; trying again",
+ gpr_log(GPR_INFO, "chand=%p calld=%p: resolver failed to return data",
chand, calld);
}
- pick_after_resolver_result_start_locked(elem);
+ pick_done_locked(elem, GRPC_ERROR_REF(error));
+ } else if (GPR_UNLIKELY(chand->resolver == nullptr)) {
+ // Shutting down.
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO, "chand=%p calld=%p: resolver disconnected", chand,
+ calld);
+ }
+ pick_done_locked(elem,
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected"));
+ } else if (GPR_UNLIKELY(chand->lb_policy == nullptr)) {
+ // Transient resolver failure.
+ // If call has wait_for_ready=true, try again; otherwise, fail.
+ uint32_t send_initial_metadata_flags =
+ calld->seen_send_initial_metadata
+ ? calld->send_initial_metadata_flags
+ : calld->pending_batches[0]
+ .batch->payload->send_initial_metadata
+ .send_initial_metadata_flags;
+ if (send_initial_metadata_flags & GRPC_INITIAL_METADATA_WAIT_FOR_READY) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "chand=%p calld=%p: resolver returned but no LB policy; "
+ "wait_for_ready=true; trying again",
+ chand, calld);
+ }
+ // Re-add ourselves to the waiting list.
+ self->AddToWaitingList();
+ // Return early so that we don't set finished_ to true below.
+ return;
+ } else {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "chand=%p calld=%p: resolver returned but no LB policy; "
+ "wait_for_ready=false; failing",
+ chand, calld);
+ }
+ pick_done_locked(
+ elem,
+ grpc_error_set_int(
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Name resolution failure"),
+ GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE));
+ }
} else {
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_INFO,
- "chand=%p calld=%p: resolver returned but no LB policy; "
- "wait_for_ready=false; failing",
+ gpr_log(GPR_INFO, "chand=%p calld=%p: resolver returned, doing LB pick",
chand, calld);
}
- async_pick_done_locked(
- elem,
- grpc_error_set_int(
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Name resolution failure"),
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE));
+ process_service_config_and_start_lb_pick_locked(elem);
}
- } else {
- if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_INFO, "chand=%p calld=%p: resolver returned, doing pick",
- chand, calld);
+ self->finished_ = true;
+ }
+
+ // Invoked when the call is cancelled.
+ // Note: This runs under the client_channel combiner, but will NOT be
+ // holding the call combiner.
+ static void CancelLocked(void* arg, grpc_error* error) {
+ ResolverResultWaiter* self = static_cast<ResolverResultWaiter*>(arg);
+ // If DoneLocked() has already run, delete ourselves without doing anything.
+ if (GPR_LIKELY(self->finished_)) {
+ Delete(self);
+ return;
}
- if (GPR_LIKELY(pick_callback_start_locked(elem))) {
- // Even if the LB policy returns a result synchronously, we have
- // already added our polling entity to chand->interested_parties
- // in order to wait for the resolver result, so we need to
- // remove it here. Therefore, we call async_pick_done_locked()
- // instead of pick_done_locked().
- async_pick_done_locked(elem, GRPC_ERROR_NONE);
+ // If we are being cancelled, immediately invoke pick_done_locked()
+ // to propagate the error back to the caller.
+ if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) {
+ grpc_call_element* elem = self->elem_;
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "chand=%p calld=%p: cancelling call waiting for name "
+ "resolution",
+ chand, calld);
+ }
+ // Note: Although we are not in the call combiner here, we are
+ // basically stealing the call combiner from the pending pick, so
+ // it's safe to call pick_done_locked() here -- we are essentially
+ // calling it here instead of calling it in DoneLocked().
+ pick_done_locked(elem, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+ "Pick cancelled", &error, 1));
}
+ self->finished_ = true;
}
-}
-static void pick_after_resolver_result_start_locked(grpc_call_element* elem) {
- channel_data* chand = static_cast<channel_data*>(elem->channel_data);
- call_data* calld = static_cast<call_data*>(elem->call_data);
- if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_INFO,
- "chand=%p calld=%p: deferring pick pending resolver result", chand,
- calld);
- }
- pick_after_resolver_result_args* args =
- static_cast<pick_after_resolver_result_args*>(gpr_zalloc(sizeof(*args)));
- args->elem = elem;
- GRPC_CLOSURE_INIT(&args->closure, pick_after_resolver_result_done_locked,
- args, grpc_combiner_scheduler(chand->combiner));
- grpc_closure_list_append(&chand->waiting_for_resolver_result_closures,
- &args->closure, GRPC_ERROR_NONE);
- grpc_call_combiner_set_notify_on_cancel(
- calld->call_combiner,
- GRPC_CLOSURE_INIT(&args->cancel_closure,
- pick_after_resolver_result_cancel_locked, args,
- grpc_combiner_scheduler(chand->combiner)));
-}
+ grpc_call_element* elem_;
+ grpc_closure done_closure_;
+ grpc_closure cancel_closure_;
+ bool finished_ = false;
+};
+
+} // namespace grpc_core
static void start_pick_locked(void* arg, grpc_error* ignored) {
grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
@@ -2993,31 +3021,24 @@ static void start_pick_locked(void* arg, grpc_error* ignored) {
GPR_ASSERT(calld->pick.connected_subchannel == nullptr);
GPR_ASSERT(calld->subchannel_call == nullptr);
if (GPR_LIKELY(chand->lb_policy != nullptr)) {
- // We already have an LB policy, so ask it for a pick.
- if (GPR_LIKELY(pick_callback_start_locked(elem))) {
- // Pick completed synchronously.
- pick_done_locked(elem, GRPC_ERROR_NONE);
- return;
- }
+ // We already have resolver results, so process the service config
+ // and start an LB pick.
+ process_service_config_and_start_lb_pick_locked(elem);
+ } else if (GPR_UNLIKELY(chand->resolver == nullptr)) {
+ pick_done_locked(elem,
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected"));
} else {
// We do not yet have an LB policy, so wait for a resolver result.
- if (GPR_UNLIKELY(chand->resolver == nullptr)) {
- pick_done_locked(elem,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected"));
- return;
- }
if (GPR_UNLIKELY(!chand->started_resolving)) {
start_resolving_locked(chand);
}
- pick_after_resolver_result_start_locked(elem);
+ // Create a new waiter, which will delete itself when done.
+ grpc_core::New<grpc_core::ResolverResultWaiter>(elem);
+ // Add the polling entity from call_data to the channel_data's
+ // interested_parties, so that the I/O of the resolver can be done
+ // under it. It will be removed in pick_done_locked().
+ maybe_add_call_to_channel_interested_parties_locked(elem);
}
- // We need to wait for either a resolver result or for an async result
- // from the LB policy. Add the polling entity from call_data to the
- // channel_data's interested_parties, so that the I/O of the LB policy
- // and resolver can be done under it. The polling entity will be
- // removed in async_pick_done_locked().
- grpc_polling_entity_add_to_pollset_set(calld->pollent,
- chand->interested_parties);
}
//
diff --git a/src/core/ext/filters/client_channel/http_connect_handshaker.cc b/src/core/ext/filters/client_channel/http_connect_handshaker.cc
index 4e8b8b71db..58f059829c 100644
--- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc
+++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc
@@ -254,9 +254,8 @@ static void http_connect_handshaker_do_handshake(
reinterpret_cast<http_connect_handshaker*>(handshaker_in);
// Check for HTTP CONNECT channel arg.
// If not found, invoke on_handshake_done without doing anything.
- const grpc_arg* arg =
- grpc_channel_args_find(args->args, GRPC_ARG_HTTP_CONNECT_SERVER);
- char* server_name = grpc_channel_arg_get_string(arg);
+ char* server_name =
+ grpc_channel_args_get_string(args->args, GRPC_ARG_HTTP_CONNECT_SERVER);
if (server_name == nullptr) {
// Set shutdown to true so that subsequent calls to
// http_connect_handshaker_shutdown() do nothing.
@@ -267,8 +266,8 @@ static void http_connect_handshaker_do_handshake(
return;
}
// Get headers from channel args.
- arg = grpc_channel_args_find(args->args, GRPC_ARG_HTTP_CONNECT_HEADERS);
- char* arg_header_string = grpc_channel_arg_get_string(arg);
+ char* arg_header_string =
+ grpc_channel_args_get_string(args->args, GRPC_ARG_HTTP_CONNECT_HEADERS);
grpc_http_header* headers = nullptr;
size_t num_headers = 0;
char** header_strings = nullptr;
diff --git a/src/core/ext/filters/client_channel/http_proxy.cc b/src/core/ext/filters/client_channel/http_proxy.cc
index 29a6c0e367..e21de35a7d 100644
--- a/src/core/ext/filters/client_channel/http_proxy.cc
+++ b/src/core/ext/filters/client_channel/http_proxy.cc
@@ -83,11 +83,22 @@ done:
return proxy_name;
}
+/**
+ * Checks the value of GRPC_ARG_ENABLE_HTTP_PROXY to determine if http_proxy
+ * should be used.
+ */
+bool http_proxy_enabled(const grpc_channel_args* args) {
+ return grpc_channel_args_get_bool(args, GRPC_ARG_ENABLE_HTTP_PROXY, true);
+}
+
static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper,
const char* server_uri,
const grpc_channel_args* args,
char** name_to_resolve,
grpc_channel_args** new_args) {
+ if (!http_proxy_enabled(args)) {
+ return false;
+ }
char* user_cred = nullptr;
*name_to_resolve = get_http_proxy_server(&user_cred);
if (*name_to_resolve == nullptr) return false;
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
index 263b51ae89..0ee4958f3d 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
@@ -1045,8 +1045,8 @@ GrpcLb::GrpcLb(const grpc_lb_addresses* addresses,
grpc_combiner_scheduler(args.combiner));
grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "grpclb");
// Record server name.
- const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI);
- const char* server_uri = grpc_channel_arg_get_string(arg);
+ const char* server_uri =
+ grpc_channel_args_get_string(args.args, GRPC_ARG_SERVER_URI);
GPR_ASSERT(server_uri != nullptr);
grpc_uri* uri = grpc_uri_parse(server_uri, true);
GPR_ASSERT(uri->path[0] != '\0');
@@ -1058,12 +1058,12 @@ GrpcLb::GrpcLb(const grpc_lb_addresses* addresses,
}
grpc_uri_destroy(uri);
// Record LB call timeout.
- arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS);
- lb_call_timeout_ms_ = grpc_channel_arg_get_integer(arg, {0, 0, INT_MAX});
+ lb_call_timeout_ms_ = grpc_channel_args_get_integer(
+ args.args, GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS, {0, 0, INT_MAX});
// Record fallback timeout.
- arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS);
- lb_fallback_timeout_ms_ = grpc_channel_arg_get_integer(
- arg, {GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX});
+ lb_fallback_timeout_ms_ = grpc_channel_args_get_integer(
+ args.args, GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS,
+ {GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX});
// Process channel args.
ProcessChannelArgsLocked(*args.args);
}
@@ -1284,8 +1284,10 @@ void GrpcLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
}
void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
- const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
- if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) {
+ const grpc_lb_addresses* addresses =
+ grpc_channel_args_get_pointer<grpc_lb_addresses>(&args,
+ GRPC_ARG_LB_ADDRESSES);
+ if (GPR_UNLIKELY(addresses == nullptr)) {
// Ignore this update.
gpr_log(
GPR_ERROR,
@@ -1293,8 +1295,6 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
this);
return;
}
- const grpc_lb_addresses* addresses =
- static_cast<const grpc_lb_addresses*>(arg->value.pointer.p);
// Update fallback address list.
if (fallback_backend_addresses_ != nullptr) {
grpc_lb_addresses_destroy(fallback_backend_addresses_);
@@ -1860,13 +1860,12 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory {
OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
const LoadBalancingPolicy::Args& args) const override {
/* Count the number of gRPC-LB addresses. There must be at least one. */
- const grpc_arg* arg =
- grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES);
- if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
+ grpc_lb_addresses* addresses =
+ grpc_channel_args_get_pointer<grpc_lb_addresses>(args.args,
+ GRPC_ARG_LB_ADDRESSES);
+ if (addresses == nullptr) {
return nullptr;
}
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
size_t num_grpclb_addrs = 0;
for (size_t i = 0; i < addresses->num_addresses; ++i) {
if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
@@ -1893,10 +1892,9 @@ bool maybe_add_client_load_reporting_filter(grpc_channel_stack_builder* builder,
void* arg) {
const grpc_channel_args* args =
grpc_channel_stack_builder_get_channel_arguments(builder);
- const grpc_arg* channel_arg =
- grpc_channel_args_find(args, GRPC_ARG_LB_POLICY_NAME);
- if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_STRING &&
- strcmp(channel_arg->value.string, "grpclb") == 0) {
+ const char* lb_policy =
+ grpc_channel_args_get_string(args, GRPC_ARG_LB_POLICY_NAME);
+ if (lb_policy != nullptr && strcmp(lb_policy, "grpclb") == 0) {
return grpc_channel_stack_builder_append_filter(
builder, (const grpc_channel_filter*)arg, nullptr, nullptr);
}
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
index 441efd5e23..972bdd40d5 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
@@ -72,11 +72,10 @@ grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args(
grpc_arg args_to_add[2];
size_t num_args_to_add = 0;
// Add arg for targets info table.
- const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES);
- GPR_ASSERT(arg != nullptr);
- GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
+ grpc_channel_args_get_pointer<grpc_lb_addresses>(args,
+ GRPC_ARG_LB_ADDRESSES);
+ GPR_ASSERT(addresses != nullptr);
grpc_core::RefCountedPtr<grpc_core::TargetAuthorityTable>
target_authority_table = grpc_core::CreateTargetAuthorityTable(addresses);
args_to_add[num_args_to_add++] =
diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
index ff2140e628..70220e28d3 100644
--- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
@@ -281,8 +281,10 @@ void PickFirst::PingOneLocked(grpc_closure* on_initiate, grpc_closure* on_ack) {
}
void PickFirst::UpdateLocked(const grpc_channel_args& args) {
- const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
- if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
+ const grpc_lb_addresses* addresses =
+ grpc_channel_args_get_pointer<const grpc_lb_addresses>(
+ &args, GRPC_ARG_LB_ADDRESSES);
+ if (addresses == nullptr) {
if (subchannel_list_ == nullptr) {
// If we don't have a current subchannel list, go into TRANSIENT FAILURE.
grpc_connectivity_state_set(
@@ -298,8 +300,6 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
}
return;
}
- const grpc_lb_addresses* addresses =
- static_cast<const grpc_lb_addresses*>(arg->value.pointer.p);
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO,
"Pick First %p received update with %" PRIuPTR " addresses", this,
diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
index b177385065..066f6ef7a6 100644
--- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
@@ -607,8 +607,10 @@ void RoundRobin::PingOneLocked(grpc_closure* on_initiate,
}
void RoundRobin::UpdateLocked(const grpc_channel_args& args) {
- const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
- if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) {
+ grpc_lb_addresses* addresses =
+ grpc_channel_args_get_pointer<grpc_lb_addresses>(&args,
+ GRPC_ARG_LB_ADDRESSES);
+ if (GPR_UNLIKELY(addresses == nullptr)) {
gpr_log(GPR_ERROR, "[RR %p] update provided no addresses; ignoring", this);
// If we don't have a current subchannel list, go into TRANSIENT_FAILURE.
// Otherwise, keep using the current subchannel list (ignore this update).
@@ -620,8 +622,6 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args) {
}
return;
}
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses",
this, addresses->num_addresses);
diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.cc b/src/core/ext/filters/client_channel/lb_policy_factory.cc
index 7c8cba55b7..93dae753bf 100644
--- a/src/core/ext/filters/client_channel/lb_policy_factory.cc
+++ b/src/core/ext/filters/client_channel/lb_policy_factory.cc
@@ -147,9 +147,6 @@ grpc_arg grpc_lb_addresses_create_channel_arg(
grpc_lb_addresses* grpc_lb_addresses_find_channel_arg(
const grpc_channel_args* channel_args) {
- const grpc_arg* lb_addresses_arg =
- grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES);
- if (lb_addresses_arg == nullptr || lb_addresses_arg->type != GRPC_ARG_POINTER)
- return nullptr;
- return static_cast<grpc_lb_addresses*>(lb_addresses_arg->value.pointer.p);
+ return grpc_channel_args_get_pointer<grpc_lb_addresses>(
+ channel_args, GRPC_ARG_LB_ADDRESSES);
}
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
index 3c40ae14b8..01156b1e40 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
@@ -140,14 +140,11 @@ AresDnsResolver::AresDnsResolver(const ResolverArgs& args)
dns_server_ = gpr_strdup(args.uri->authority);
}
channel_args_ = grpc_channel_args_copy(args.args);
- const grpc_arg* arg = grpc_channel_args_find(
- channel_args_, GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION);
- request_service_config_ = !grpc_channel_arg_get_integer(
- arg, (grpc_integer_options){false, false, true});
- arg = grpc_channel_args_find(channel_args_,
- GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS);
- min_time_between_resolutions_ =
- grpc_channel_arg_get_integer(arg, {1000, 0, INT_MAX});
+ request_service_config_ = !grpc_channel_args_get_bool(
+ channel_args_, GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION, false);
+ min_time_between_resolutions_ = grpc_channel_args_get_integer(
+ channel_args_, GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS,
+ {1000, 0, INT_MAX});
interested_parties_ = grpc_pollset_set_create();
if (args.pollset_set != nullptr) {
grpc_pollset_set_add_pollset_set(interested_parties_, args.pollset_set);
@@ -414,10 +411,10 @@ void AresDnsResolver::StartResolvingLocked() {
resolving_ = true;
lb_addresses_ = nullptr;
service_config_json_ = nullptr;
- pending_request_ = grpc_dns_lookup_ares(
+ pending_request_ = grpc_dns_lookup_ares_locked(
dns_server_, name_to_resolve_, kDefaultPort, interested_parties_,
&on_resolved_, &lb_addresses_, true /* check_grpclb */,
- request_service_config_ ? &service_config_json_ : nullptr);
+ request_service_config_ ? &service_config_json_ : nullptr, combiner());
last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now();
}
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
index 6239549534..27d1511d94 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
@@ -29,25 +29,27 @@ typedef struct grpc_ares_ev_driver grpc_ares_ev_driver;
/* Start \a ev_driver. It will keep working until all IO on its ares_channel is
done, or grpc_ares_ev_driver_destroy() is called. It may notify the callbacks
bound to its ares_channel when necessary. */
-void grpc_ares_ev_driver_start(grpc_ares_ev_driver* ev_driver);
+void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver);
/* Returns the ares_channel owned by \a ev_driver. To bind a c-ares query to
\a ev_driver, use the ares_channel owned by \a ev_driver as the arg of the
query. */
-ares_channel* grpc_ares_ev_driver_get_channel(grpc_ares_ev_driver* ev_driver);
+ares_channel* grpc_ares_ev_driver_get_channel_locked(
+ grpc_ares_ev_driver* ev_driver);
/* Creates a new grpc_ares_ev_driver. Returns GRPC_ERROR_NONE if \a ev_driver is
created successfully. */
-grpc_error* grpc_ares_ev_driver_create(grpc_ares_ev_driver** ev_driver,
- grpc_pollset_set* pollset_set);
+grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver,
+ grpc_pollset_set* pollset_set,
+ grpc_combiner* combiner);
/* Destroys \a ev_driver asynchronously. Pending lookups made on \a ev_driver
will be cancelled and their on_done callbacks will be invoked with a status
of ARES_ECANCELLED. */
-void grpc_ares_ev_driver_destroy(grpc_ares_ev_driver* ev_driver);
+void grpc_ares_ev_driver_destroy_locked(grpc_ares_ev_driver* ev_driver);
/* Shutdown all the grpc_fds used by \a ev_driver */
-void grpc_ares_ev_driver_shutdown(grpc_ares_ev_driver* ev_driver);
+void grpc_ares_ev_driver_shutdown_locked(grpc_ares_ev_driver* ev_driver);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H \
*/
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
index b604f2bf14..b73e979e9f 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
@@ -18,9 +18,10 @@
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/port.h"
-#if GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET)
+#if GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET_ARES_EV_DRIVER)
#include <ares.h>
+#include <string.h>
#include <sys/ioctl.h>
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
@@ -38,25 +39,23 @@
typedef struct fd_node {
/** the owner of this fd node */
grpc_ares_ev_driver* ev_driver;
- /** a closure wrapping on_readable_cb, which should be invoked when the
- grpc_fd in this node becomes readable. */
+ /** a closure wrapping on_readable_locked, which should be
+ invoked when the grpc_fd in this node becomes readable. */
grpc_closure read_closure;
- /** a closure wrapping on_writable_cb, which should be invoked when the
- grpc_fd in this node becomes writable. */
+ /** a closure wrapping on_writable_locked, which should be
+ invoked when the grpc_fd in this node becomes writable. */
grpc_closure write_closure;
/** next fd node in the list */
struct fd_node* next;
- /** mutex guarding the rest of the state */
- gpr_mu mu;
/** the grpc_fd owned by this fd node */
grpc_fd* fd;
/** if the readable closure has been registered */
bool readable_registered;
/** if the writable closure has been registered */
bool writable_registered;
- /** if the fd is being shut down */
- bool shutting_down;
+ /** if the fd has been shutdown yet from grpc iomgr perspective */
+ bool already_shutdown;
} fd_node;
struct grpc_ares_ev_driver {
@@ -67,8 +66,8 @@ struct grpc_ares_ev_driver {
/** refcount of the event driver */
gpr_refcount refs;
- /** mutex guarding the rest of the state */
- gpr_mu mu;
+ /** combiner to synchronize c-ares and I/O callbacks on */
+ grpc_combiner* combiner;
/** a list of grpc_fd that this event driver is currently using. */
fd_node* fds;
/** is this event driver currently working? */
@@ -91,44 +90,42 @@ static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) {
if (gpr_unref(&ev_driver->refs)) {
gpr_log(GPR_DEBUG, "destroy ev_driver %" PRIuPTR, (uintptr_t)ev_driver);
GPR_ASSERT(ev_driver->fds == nullptr);
- gpr_mu_destroy(&ev_driver->mu);
+ GRPC_COMBINER_UNREF(ev_driver->combiner, "free ares event driver");
ares_destroy(ev_driver->channel);
gpr_free(ev_driver);
}
}
-static void fd_node_destroy(fd_node* fdn) {
+static void fd_node_destroy_locked(fd_node* fdn) {
gpr_log(GPR_DEBUG, "delete fd: %d", grpc_fd_wrapped_fd(fdn->fd));
GPR_ASSERT(!fdn->readable_registered);
GPR_ASSERT(!fdn->writable_registered);
- gpr_mu_destroy(&fdn->mu);
- /* c-ares library has closed the fd inside grpc_fd. This fd may be picked up
+ GPR_ASSERT(fdn->already_shutdown);
+ /* c-ares library will close the fd inside grpc_fd. This fd may be picked up
immediately by another thread, and should not be closed by the following
grpc_fd_orphan. */
- grpc_fd_orphan(fdn->fd, nullptr, nullptr, true /* already_closed */,
- "c-ares query finished");
+ int dummy_release_fd;
+ grpc_fd_orphan(fdn->fd, nullptr, &dummy_release_fd, "c-ares query finished");
gpr_free(fdn);
}
-static void fd_node_shutdown(fd_node* fdn) {
- gpr_mu_lock(&fdn->mu);
- fdn->shutting_down = true;
- if (!fdn->readable_registered && !fdn->writable_registered) {
- gpr_mu_unlock(&fdn->mu);
- fd_node_destroy(fdn);
- } else {
- grpc_fd_shutdown(
- fdn->fd, GRPC_ERROR_CREATE_FROM_STATIC_STRING("c-ares fd shutdown"));
- gpr_mu_unlock(&fdn->mu);
+static void fd_node_shutdown_locked(fd_node* fdn, const char* reason) {
+ if (!fdn->already_shutdown) {
+ fdn->already_shutdown = true;
+ grpc_fd_shutdown(fdn->fd, GRPC_ERROR_CREATE_FROM_STATIC_STRING(reason));
}
}
-grpc_error* grpc_ares_ev_driver_create(grpc_ares_ev_driver** ev_driver,
- grpc_pollset_set* pollset_set) {
+grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver,
+ grpc_pollset_set* pollset_set,
+ grpc_combiner* combiner) {
*ev_driver = static_cast<grpc_ares_ev_driver*>(
gpr_malloc(sizeof(grpc_ares_ev_driver)));
- int status = ares_init(&(*ev_driver)->channel);
- gpr_log(GPR_DEBUG, "grpc_ares_ev_driver_create");
+ ares_options opts;
+ memset(&opts, 0, sizeof(opts));
+ opts.flags |= ARES_FLAG_STAYOPEN;
+ int status = ares_init_options(&(*ev_driver)->channel, &opts, ARES_OPT_FLAGS);
+ gpr_log(GPR_DEBUG, "grpc_ares_ev_driver_create_locked");
if (status != ARES_SUCCESS) {
char* err_msg;
gpr_asprintf(&err_msg, "Failed to init ares channel. C-ares error: %s",
@@ -138,7 +135,7 @@ grpc_error* grpc_ares_ev_driver_create(grpc_ares_ev_driver** ev_driver,
gpr_free(*ev_driver);
return err;
}
- gpr_mu_init(&(*ev_driver)->mu);
+ (*ev_driver)->combiner = GRPC_COMBINER_REF(combiner, "ares event driver");
gpr_ref_init(&(*ev_driver)->refs, 1);
(*ev_driver)->pollset_set = pollset_set;
(*ev_driver)->fds = nullptr;
@@ -147,33 +144,26 @@ grpc_error* grpc_ares_ev_driver_create(grpc_ares_ev_driver** ev_driver,
return GRPC_ERROR_NONE;
}
-void grpc_ares_ev_driver_destroy(grpc_ares_ev_driver* ev_driver) {
- // It's not safe to shut down remaining fds here directly, becauses
- // ares_host_callback does not provide an exec_ctx. We mark the event driver
- // as being shut down. If the event driver is working,
- // grpc_ares_notify_on_event_locked will shut down the fds; if it's not
- // working, there are no fds to shut down.
- gpr_mu_lock(&ev_driver->mu);
+void grpc_ares_ev_driver_destroy_locked(grpc_ares_ev_driver* ev_driver) {
+ // We mark the event driver as being shut down. If the event driver
+ // is working, grpc_ares_notify_on_event_locked will shut down the
+ // fds; if it's not working, there are no fds to shut down.
ev_driver->shutting_down = true;
- gpr_mu_unlock(&ev_driver->mu);
grpc_ares_ev_driver_unref(ev_driver);
}
-void grpc_ares_ev_driver_shutdown(grpc_ares_ev_driver* ev_driver) {
- gpr_mu_lock(&ev_driver->mu);
+void grpc_ares_ev_driver_shutdown_locked(grpc_ares_ev_driver* ev_driver) {
ev_driver->shutting_down = true;
fd_node* fn = ev_driver->fds;
while (fn != nullptr) {
- grpc_fd_shutdown(fn->fd, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "grpc_ares_ev_driver_shutdown"));
+ fd_node_shutdown_locked(fn, "grpc_ares_ev_driver_shutdown");
fn = fn->next;
}
- gpr_mu_unlock(&ev_driver->mu);
}
// Search fd in the fd_node list head. This is an O(n) search, the max possible
// value of n is ARES_GETSOCK_MAXNUM (16). n is typically 1 - 2 in our tests.
-static fd_node* pop_fd_node(fd_node** head, int fd) {
+static fd_node* pop_fd_node_locked(fd_node** head, int fd) {
fd_node dummy_head;
dummy_head.next = *head;
fd_node* node = &dummy_head;
@@ -190,31 +180,22 @@ static fd_node* pop_fd_node(fd_node** head, int fd) {
}
/* Check if \a fd is still readable */
-static bool grpc_ares_is_fd_still_readable(grpc_ares_ev_driver* ev_driver,
- int fd) {
+static bool grpc_ares_is_fd_still_readable_locked(
+ grpc_ares_ev_driver* ev_driver, int fd) {
size_t bytes_available = 0;
return ioctl(fd, FIONREAD, &bytes_available) == 0 && bytes_available > 0;
}
-static void on_readable_cb(void* arg, grpc_error* error) {
+static void on_readable_locked(void* arg, grpc_error* error) {
fd_node* fdn = static_cast<fd_node*>(arg);
grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
- gpr_mu_lock(&fdn->mu);
const int fd = grpc_fd_wrapped_fd(fdn->fd);
fdn->readable_registered = false;
- if (fdn->shutting_down && !fdn->writable_registered) {
- gpr_mu_unlock(&fdn->mu);
- fd_node_destroy(fdn);
- grpc_ares_ev_driver_unref(ev_driver);
- return;
- }
- gpr_mu_unlock(&fdn->mu);
-
gpr_log(GPR_DEBUG, "readable on %d", fd);
if (error == GRPC_ERROR_NONE) {
do {
ares_process_fd(ev_driver->channel, fd, ARES_SOCKET_BAD);
- } while (grpc_ares_is_fd_still_readable(ev_driver, fd));
+ } while (grpc_ares_is_fd_still_readable_locked(ev_driver, fd));
} else {
// If error is not GRPC_ERROR_NONE, it means the fd has been shutdown or
// timed out. The pending lookups made on this ev_driver will be cancelled
@@ -224,26 +205,15 @@ static void on_readable_cb(void* arg, grpc_error* error) {
// grpc_ares_notify_on_event_locked().
ares_cancel(ev_driver->channel);
}
- gpr_mu_lock(&ev_driver->mu);
grpc_ares_notify_on_event_locked(ev_driver);
- gpr_mu_unlock(&ev_driver->mu);
grpc_ares_ev_driver_unref(ev_driver);
}
-static void on_writable_cb(void* arg, grpc_error* error) {
+static void on_writable_locked(void* arg, grpc_error* error) {
fd_node* fdn = static_cast<fd_node*>(arg);
grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
- gpr_mu_lock(&fdn->mu);
const int fd = grpc_fd_wrapped_fd(fdn->fd);
fdn->writable_registered = false;
- if (fdn->shutting_down && !fdn->readable_registered) {
- gpr_mu_unlock(&fdn->mu);
- fd_node_destroy(fdn);
- grpc_ares_ev_driver_unref(ev_driver);
- return;
- }
- gpr_mu_unlock(&fdn->mu);
-
gpr_log(GPR_DEBUG, "writable on %d", fd);
if (error == GRPC_ERROR_NONE) {
ares_process_fd(ev_driver->channel, ARES_SOCKET_BAD, fd);
@@ -256,13 +226,12 @@ static void on_writable_cb(void* arg, grpc_error* error) {
// grpc_ares_notify_on_event_locked().
ares_cancel(ev_driver->channel);
}
- gpr_mu_lock(&ev_driver->mu);
grpc_ares_notify_on_event_locked(ev_driver);
- gpr_mu_unlock(&ev_driver->mu);
grpc_ares_ev_driver_unref(ev_driver);
}
-ares_channel* grpc_ares_ev_driver_get_channel(grpc_ares_ev_driver* ev_driver) {
+ares_channel* grpc_ares_ev_driver_get_channel_locked(
+ grpc_ares_ev_driver* ev_driver) {
return &ev_driver->channel;
}
@@ -277,29 +246,27 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) {
for (size_t i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
if (ARES_GETSOCK_READABLE(socks_bitmask, i) ||
ARES_GETSOCK_WRITABLE(socks_bitmask, i)) {
- fd_node* fdn = pop_fd_node(&ev_driver->fds, socks[i]);
+ fd_node* fdn = pop_fd_node_locked(&ev_driver->fds, socks[i]);
// Create a new fd_node if sock[i] is not in the fd_node list.
if (fdn == nullptr) {
char* fd_name;
gpr_asprintf(&fd_name, "ares_ev_driver-%" PRIuPTR, i);
fdn = static_cast<fd_node*>(gpr_malloc(sizeof(fd_node)));
gpr_log(GPR_DEBUG, "new fd: %d", socks[i]);
- fdn->fd = grpc_fd_create(socks[i], fd_name);
+ fdn->fd = grpc_fd_create(socks[i], fd_name, false);
fdn->ev_driver = ev_driver;
fdn->readable_registered = false;
fdn->writable_registered = false;
- fdn->shutting_down = false;
- gpr_mu_init(&fdn->mu);
- GRPC_CLOSURE_INIT(&fdn->read_closure, on_readable_cb, fdn,
- grpc_schedule_on_exec_ctx);
- GRPC_CLOSURE_INIT(&fdn->write_closure, on_writable_cb, fdn,
- grpc_schedule_on_exec_ctx);
+ fdn->already_shutdown = false;
+ GRPC_CLOSURE_INIT(&fdn->read_closure, on_readable_locked, fdn,
+ grpc_combiner_scheduler(ev_driver->combiner));
+ GRPC_CLOSURE_INIT(&fdn->write_closure, on_writable_locked, fdn,
+ grpc_combiner_scheduler(ev_driver->combiner));
grpc_pollset_set_add_fd(ev_driver->pollset_set, fdn->fd);
gpr_free(fd_name);
}
fdn->next = new_list;
new_list = fdn;
- gpr_mu_lock(&fdn->mu);
// Register read_closure if the socket is readable and read_closure has
// not been registered with this socket.
if (ARES_GETSOCK_READABLE(socks_bitmask, i) &&
@@ -319,7 +286,6 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) {
grpc_fd_notify_on_write(fdn->fd, &fdn->write_closure);
fdn->writable_registered = true;
}
- gpr_mu_unlock(&fdn->mu);
}
}
}
@@ -329,7 +295,13 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) {
while (ev_driver->fds != nullptr) {
fd_node* cur = ev_driver->fds;
ev_driver->fds = ev_driver->fds->next;
- fd_node_shutdown(cur);
+ fd_node_shutdown_locked(cur, "c-ares fd shutdown");
+ if (!cur->readable_registered && !cur->writable_registered) {
+ fd_node_destroy_locked(cur);
+ } else {
+ cur->next = new_list;
+ new_list = cur;
+ }
}
ev_driver->fds = new_list;
// If the ev driver has no working fd, all the tasks are done.
@@ -339,13 +311,11 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) {
}
}
-void grpc_ares_ev_driver_start(grpc_ares_ev_driver* ev_driver) {
- gpr_mu_lock(&ev_driver->mu);
+void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) {
if (!ev_driver->working) {
ev_driver->working = true;
grpc_ares_notify_on_event_locked(ev_driver);
}
- gpr_mu_unlock(&ev_driver->mu);
}
-#endif /* GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET) */
+#endif /* GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET_ARES_EV_DRIVER) */
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
index 18d0a7b9f6..471de58e8c 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
@@ -65,8 +65,6 @@ struct grpc_ares_request {
/** number of ongoing queries */
gpr_refcount pending_queries;
- /** mutex guarding the rest of the state */
- gpr_mu mu;
/** is there at least one successful query, set in on_done_cb */
bool success;
/** the errors explaining the request failure, set in on_done_cb */
@@ -74,7 +72,8 @@ struct grpc_ares_request {
};
typedef struct grpc_ares_hostbyname_request {
- /** following members are set in create_hostbyname_request */
+ /** following members are set in create_hostbyname_request_locked
+ */
/** the top-level request instance */
grpc_ares_request* parent_request;
/** host to resolve, parsed from the name to resolve */
@@ -96,10 +95,6 @@ static uint16_t strhtons(const char* port) {
return htons(static_cast<unsigned short>(atoi(port)));
}
-static void grpc_ares_request_ref(grpc_ares_request* r) {
- gpr_ref(&r->pending_queries);
-}
-
static void log_address_sorting_list(grpc_lb_addresses* lb_addrs,
const char* input_output_str) {
for (size_t i = 0; i < lb_addrs->num_addresses; i++) {
@@ -149,7 +144,11 @@ void grpc_cares_wrapper_test_only_address_sorting_sort(
grpc_cares_wrapper_address_sorting_sort(lb_addrs);
}
-static void grpc_ares_request_unref(grpc_ares_request* r) {
+static void grpc_ares_request_ref_locked(grpc_ares_request* r) {
+ gpr_ref(&r->pending_queries);
+}
+
+static void grpc_ares_request_unref_locked(grpc_ares_request* r) {
/* If there are no pending queries, invoke on_done callback and destroy the
request */
if (gpr_unref(&r->pending_queries)) {
@@ -158,13 +157,12 @@ static void grpc_ares_request_unref(grpc_ares_request* r) {
grpc_cares_wrapper_address_sorting_sort(lb_addrs);
}
GRPC_CLOSURE_SCHED(r->on_done, r->error);
- gpr_mu_destroy(&r->mu);
- grpc_ares_ev_driver_destroy(r->ev_driver);
+ grpc_ares_ev_driver_destroy_locked(r->ev_driver);
gpr_free(r);
}
}
-static grpc_ares_hostbyname_request* create_hostbyname_request(
+static grpc_ares_hostbyname_request* create_hostbyname_request_locked(
grpc_ares_request* parent_request, char* host, uint16_t port,
bool is_balancer) {
grpc_ares_hostbyname_request* hr = static_cast<grpc_ares_hostbyname_request*>(
@@ -173,22 +171,22 @@ static grpc_ares_hostbyname_request* create_hostbyname_request(
hr->host = gpr_strdup(host);
hr->port = port;
hr->is_balancer = is_balancer;
- grpc_ares_request_ref(parent_request);
+ grpc_ares_request_ref_locked(parent_request);
return hr;
}
-static void destroy_hostbyname_request(grpc_ares_hostbyname_request* hr) {
- grpc_ares_request_unref(hr->parent_request);
+static void destroy_hostbyname_request_locked(
+ grpc_ares_hostbyname_request* hr) {
+ grpc_ares_request_unref_locked(hr->parent_request);
gpr_free(hr->host);
gpr_free(hr);
}
-static void on_hostbyname_done_cb(void* arg, int status, int timeouts,
- struct hostent* hostent) {
+static void on_hostbyname_done_locked(void* arg, int status, int timeouts,
+ struct hostent* hostent) {
grpc_ares_hostbyname_request* hr =
static_cast<grpc_ares_hostbyname_request*>(arg);
grpc_ares_request* r = hr->parent_request;
- gpr_mu_lock(&r->mu);
if (status == ARES_SUCCESS) {
GRPC_ERROR_UNREF(r->error);
r->error = GRPC_ERROR_NONE;
@@ -263,33 +261,33 @@ static void on_hostbyname_done_cb(void* arg, int status, int timeouts,
r->error = grpc_error_add_child(error, r->error);
}
}
- gpr_mu_unlock(&r->mu);
- destroy_hostbyname_request(hr);
+ destroy_hostbyname_request_locked(hr);
}
-static void on_srv_query_done_cb(void* arg, int status, int timeouts,
- unsigned char* abuf, int alen) {
+static void on_srv_query_done_locked(void* arg, int status, int timeouts,
+ unsigned char* abuf, int alen) {
grpc_ares_request* r = static_cast<grpc_ares_request*>(arg);
- gpr_log(GPR_DEBUG, "on_query_srv_done_cb");
+ gpr_log(GPR_DEBUG, "on_query_srv_done_locked");
if (status == ARES_SUCCESS) {
- gpr_log(GPR_DEBUG, "on_query_srv_done_cb ARES_SUCCESS");
+ gpr_log(GPR_DEBUG, "on_query_srv_done_locked ARES_SUCCESS");
struct ares_srv_reply* reply;
const int parse_status = ares_parse_srv_reply(abuf, alen, &reply);
if (parse_status == ARES_SUCCESS) {
- ares_channel* channel = grpc_ares_ev_driver_get_channel(r->ev_driver);
+ ares_channel* channel =
+ grpc_ares_ev_driver_get_channel_locked(r->ev_driver);
for (struct ares_srv_reply* srv_it = reply; srv_it != nullptr;
srv_it = srv_it->next) {
if (grpc_ipv6_loopback_available()) {
- grpc_ares_hostbyname_request* hr = create_hostbyname_request(
+ grpc_ares_hostbyname_request* hr = create_hostbyname_request_locked(
r, srv_it->host, htons(srv_it->port), true /* is_balancer */);
ares_gethostbyname(*channel, hr->host, AF_INET6,
- on_hostbyname_done_cb, hr);
+ on_hostbyname_done_locked, hr);
}
- grpc_ares_hostbyname_request* hr = create_hostbyname_request(
+ grpc_ares_hostbyname_request* hr = create_hostbyname_request_locked(
r, srv_it->host, htons(srv_it->port), true /* is_balancer */);
- ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_cb,
- hr);
- grpc_ares_ev_driver_start(r->ev_driver);
+ ares_gethostbyname(*channel, hr->host, AF_INET,
+ on_hostbyname_done_locked, hr);
+ grpc_ares_ev_driver_start_locked(r->ev_driver);
}
}
if (reply != nullptr) {
@@ -307,21 +305,20 @@ static void on_srv_query_done_cb(void* arg, int status, int timeouts,
r->error = grpc_error_add_child(error, r->error);
}
}
- grpc_ares_request_unref(r);
+ grpc_ares_request_unref_locked(r);
}
static const char g_service_config_attribute_prefix[] = "grpc_config=";
-static void on_txt_done_cb(void* arg, int status, int timeouts,
- unsigned char* buf, int len) {
- gpr_log(GPR_DEBUG, "on_txt_done_cb");
+static void on_txt_done_locked(void* arg, int status, int timeouts,
+ unsigned char* buf, int len) {
+ gpr_log(GPR_DEBUG, "on_txt_done_locked");
char* error_msg;
grpc_ares_request* r = static_cast<grpc_ares_request*>(arg);
const size_t prefix_len = sizeof(g_service_config_attribute_prefix) - 1;
struct ares_txt_ext* result = nullptr;
struct ares_txt_ext* reply = nullptr;
grpc_error* error = GRPC_ERROR_NONE;
- gpr_mu_lock(&r->mu);
if (status != ARES_SUCCESS) goto fail;
status = ares_parse_txt_reply_ext(buf, len, &reply);
if (status != ARES_SUCCESS) goto fail;
@@ -366,14 +363,14 @@ fail:
r->error = grpc_error_add_child(error, r->error);
}
done:
- gpr_mu_unlock(&r->mu);
- grpc_ares_request_unref(r);
+ grpc_ares_request_unref_locked(r);
}
-static grpc_ares_request* grpc_dns_lookup_ares_impl(
+static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json) {
+ grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json,
+ grpc_combiner* combiner) {
grpc_error* error = GRPC_ERROR_NONE;
grpc_ares_hostbyname_request* hr = nullptr;
grpc_ares_request* r = nullptr;
@@ -402,20 +399,19 @@ static grpc_ares_request* grpc_dns_lookup_ares_impl(
}
port = gpr_strdup(default_port);
}
-
grpc_ares_ev_driver* ev_driver;
- error = grpc_ares_ev_driver_create(&ev_driver, interested_parties);
+ error = grpc_ares_ev_driver_create_locked(&ev_driver, interested_parties,
+ combiner);
if (error != GRPC_ERROR_NONE) goto error_cleanup;
r = static_cast<grpc_ares_request*>(gpr_zalloc(sizeof(grpc_ares_request)));
- gpr_mu_init(&r->mu);
r->ev_driver = ev_driver;
r->on_done = on_done;
r->lb_addrs_out = addrs;
r->service_config_json_out = service_config_json;
r->success = false;
r->error = GRPC_ERROR_NONE;
- channel = grpc_ares_ev_driver_get_channel(r->ev_driver);
+ channel = grpc_ares_ev_driver_get_channel_locked(r->ev_driver);
// If dns_server is specified, use it.
if (dns_server != nullptr) {
@@ -457,32 +453,34 @@ static grpc_ares_request* grpc_dns_lookup_ares_impl(
}
gpr_ref_init(&r->pending_queries, 1);
if (grpc_ipv6_loopback_available()) {
- hr = create_hostbyname_request(r, host, strhtons(port),
- false /* is_balancer */);
- ares_gethostbyname(*channel, hr->host, AF_INET6, on_hostbyname_done_cb, hr);
+ hr = create_hostbyname_request_locked(r, host, strhtons(port),
+ false /* is_balancer */);
+ ares_gethostbyname(*channel, hr->host, AF_INET6, on_hostbyname_done_locked,
+ hr);
}
- hr = create_hostbyname_request(r, host, strhtons(port),
- false /* is_balancer */);
- ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_cb, hr);
+ hr = create_hostbyname_request_locked(r, host, strhtons(port),
+ false /* is_balancer */);
+ ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_locked,
+ hr);
if (check_grpclb) {
/* Query the SRV record */
- grpc_ares_request_ref(r);
+ grpc_ares_request_ref_locked(r);
char* service_name;
gpr_asprintf(&service_name, "_grpclb._tcp.%s", host);
- ares_query(*channel, service_name, ns_c_in, ns_t_srv, on_srv_query_done_cb,
- r);
+ ares_query(*channel, service_name, ns_c_in, ns_t_srv,
+ on_srv_query_done_locked, r);
gpr_free(service_name);
}
if (service_config_json != nullptr) {
- grpc_ares_request_ref(r);
+ grpc_ares_request_ref_locked(r);
char* config_name;
gpr_asprintf(&config_name, "_grpc_config.%s", host);
- ares_search(*channel, config_name, ns_c_in, ns_t_txt, on_txt_done_cb, r);
+ ares_search(*channel, config_name, ns_c_in, ns_t_txt, on_txt_done_locked,
+ r);
gpr_free(config_name);
}
- /* TODO(zyc): Handle CNAME records here. */
- grpc_ares_ev_driver_start(r->ev_driver);
- grpc_ares_request_unref(r);
+ grpc_ares_ev_driver_start_locked(r->ev_driver);
+ grpc_ares_request_unref_locked(r);
gpr_free(host);
gpr_free(port);
return r;
@@ -494,15 +492,15 @@ error_cleanup:
return nullptr;
}
-grpc_ares_request* (*grpc_dns_lookup_ares)(
+grpc_ares_request* (*grpc_dns_lookup_ares_locked)(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** addrs, bool check_grpclb,
- char** service_config_json) = grpc_dns_lookup_ares_impl;
+ grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json,
+ grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl;
void grpc_cancel_ares_request(grpc_ares_request* r) {
- if (grpc_dns_lookup_ares == grpc_dns_lookup_ares_impl) {
- grpc_ares_ev_driver_shutdown(r->ev_driver);
+ if (grpc_dns_lookup_ares_locked == grpc_dns_lookup_ares_locked_impl) {
+ grpc_ares_ev_driver_shutdown_locked(r->ev_driver);
}
}
@@ -534,6 +532,8 @@ void grpc_ares_cleanup(void) {
*/
typedef struct grpc_resolve_address_ares_request {
+ /* combiner that queries and related callbacks run under */
+ grpc_combiner* combiner;
/** the pointer to receive the resolved addresses */
grpc_resolved_addresses** addrs_out;
/** currently resolving lb addresses */
@@ -541,8 +541,14 @@ typedef struct grpc_resolve_address_ares_request {
/** closure to call when the resolve_address_ares request completes */
grpc_closure* on_resolve_address_done;
/** a closure wrapping on_dns_lookup_done_cb, which should be invoked when the
- grpc_dns_lookup_ares operation is done. */
+ grpc_dns_lookup_ares_locked operation is done. */
grpc_closure on_dns_lookup_done;
+ /* target name */
+ const char* name;
+ /* default port to use if none is specified */
+ const char* default_port;
+ /* pollset_set to be driven by */
+ grpc_pollset_set* interested_parties;
} grpc_resolve_address_ares_request;
static void on_dns_lookup_done_cb(void* arg, grpc_error* error) {
@@ -566,9 +572,20 @@ static void on_dns_lookup_done_cb(void* arg, grpc_error* error) {
}
GRPC_CLOSURE_SCHED(r->on_resolve_address_done, GRPC_ERROR_REF(error));
if (r->lb_addrs != nullptr) grpc_lb_addresses_destroy(r->lb_addrs);
+ GRPC_COMBINER_UNREF(r->combiner, "on_dns_lookup_done_cb");
gpr_free(r);
}
+static void grpc_resolve_address_invoke_dns_lookup_ares_locked(
+ void* arg, grpc_error* unused_error) {
+ grpc_resolve_address_ares_request* r =
+ static_cast<grpc_resolve_address_ares_request*>(arg);
+ grpc_dns_lookup_ares_locked(
+ nullptr /* dns_server */, r->name, r->default_port, r->interested_parties,
+ &r->on_dns_lookup_done, &r->lb_addrs, false /* check_grpclb */,
+ nullptr /* service_config_json */, r->combiner);
+}
+
static void grpc_resolve_address_ares_impl(const char* name,
const char* default_port,
grpc_pollset_set* interested_parties,
@@ -577,14 +594,18 @@ static void grpc_resolve_address_ares_impl(const char* name,
grpc_resolve_address_ares_request* r =
static_cast<grpc_resolve_address_ares_request*>(
gpr_zalloc(sizeof(grpc_resolve_address_ares_request)));
+ r->combiner = grpc_combiner_create();
r->addrs_out = addrs;
r->on_resolve_address_done = on_done;
GRPC_CLOSURE_INIT(&r->on_dns_lookup_done, on_dns_lookup_done_cb, r,
grpc_schedule_on_exec_ctx);
- grpc_dns_lookup_ares(nullptr /* dns_server */, name, default_port,
- interested_parties, &r->on_dns_lookup_done, &r->lb_addrs,
- false /* check_grpclb */,
- nullptr /* service_config_json */);
+ r->name = name;
+ r->default_port = default_port;
+ r->interested_parties = interested_parties;
+ GRPC_CLOSURE_SCHED(
+ GRPC_CLOSURE_CREATE(grpc_resolve_address_invoke_dns_lookup_ares_locked, r,
+ grpc_combiner_scheduler(r->combiner)),
+ GRPC_ERROR_NONE);
}
void (*grpc_resolve_address_ares)(
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
index 2d84a038d6..9e93d0cf94 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
@@ -48,11 +48,11 @@ extern void (*grpc_resolve_address_ares)(const char* name,
function. \a on_done may be called directly in this function without being
scheduled with \a exec_ctx, so it must not try to acquire locks that are
being held by the caller. */
-extern grpc_ares_request* (*grpc_dns_lookup_ares)(
+extern grpc_ares_request* (*grpc_dns_lookup_ares_locked)(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
grpc_lb_addresses** addresses, bool check_grpclb,
- char** service_config_json);
+ char** service_config_json, grpc_combiner* combiner);
/* Cancel the pending grpc_ares_request \a request */
void grpc_cancel_ares_request(grpc_ares_request* request);
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
index 5096e480bc..d6a76fc8b6 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
@@ -26,18 +26,19 @@ struct grpc_ares_request {
char val;
};
-static grpc_ares_request* grpc_dns_lookup_ares_impl(
+static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json) {
+ grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json,
+ grpc_combiner* combiner) {
return NULL;
}
-grpc_ares_request* (*grpc_dns_lookup_ares)(
+grpc_ares_request* (*grpc_dns_lookup_ares_locked)(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** addrs, bool check_grpclb,
- char** service_config_json) = grpc_dns_lookup_ares_impl;
+ grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json,
+ grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl;
void grpc_cancel_ares_request(grpc_ares_request* r) {}
diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
index fae4c33a17..25e92a078d 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
@@ -116,10 +116,9 @@ NativeDnsResolver::NativeDnsResolver(const ResolverArgs& args)
if (path[0] == '/') ++path;
name_to_resolve_ = gpr_strdup(path);
channel_args_ = grpc_channel_args_copy(args.args);
- const grpc_arg* arg = grpc_channel_args_find(
- args.args, GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS);
- min_time_between_resolutions_ =
- grpc_channel_arg_get_integer(arg, {1000, 0, INT_MAX});
+ min_time_between_resolutions_ = grpc_channel_args_get_integer(
+ args.args, GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS,
+ {1000, 0, INT_MAX});
interested_parties_ = grpc_pollset_set_create();
if (args.pollset_set != nullptr) {
grpc_pollset_set_add_pollset_set(interested_parties_, args.pollset_set);
diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
index 99a33f2277..9250dbd6b3 100644
--- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
@@ -252,20 +252,15 @@ static const grpc_arg_pointer_vtable response_generator_arg_vtable = {
grpc_arg FakeResolverResponseGenerator::MakeChannelArg(
FakeResolverResponseGenerator* generator) {
- grpc_arg arg;
- arg.type = GRPC_ARG_POINTER;
- arg.key = (char*)GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR;
- arg.value.pointer.p = generator;
- arg.value.pointer.vtable = &response_generator_arg_vtable;
- return arg;
+ return grpc_channel_arg_pointer_create(
+ const_cast<char*>(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR), generator,
+ &response_generator_arg_vtable);
}
FakeResolverResponseGenerator* FakeResolverResponseGenerator::GetFromArgs(
const grpc_channel_args* args) {
- const grpc_arg* arg =
- grpc_channel_args_find(args, GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR);
- if (arg == nullptr || arg->type != GRPC_ARG_POINTER) return nullptr;
- return static_cast<FakeResolverResponseGenerator*>(arg->value.pointer.p);
+ return grpc_channel_args_get_pointer<FakeResolverResponseGenerator>(
+ args, GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR);
}
//
diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc
index f010002ab9..5db5d1f6c0 100644
--- a/src/core/ext/filters/client_channel/subchannel.cc
+++ b/src/core/ext/filters/client_channel/subchannel.cc
@@ -736,9 +736,8 @@ void grpc_get_subchannel_address_arg(const grpc_channel_args* args,
}
const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args) {
- const grpc_arg* addr_arg =
- grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS);
- const char* addr_str = grpc_channel_arg_get_string(addr_arg);
+ const char* addr_str =
+ grpc_channel_args_get_string(args, GRPC_ARG_SUBCHANNEL_ADDRESS);
GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy.
return addr_str;
}
diff --git a/src/core/ext/filters/deadline/deadline_filter.cc b/src/core/ext/filters/deadline/deadline_filter.cc
index 27d3eac8d6..caa547204b 100644
--- a/src/core/ext/filters/deadline/deadline_filter.cc
+++ b/src/core/ext/filters/deadline/deadline_filter.cc
@@ -289,11 +289,10 @@ static void client_start_transport_stream_op_batch(
static void recv_initial_metadata_ready(void* arg, grpc_error* error) {
grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
server_call_data* calld = static_cast<server_call_data*>(elem->call_data);
- // Get deadline from metadata and start the timer if needed.
start_timer_if_needed(elem, calld->recv_initial_metadata->deadline);
// Invoke the next callback.
- calld->next_recv_initial_metadata_ready->cb(
- calld->next_recv_initial_metadata_ready->cb_arg, error);
+ GRPC_CLOSURE_RUN(calld->next_recv_initial_metadata_ready,
+ GRPC_ERROR_REF(error));
}
// Method for starting a call op for server filter.
@@ -359,8 +358,8 @@ const grpc_channel_filter grpc_server_deadline_filter = {
};
bool grpc_deadline_checking_enabled(const grpc_channel_args* channel_args) {
- return grpc_channel_arg_get_bool(
- grpc_channel_args_find(channel_args, GRPC_ARG_ENABLE_DEADLINE_CHECKS),
+ return grpc_channel_args_get_bool(
+ channel_args, GRPC_ARG_ENABLE_DEADLINE_CHECKS,
!grpc_channel_args_want_minimal_stack(channel_args));
}
diff --git a/src/core/ext/filters/http/client/http_client_filter.cc b/src/core/ext/filters/http/client/http_client_filter.cc
index ae94ce47b9..fe7f2ba705 100644
--- a/src/core/ext/filters/http/client/http_client_filter.cc
+++ b/src/core/ext/filters/http/client/http_client_filter.cc
@@ -23,6 +23,7 @@
#include <stdint.h>
#include <string.h>
#include "src/core/ext/filters/http/client/http_client_filter.h"
+#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/profiling/timers.h"
@@ -435,64 +436,43 @@ static void destroy_call_elem(grpc_call_element* elem,
const grpc_call_final_info* final_info,
grpc_closure* ignored) {}
-static grpc_mdelem scheme_from_args(const grpc_channel_args* args) {
- unsigned i;
- size_t j;
+static grpc_mdelem scheme_from_args(const grpc_channel_args* channel_args) {
grpc_mdelem valid_schemes[] = {GRPC_MDELEM_SCHEME_HTTP,
GRPC_MDELEM_SCHEME_HTTPS};
- if (args != nullptr) {
- for (i = 0; i < args->num_args; ++i) {
- if (args->args[i].type == GRPC_ARG_STRING &&
- strcmp(args->args[i].key, GRPC_ARG_HTTP2_SCHEME) == 0) {
- for (j = 0; j < GPR_ARRAY_SIZE(valid_schemes); j++) {
- if (0 == grpc_slice_str_cmp(GRPC_MDVALUE(valid_schemes[j]),
- args->args[i].value.string)) {
- return valid_schemes[j];
- }
- }
+ char* scheme =
+ grpc_channel_args_get_string(channel_args, GRPC_ARG_HTTP2_SCHEME);
+ if (scheme != nullptr) {
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(valid_schemes); i++) {
+ if (0 == grpc_slice_str_cmp(GRPC_MDVALUE(valid_schemes[i]), scheme)) {
+ return valid_schemes[i];
}
}
}
return GRPC_MDELEM_SCHEME_HTTP;
}
-static size_t max_payload_size_from_args(const grpc_channel_args* args) {
- if (args != nullptr) {
- for (size_t i = 0; i < args->num_args; ++i) {
- if (0 == strcmp(args->args[i].key, GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET)) {
- if (args->args[i].type != GRPC_ARG_INTEGER) {
- gpr_log(GPR_ERROR, "%s: must be an integer",
- GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET);
- } else {
- return static_cast<size_t>(args->args[i].value.integer);
- }
- }
- }
- }
- return kMaxPayloadSizeForGet;
+static size_t max_payload_size_from_args(
+ const grpc_channel_args* channel_args) {
+ return grpc_channel_args_get_integer(
+ channel_args, GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET,
+ {kMaxPayloadSizeForGet, 0, kMaxPayloadSizeForGet});
}
static grpc_slice user_agent_from_args(const grpc_channel_args* args,
const char* transport_name) {
gpr_strvec v;
- size_t i;
int is_first = 1;
char* tmp;
grpc_slice result;
gpr_strvec_init(&v);
- for (i = 0; args && i < args->num_args; i++) {
- if (0 == strcmp(args->args[i].key, GRPC_ARG_PRIMARY_USER_AGENT_STRING)) {
- if (args->args[i].type != GRPC_ARG_STRING) {
- gpr_log(GPR_ERROR, "Channel argument '%s' should be a string",
- GRPC_ARG_PRIMARY_USER_AGENT_STRING);
- } else {
- if (!is_first) gpr_strvec_add(&v, gpr_strdup(" "));
- is_first = 0;
- gpr_strvec_add(&v, gpr_strdup(args->args[i].value.string));
- }
- }
+ char* user_agent_str =
+ grpc_channel_args_get_string(args, GRPC_ARG_PRIMARY_USER_AGENT_STRING);
+ if (user_agent_str != nullptr) {
+ if (!is_first) gpr_strvec_add(&v, gpr_strdup(" "));
+ is_first = 0;
+ gpr_strvec_add(&v, gpr_strdup(user_agent_str));
}
gpr_asprintf(&tmp, "%sgrpc-c/%s (%s; %s; %s)", is_first ? "" : " ",
@@ -501,17 +481,11 @@ static grpc_slice user_agent_from_args(const grpc_channel_args* args,
is_first = 0;
gpr_strvec_add(&v, tmp);
- for (i = 0; args && i < args->num_args; i++) {
- if (0 == strcmp(args->args[i].key, GRPC_ARG_SECONDARY_USER_AGENT_STRING)) {
- if (args->args[i].type != GRPC_ARG_STRING) {
- gpr_log(GPR_ERROR, "Channel argument '%s' should be a string",
- GRPC_ARG_SECONDARY_USER_AGENT_STRING);
- } else {
- if (!is_first) gpr_strvec_add(&v, gpr_strdup(" "));
- is_first = 0;
- gpr_strvec_add(&v, gpr_strdup(args->args[i].value.string));
- }
- }
+ user_agent_str =
+ grpc_channel_args_get_string(args, GRPC_ARG_SECONDARY_USER_AGENT_STRING);
+ if (user_agent_str != nullptr) {
+ gpr_strvec_add(&v, gpr_strdup(" "));
+ gpr_strvec_add(&v, gpr_strdup(user_agent_str));
}
tmp = gpr_strvec_flatten(&v, nullptr);
diff --git a/src/core/ext/filters/http/http_filters_plugin.cc b/src/core/ext/filters/http/http_filters_plugin.cc
index f03fa0141d..d3cbe50016 100644
--- a/src/core/ext/filters/http/http_filters_plugin.cc
+++ b/src/core/ext/filters/http/http_filters_plugin.cc
@@ -48,8 +48,8 @@ static bool maybe_add_optional_filter(grpc_channel_stack_builder* builder,
optional_filter* filtarg = static_cast<optional_filter*>(arg);
const grpc_channel_args* channel_args =
grpc_channel_stack_builder_get_channel_arguments(builder);
- bool enable = grpc_channel_arg_get_bool(
- grpc_channel_args_find(channel_args, filtarg->control_channel_arg),
+ bool enable = grpc_channel_args_get_bool(
+ channel_args, filtarg->control_channel_arg,
!grpc_channel_args_want_minimal_stack(channel_args));
return enable ? grpc_channel_stack_builder_prepend_filter(
builder, filtarg->filter, nullptr, nullptr)
diff --git a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
index 0d349e2a89..a8f70333b2 100644
--- a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
+++ b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
@@ -82,9 +82,7 @@ static void on_initial_md_ready(void* user_data, grpc_error* err) {
} else {
GRPC_ERROR_REF(err);
}
- calld->ops_recv_initial_metadata_ready->cb(
- calld->ops_recv_initial_metadata_ready->cb_arg, err);
- GRPC_ERROR_UNREF(err);
+ GRPC_CLOSURE_RUN(calld->ops_recv_initial_metadata_ready, err);
}
/* Constructor for call_data */
diff --git a/src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc b/src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc
index 667c0c56ef..73bcf242d8 100644
--- a/src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc
+++ b/src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc
@@ -33,8 +33,7 @@
#include "src/core/lib/surface/channel_init.h"
static bool is_load_reporting_enabled(const grpc_channel_args* a) {
- return grpc_channel_arg_get_bool(
- grpc_channel_args_find(a, GRPC_ARG_ENABLE_LOAD_REPORTING), false);
+ return grpc_channel_args_get_bool(a, GRPC_ARG_ENABLE_LOAD_REPORTING, false);
}
static bool maybe_add_server_load_reporting_filter(
diff --git a/src/core/ext/filters/max_age/max_age_filter.cc b/src/core/ext/filters/max_age/max_age_filter.cc
index 1fe8288bd0..bbe4998f00 100644
--- a/src/core/ext/filters/max_age/max_age_filter.cc
+++ b/src/core/ext/filters/max_age/max_age_filter.cc
@@ -519,13 +519,12 @@ static bool maybe_add_max_age_filter(grpc_channel_stack_builder* builder,
void* arg) {
const grpc_channel_args* channel_args =
grpc_channel_stack_builder_get_channel_arguments(builder);
- bool enable =
- grpc_channel_arg_get_integer(
- grpc_channel_args_find(channel_args, GRPC_ARG_MAX_CONNECTION_AGE_MS),
- MAX_CONNECTION_AGE_INTEGER_OPTIONS) != INT_MAX ||
- grpc_channel_arg_get_integer(
- grpc_channel_args_find(channel_args, GRPC_ARG_MAX_CONNECTION_IDLE_MS),
- MAX_CONNECTION_IDLE_INTEGER_OPTIONS) != INT_MAX;
+ bool enable = grpc_channel_args_get_integer(
+ channel_args, GRPC_ARG_MAX_CONNECTION_AGE_MS,
+ MAX_CONNECTION_AGE_INTEGER_OPTIONS) != INT_MAX ||
+ grpc_channel_args_get_integer(
+ channel_args, GRPC_ARG_MAX_CONNECTION_IDLE_MS,
+ MAX_CONNECTION_IDLE_INTEGER_OPTIONS) != INT_MAX;
if (enable) {
return grpc_channel_stack_builder_prepend_filter(
builder, &grpc_max_age_filter, nullptr, nullptr);
diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc
index c7fc3f2e62..9815c93145 100644
--- a/src/core/ext/filters/message_size/message_size_filter.cc
+++ b/src/core/ext/filters/message_size/message_size_filter.cc
@@ -254,9 +254,8 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem,
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
chand->limits = get_message_size_limits(args->channel_args);
// Get method config table from channel args.
- const grpc_arg* channel_arg =
- grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG);
- const char* service_config_str = grpc_channel_arg_get_string(channel_arg);
+ const char* service_config_str =
+ grpc_channel_args_get_string(args->channel_args, GRPC_ARG_SERVICE_CONFIG);
if (service_config_str != nullptr) {
grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config =
grpc_core::ServiceConfig::Create(service_config_str);
diff --git a/src/core/ext/transport/chttp2/client/authority.cc b/src/core/ext/transport/chttp2/client/authority.cc
index bad3153b01..e3ef47c199 100644
--- a/src/core/ext/transport/chttp2/client/authority.cc
+++ b/src/core/ext/transport/chttp2/client/authority.cc
@@ -28,9 +28,8 @@ grpc_channel_args* grpc_default_authority_add_if_not_present(
size_t num_new_args = 0;
grpc_core::UniquePtr<char> default_authority;
if (!has_default_authority) {
- const grpc_arg* server_uri_arg =
- grpc_channel_args_find(args, GRPC_ARG_SERVER_URI);
- const char* server_uri_str = grpc_channel_arg_get_string(server_uri_arg);
+ const char* server_uri_str =
+ grpc_channel_args_get_string(args, GRPC_ARG_SERVER_URI);
GPR_ASSERT(server_uri_str != nullptr);
default_authority =
grpc_core::ResolverRegistry::GetDefaultAuthority(server_uri_str);
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
index b95c9dae53..dfed824cd5 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
@@ -50,7 +50,7 @@ grpc_channel* grpc_insecure_channel_create_from_fd(
GPR_ASSERT(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == 0);
grpc_endpoint* client = grpc_tcp_client_create_from_fd(
- grpc_fd_create(fd, "client"), args, "fd-client");
+ grpc_fd_create(fd, "client", false), args, "fd-client");
grpc_transport* transport =
grpc_create_chttp2_transport(final_args, client, true);
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
index 5ce73a95d7..f49bd27b6c 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
@@ -64,9 +64,8 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args(
return nullptr;
}
// To which address are we connecting? By default, use the server URI.
- const grpc_arg* server_uri_arg =
- grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI);
- const char* server_uri_str = grpc_channel_arg_get_string(server_uri_arg);
+ const char* server_uri_str =
+ grpc_channel_args_get_string(args->args, GRPC_ARG_SERVER_URI);
GPR_ASSERT(server_uri_str != nullptr);
grpc_uri* server_uri =
grpc_uri_parse(server_uri_str, true /* supress errors */);
diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
index 371e463814..a0228785ee 100644
--- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
+++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
@@ -43,8 +43,9 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server,
char* name;
gpr_asprintf(&name, "fd:%d", fd);
- grpc_endpoint* server_endpoint = grpc_tcp_create(
- grpc_fd_create(fd, name), grpc_server_get_channel_args(server), name);
+ grpc_endpoint* server_endpoint =
+ grpc_tcp_create(grpc_fd_create(fd, name, false),
+ grpc_server_get_channel_args(server), name);
gpr_free(name);
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
index cc4a823798..1a924e66e6 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
@@ -447,20 +447,19 @@ static void init_transport(grpc_chttp2_transport* t,
grpc_channel_arg_get_integer(&channel_args->args[i], {0, 0, 1}));
} else if (0 == strcmp(channel_args->args[i].key,
GRPC_ARG_OPTIMIZATION_TARGET)) {
- if (channel_args->args[i].type != GRPC_ARG_STRING) {
- gpr_log(GPR_ERROR, "%s should be a string",
- GRPC_ARG_OPTIMIZATION_TARGET);
- } else if (0 == strcmp(channel_args->args[i].value.string, "blend")) {
+ char* opt_target_str =
+ grpc_channel_arg_get_string(&channel_args->args[i]);
+ if (opt_target_str == nullptr) {
+ gpr_log(GPR_ERROR, "null/missing value opt target, assuming 'blend'");
+ } else if (0 == strcmp(opt_target_str, "blend")) {
t->opt_target = GRPC_CHTTP2_OPTIMIZE_FOR_LATENCY;
- } else if (0 == strcmp(channel_args->args[i].value.string, "latency")) {
+ } else if (0 == strcmp(opt_target_str, "latency")) {
t->opt_target = GRPC_CHTTP2_OPTIMIZE_FOR_LATENCY;
- } else if (0 ==
- strcmp(channel_args->args[i].value.string, "throughput")) {
+ } else if (0 == strcmp(opt_target_str, "throughput")) {
t->opt_target = GRPC_CHTTP2_OPTIMIZE_FOR_THROUGHPUT;
} else {
gpr_log(GPR_ERROR, "%s value '%s' unknown, assuming 'blend'",
- GRPC_ARG_OPTIMIZATION_TARGET,
- channel_args->args[i].value.string);
+ GRPC_ARG_OPTIMIZATION_TARGET, opt_target_str);
}
} else {
static const struct {
@@ -1451,10 +1450,8 @@ static void perform_stream_op_locked(void* stream_op,
}
}
if (op_payload->send_initial_metadata.peer_string != nullptr) {
- char* old_peer_string = (char*)gpr_atm_full_xchg(
- op_payload->send_initial_metadata.peer_string,
- (gpr_atm)gpr_strdup(t->peer_string));
- gpr_free(old_peer_string);
+ gpr_atm_rel_store(op_payload->send_initial_metadata.peer_string,
+ (gpr_atm)t->peer_string);
}
}
@@ -1569,10 +1566,8 @@ static void perform_stream_op_locked(void* stream_op,
s->trailing_metadata_available =
op_payload->recv_initial_metadata.trailing_metadata_available;
if (op_payload->recv_initial_metadata.peer_string != nullptr) {
- char* old_peer_string = (char*)gpr_atm_full_xchg(
- op_payload->recv_initial_metadata.peer_string,
- (gpr_atm)gpr_strdup(t->peer_string));
- gpr_free(old_peer_string);
+ gpr_atm_rel_store(op_payload->recv_initial_metadata.peer_string,
+ (gpr_atm)t->peer_string);
}
grpc_chttp2_maybe_complete_recv_initial_metadata(t, s);
}
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
index d5ef063883..0eaf63f133 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
@@ -41,14 +41,18 @@
#include "src/core/lib/transport/static_metadata.h"
#include "src/core/lib/transport/timeout_encoding.h"
-#define HASH_FRAGMENT_1(x) ((x)&255)
-#define HASH_FRAGMENT_2(x) ((x >> 8) & 255)
-#define HASH_FRAGMENT_3(x) ((x >> 16) & 255)
-#define HASH_FRAGMENT_4(x) ((x >> 24) & 255)
+#define HASH_FRAGMENT_MASK (GRPC_CHTTP2_HPACKC_NUM_VALUES - 1)
+#define HASH_FRAGMENT_1(x) ((x)&HASH_FRAGMENT_MASK)
+#define HASH_FRAGMENT_2(x) \
+ (((x) >> GRPC_CHTTP2_HPACKC_NUM_VALUES_BITS) & HASH_FRAGMENT_MASK)
+#define HASH_FRAGMENT_3(x) \
+ (((x) >> (GRPC_CHTTP2_HPACKC_NUM_VALUES_BITS * 2)) & HASH_FRAGMENT_MASK)
+#define HASH_FRAGMENT_4(x) \
+ (((x) >> (GRPC_CHTTP2_HPACKC_NUM_VALUES_BITS * 3)) & HASH_FRAGMENT_MASK)
/* if the probability of this item being seen again is < 1/x then don't add
it to the table */
-#define ONE_ON_ADD_PROBABILITY 128
+#define ONE_ON_ADD_PROBABILITY (GRPC_CHTTP2_HPACKC_NUM_VALUES >> 1)
/* don't consider adding anything bigger than this to the hpack table */
#define MAX_DECODER_SPACE_USAGE 512
@@ -135,7 +139,7 @@ static void inc_filter(uint8_t idx, uint32_t* sum, uint8_t* elems) {
} else {
int i;
*sum = 0;
- for (i = 0; i < GRPC_CHTTP2_HPACKC_NUM_FILTERS; i++) {
+ for (i = 0; i < GRPC_CHTTP2_HPACKC_NUM_VALUES; i++) {
elems[i] /= 2;
(*sum) += elems[i];
}
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
index b370932131..e31a7399d7 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
@@ -28,8 +28,9 @@
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/transport.h"
-#define GRPC_CHTTP2_HPACKC_NUM_FILTERS 256
-#define GRPC_CHTTP2_HPACKC_NUM_VALUES 256
+// This should be <= 8. We use 6 to save space.
+#define GRPC_CHTTP2_HPACKC_NUM_VALUES_BITS 6
+#define GRPC_CHTTP2_HPACKC_NUM_VALUES (1 << GRPC_CHTTP2_HPACKC_NUM_VALUES_BITS)
/* initial table size, per spec */
#define GRPC_CHTTP2_HPACKC_INITIAL_TABLE_SIZE 4096
/* maximum table size we'll actually use */
@@ -58,7 +59,7 @@ typedef struct {
a new literal should be added to the compression table or not.
They track a single integer that counts how often a particular value has
been seen. When that count reaches max (255), all values are halved. */
- uint8_t filter_elems[GRPC_CHTTP2_HPACKC_NUM_FILTERS];
+ uint8_t filter_elems[GRPC_CHTTP2_HPACKC_NUM_VALUES];
/* entry tables for keys & elems: these tables track values that have been
seen and *may* be in the decompressor table */
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc
index 420c2d13e1..5d614c1d05 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.cc
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc
@@ -1450,20 +1450,8 @@ grpc_transport* grpc_create_cronet_transport(void* engine, const char* target,
}
strcpy(ct->host, target);
- ct->use_packet_coalescing = true;
- if (args) {
- for (size_t i = 0; i < args->num_args; i++) {
- if (0 ==
- strcmp(args->args[i].key, GRPC_ARG_USE_CRONET_PACKET_COALESCING)) {
- if (GPR_UNLIKELY(args->args[i].type != GRPC_ARG_INTEGER)) {
- gpr_log(GPR_ERROR, "%s ignored: it must be an integer",
- GRPC_ARG_USE_CRONET_PACKET_COALESCING);
- } else {
- ct->use_packet_coalescing = (args->args[i].value.integer != 0);
- }
- }
- }
- }
+ ct->use_packet_coalescing = grpc_channel_args_get_bool(
+ args, GRPC_ARG_USE_CRONET_PACKET_COALESCING, true);
return &ct->base;
diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc
index 2c3bff5c1e..6e5aa5a46b 100644
--- a/src/core/ext/transport/inproc/inproc_transport.cc
+++ b/src/core/ext/transport/inproc/inproc_transport.cc
@@ -1204,10 +1204,9 @@ grpc_channel* grpc_inproc_channel_create(grpc_server* server,
// Add a default authority channel argument for the client
- grpc_arg default_authority_arg;
- default_authority_arg.type = GRPC_ARG_STRING;
- default_authority_arg.key = (char*)GRPC_ARG_DEFAULT_AUTHORITY;
- default_authority_arg.value.string = (char*)"inproc.authority";
+ grpc_arg default_authority_arg = grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY),
+ const_cast<char*>("inproc.authority"));
grpc_channel_args* client_args =
grpc_channel_args_copy_and_add(args, &default_authority_arg, 1);
diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h
index 5ff303a9dc..0c4f56a688 100644
--- a/src/core/lib/channel/channel_args.h
+++ b/src/core/lib/channel/channel_args.h
@@ -23,6 +23,7 @@
#include <grpc/compression.h>
#include <grpc/grpc.h>
+#include <grpc/support/log.h>
#include "src/core/lib/iomgr/socket_mutator.h"
// Channel args are intentionally immutable, to avoid the need for locking.
@@ -110,13 +111,49 @@ typedef struct grpc_integer_options {
/** Returns the value of \a arg, subject to the contraints in \a options. */
int grpc_channel_arg_get_integer(const grpc_arg* arg,
const grpc_integer_options options);
+/** convinience helper for the above that finds the arg first. */
+inline int grpc_channel_args_get_integer(const grpc_channel_args* args,
+ const char* name,
+ const grpc_integer_options options) {
+ return grpc_channel_arg_get_integer(grpc_channel_args_find(args, name),
+ options);
+}
/** Returns the value of \a arg if \a arg is of type GRPC_ARG_STRING.
Otherwise, emits a warning log, and returns nullptr.
If arg is nullptr, returns nullptr, and does not emit a warning. */
char* grpc_channel_arg_get_string(const grpc_arg* arg);
+/** convinience helper for the above that finds the arg first. */
+inline char* grpc_channel_args_get_string(const grpc_channel_args* args,
+ const char* name) {
+ return grpc_channel_arg_get_string(grpc_channel_args_find(args, name));
+}
+
+/** Returns the value of \a arg if \a arg is of type GRPC_ARG_POINTER
+ Otherwise, emits a warning log, and returns nullptr.
+ If arg is nullptr, returns nullptr, and does not emit a warning. */
+template <typename Type>
+inline Type* grpc_channel_arg_get_pointer(const grpc_arg* arg) {
+ if (arg == nullptr) return nullptr;
+ if (arg->type != GRPC_ARG_POINTER) {
+ gpr_log(GPR_ERROR, "%s ignored: it must be an pointer", arg->key);
+ return nullptr;
+ }
+ return static_cast<Type*>(arg->value.pointer.p);
+}
+/** convinience helper for the above that finds the arg first. */
+template <typename Type>
+inline Type* grpc_channel_args_get_pointer(const grpc_channel_args* args,
+ const char* name) {
+ return grpc_channel_arg_get_pointer<Type>(grpc_channel_args_find(args, name));
+}
bool grpc_channel_arg_get_bool(const grpc_arg* arg, bool default_value);
+inline bool grpc_channel_args_get_bool(const grpc_channel_args* args,
+ const char* name, bool default_value) {
+ return grpc_channel_arg_get_bool(grpc_channel_args_find(args, name),
+ default_value);
+}
// Helpers for creating channel args.
grpc_arg grpc_channel_arg_string_create(char* name, char* value);
diff --git a/src/core/lib/channel/handshaker.cc b/src/core/lib/channel/handshaker.cc
index 86f8699e04..ad3250b7e9 100644
--- a/src/core/lib/channel/handshaker.cc
+++ b/src/core/lib/channel/handshaker.cc
@@ -223,18 +223,23 @@ static bool call_next_handshaker_locked(grpc_handshake_manager* mgr,
mgr->index == mgr->count) {
if (error == GRPC_ERROR_NONE && mgr->shutdown) {
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("handshaker shutdown");
- // TODO(roth): It is currently necessary to shutdown endpoints
- // before destroying then, even when we know that there are no
- // pending read/write callbacks. This should be fixed, at which
- // point this can be removed.
- grpc_endpoint_shutdown(mgr->args.endpoint, GRPC_ERROR_REF(error));
- grpc_endpoint_destroy(mgr->args.endpoint);
- mgr->args.endpoint = nullptr;
- grpc_channel_args_destroy(mgr->args.args);
- mgr->args.args = nullptr;
- grpc_slice_buffer_destroy_internal(mgr->args.read_buffer);
- gpr_free(mgr->args.read_buffer);
- mgr->args.read_buffer = nullptr;
+ // It is possible that the endpoint has already been destroyed by
+ // a shutdown call while this callback was sitting on the ExecCtx
+ // with no error.
+ if (mgr->args.endpoint != nullptr) {
+ // TODO(roth): It is currently necessary to shutdown endpoints
+ // before destroying then, even when we know that there are no
+ // pending read/write callbacks. This should be fixed, at which
+ // point this can be removed.
+ grpc_endpoint_shutdown(mgr->args.endpoint, GRPC_ERROR_REF(error));
+ grpc_endpoint_destroy(mgr->args.endpoint);
+ mgr->args.endpoint = nullptr;
+ grpc_channel_args_destroy(mgr->args.args);
+ mgr->args.args = nullptr;
+ grpc_slice_buffer_destroy_internal(mgr->args.read_buffer);
+ gpr_free(mgr->args.read_buffer);
+ mgr->args.read_buffer = nullptr;
+ }
}
if (grpc_handshaker_trace.enabled()) {
gpr_log(GPR_INFO,
diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc
new file mode 100644
index 0000000000..827fd24831
--- /dev/null
+++ b/src/core/lib/iomgr/cfstream_handle.cc
@@ -0,0 +1,185 @@
+/*
+ *
+ * Copyright 2018 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/iomgr/port.h"
+
+#ifdef GRPC_CFSTREAM
+#import <CoreFoundation/CoreFoundation.h>
+#import "src/core/lib/iomgr/cfstream_handle.h"
+
+#include <grpc/support/atm.h>
+#include <grpc/support/sync.h>
+
+#include "src/core/lib/debug/trace.h"
+#include "src/core/lib/iomgr/closure.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+
+extern grpc_core::TraceFlag grpc_tcp_trace;
+
+void* CFStreamHandle::Retain(void* info) {
+ CFStreamHandle* handle = static_cast<CFStreamHandle*>(info);
+ CFSTREAM_HANDLE_REF(handle, "retain");
+ return info;
+}
+
+void CFStreamHandle::Release(void* info) {
+ CFStreamHandle* handle = static_cast<CFStreamHandle*>(info);
+ CFSTREAM_HANDLE_UNREF(handle, "release");
+}
+
+CFStreamHandle* CFStreamHandle::CreateStreamHandle(
+ CFReadStreamRef read_stream, CFWriteStreamRef write_stream) {
+ return new CFStreamHandle(read_stream, write_stream);
+}
+
+void CFStreamHandle::ReadCallback(CFReadStreamRef stream,
+ CFStreamEventType type,
+ void* client_callback_info) {
+ CFStreamHandle* handle = static_cast<CFStreamHandle*>(client_callback_info);
+ CFSTREAM_HANDLE_REF(handle, "read callback");
+ dispatch_async(
+ dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ grpc_core::ExecCtx exec_ctx;
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "CFStream ReadCallback (%p, %p, %lu, %p)", handle,
+ stream, type, client_callback_info);
+ }
+ switch (type) {
+ case kCFStreamEventOpenCompleted:
+ handle->open_event_.SetReady();
+ break;
+ case kCFStreamEventHasBytesAvailable:
+ case kCFStreamEventEndEncountered:
+ handle->read_event_.SetReady();
+ break;
+ case kCFStreamEventErrorOccurred:
+ handle->open_event_.SetReady();
+ handle->read_event_.SetReady();
+ break;
+ default:
+ GPR_UNREACHABLE_CODE(return );
+ }
+ CFSTREAM_HANDLE_UNREF(handle, "read callback");
+ });
+}
+void CFStreamHandle::WriteCallback(CFWriteStreamRef stream,
+ CFStreamEventType type,
+ void* clientCallBackInfo) {
+ CFStreamHandle* handle = static_cast<CFStreamHandle*>(clientCallBackInfo);
+ CFSTREAM_HANDLE_REF(handle, "write callback");
+ dispatch_async(
+ dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ grpc_core::ExecCtx exec_ctx;
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "CFStream WriteCallback (%p, %p, %lu, %p)", handle,
+ stream, type, clientCallBackInfo);
+ }
+ switch (type) {
+ case kCFStreamEventOpenCompleted:
+ handle->open_event_.SetReady();
+ break;
+ case kCFStreamEventCanAcceptBytes:
+ case kCFStreamEventEndEncountered:
+ handle->write_event_.SetReady();
+ break;
+ case kCFStreamEventErrorOccurred:
+ handle->open_event_.SetReady();
+ handle->write_event_.SetReady();
+ break;
+ default:
+ GPR_UNREACHABLE_CODE(return );
+ }
+ CFSTREAM_HANDLE_UNREF(handle, "write callback");
+ });
+}
+
+CFStreamHandle::CFStreamHandle(CFReadStreamRef read_stream,
+ CFWriteStreamRef write_stream) {
+ gpr_ref_init(&refcount_, 1);
+ open_event_.InitEvent();
+ read_event_.InitEvent();
+ write_event_.InitEvent();
+ CFStreamClientContext ctx = {0, static_cast<void*>(this),
+ CFStreamHandle::Retain, CFStreamHandle::Release,
+ nil};
+ CFReadStreamSetClient(
+ read_stream,
+ kCFStreamEventOpenCompleted | kCFStreamEventHasBytesAvailable |
+ kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered,
+ CFStreamHandle::ReadCallback, &ctx);
+ CFWriteStreamSetClient(
+ write_stream,
+ kCFStreamEventOpenCompleted | kCFStreamEventCanAcceptBytes |
+ kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered,
+ CFStreamHandle::WriteCallback, &ctx);
+ CFReadStreamScheduleWithRunLoop(read_stream, CFRunLoopGetMain(),
+ kCFRunLoopCommonModes);
+ CFWriteStreamScheduleWithRunLoop(write_stream, CFRunLoopGetMain(),
+ kCFRunLoopCommonModes);
+}
+
+CFStreamHandle::~CFStreamHandle() {
+ open_event_.DestroyEvent();
+ read_event_.DestroyEvent();
+ write_event_.DestroyEvent();
+}
+
+void CFStreamHandle::NotifyOnOpen(grpc_closure* closure) {
+ open_event_.NotifyOn(closure);
+}
+
+void CFStreamHandle::NotifyOnRead(grpc_closure* closure) {
+ read_event_.NotifyOn(closure);
+}
+
+void CFStreamHandle::NotifyOnWrite(grpc_closure* closure) {
+ write_event_.NotifyOn(closure);
+}
+
+void CFStreamHandle::Shutdown(grpc_error* error) {
+ open_event_.SetShutdown(GRPC_ERROR_REF(error));
+ read_event_.SetShutdown(GRPC_ERROR_REF(error));
+ write_event_.SetShutdown(GRPC_ERROR_REF(error));
+ GRPC_ERROR_UNREF(error);
+}
+
+void CFStreamHandle::Ref(const char* file, int line, const char* reason) {
+ if (grpc_tcp_trace.enabled()) {
+ gpr_atm val = gpr_atm_no_barrier_load(&refcount_.count);
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
+ "CFStream Handle ref %p : %s %" PRIdPTR " -> %" PRIdPTR, this,
+ reason, val, val + 1);
+ }
+ gpr_ref(&refcount_);
+}
+
+void CFStreamHandle::Unref(const char* file, int line, const char* reason) {
+ if (grpc_tcp_trace.enabled()) {
+ gpr_atm val = gpr_atm_no_barrier_load(&refcount_.count);
+ gpr_log(GPR_ERROR,
+ "CFStream Handle unref %p : %s %" PRIdPTR " -> %" PRIdPTR, this,
+ reason, val, val - 1);
+ }
+ if (gpr_unref(&refcount_)) {
+ delete this;
+ }
+}
+
+#endif
diff --git a/src/core/lib/iomgr/cfstream_handle.h b/src/core/lib/iomgr/cfstream_handle.h
new file mode 100644
index 0000000000..4258e72431
--- /dev/null
+++ b/src/core/lib/iomgr/cfstream_handle.h
@@ -0,0 +1,80 @@
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+
+/* The CFStream handle acts as an event synchronization entity for
+ * read/write/open/error/eos events happening on CFStream streams. */
+
+#ifndef GRPC_CORE_LIB_IOMGR_CFSTREAM_HANDLE_H
+#define GRPC_CORE_LIB_IOMGR_CFSTREAM_HANDLE_H
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/iomgr/port.h"
+
+#ifdef GRPC_CFSTREAM
+#import <CoreFoundation/CoreFoundation.h>
+
+#include "src/core/lib/iomgr/closure.h"
+#include "src/core/lib/iomgr/lockfree_event.h"
+
+class CFStreamHandle final {
+ public:
+ static CFStreamHandle* CreateStreamHandle(CFReadStreamRef read_stream,
+ CFWriteStreamRef write_stream);
+ ~CFStreamHandle();
+ CFStreamHandle(const CFReadStreamRef& ref) = delete;
+ CFStreamHandle(CFReadStreamRef&& ref) = delete;
+ CFStreamHandle& operator=(const CFStreamHandle& rhs) = delete;
+
+ void NotifyOnOpen(grpc_closure* closure);
+ void NotifyOnRead(grpc_closure* closure);
+ void NotifyOnWrite(grpc_closure* closure);
+ void Shutdown(grpc_error* error);
+
+ void Ref(const char* file = "", int line = 0, const char* reason = nullptr);
+ void Unref(const char* file = "", int line = 0, const char* reason = nullptr);
+
+ private:
+ CFStreamHandle(CFReadStreamRef read_stream, CFWriteStreamRef write_stream);
+ static void ReadCallback(CFReadStreamRef stream, CFStreamEventType type,
+ void* client_callback_info);
+ static void WriteCallback(CFWriteStreamRef stream, CFStreamEventType type,
+ void* client_callback_info);
+ static void* Retain(void* info);
+ static void Release(void* info);
+
+ grpc_core::LockfreeEvent open_event_;
+ grpc_core::LockfreeEvent read_event_;
+ grpc_core::LockfreeEvent write_event_;
+
+ gpr_refcount refcount_;
+};
+
+#ifdef DEBUG
+#define CFSTREAM_HANDLE_REF(handle, reason) \
+ (handle)->Ref(__FILE__, __LINE__, (reason))
+#define CFSTREAM_HANDLE_UNREF(handle, reason) \
+ (handle)->Unref(__FILE__, __LINE__, (reason))
+#else
+#define CFSTREAM_HANDLE_REF(handle, reason) (handle)->Ref()
+#define CFSTREAM_HANDLE_UNREF(handle, reason) (handle)->Unref()
+#endif
+
+#endif
+
+#endif /* GRPC_CORE_LIB_IOMGR_CFSTREAM_HANDLE_H */
diff --git a/src/core/lib/iomgr/endpoint_cfstream.cc b/src/core/lib/iomgr/endpoint_cfstream.cc
new file mode 100644
index 0000000000..c3bc0cc8fd
--- /dev/null
+++ b/src/core/lib/iomgr/endpoint_cfstream.cc
@@ -0,0 +1,372 @@
+/*
+ *
+ * Copyright 2018 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/iomgr/port.h"
+
+#ifdef GRPC_CFSTREAM_ENDPOINT
+
+#import <CoreFoundation/CoreFoundation.h>
+#import "src/core/lib/iomgr/endpoint_cfstream.h"
+
+#include <grpc/slice_buffer.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/iomgr/cfstream_handle.h"
+#include "src/core/lib/iomgr/closure.h"
+#include "src/core/lib/iomgr/endpoint.h"
+#include "src/core/lib/iomgr/error_cfstream.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
+
+extern grpc_core::TraceFlag grpc_tcp_trace;
+
+typedef struct {
+ grpc_endpoint base;
+ gpr_refcount refcount;
+
+ CFReadStreamRef read_stream;
+ CFWriteStreamRef write_stream;
+ CFStreamHandle* stream_sync;
+
+ grpc_closure* read_cb;
+ grpc_closure* write_cb;
+ grpc_slice_buffer* read_slices;
+ grpc_slice_buffer* write_slices;
+
+ grpc_closure read_action;
+ grpc_closure write_action;
+
+ char* peer_string;
+ grpc_resource_user* resource_user;
+ grpc_resource_user_slice_allocator slice_allocator;
+} CFStreamEndpoint;
+
+static void CFStreamFree(CFStreamEndpoint* ep) {
+ grpc_resource_user_unref(ep->resource_user);
+ CFRelease(ep->read_stream);
+ CFRelease(ep->write_stream);
+ CFSTREAM_HANDLE_UNREF(ep->stream_sync, "free");
+ gpr_free(ep->peer_string);
+ gpr_free(ep);
+}
+
+#ifndef NDEBUG
+#define EP_REF(ep, reason) CFStreamRef((ep), (reason), __FILE__, __LINE__)
+#define EP_UNREF(ep, reason) CFStreamUnref((ep), (reason), __FILE__, __LINE__)
+static void CFStreamUnref(CFStreamEndpoint* ep, const char* reason,
+ const char* file, int line) {
+ if (grpc_tcp_trace.enabled()) {
+ gpr_atm val = gpr_atm_no_barrier_load(&ep->refcount.count);
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
+ "CFStream endpoint unref %p : %s %" PRIdPTR " -> %" PRIdPTR, ep,
+ reason, val, val - 1);
+ }
+ if (gpr_unref(&ep->refcount)) {
+ CFStreamFree(ep);
+ }
+}
+static void CFStreamRef(CFStreamEndpoint* ep, const char* reason,
+ const char* file, int line) {
+ if (grpc_tcp_trace.enabled()) {
+ gpr_atm val = gpr_atm_no_barrier_load(&ep->refcount.count);
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
+ "CFStream endpoint ref %p : %s %" PRIdPTR " -> %" PRIdPTR, ep,
+ reason, val, val + 1);
+ }
+ gpr_ref(&ep->refcount);
+}
+#else
+#define EP_REF(ep, reason) CFStreamRef((ep))
+#define EP_UNREF(ep, reason) CFStreamUnref((ep))
+static void CFStreamUnref(CFStreamEndpoint* ep) {
+ if (gpr_unref(&ep->refcount)) {
+ CFStreamFree(ep);
+ }
+}
+static void CFStreamRef(CFStreamEndpoint* ep) { gpr_ref(&ep->refcount); }
+#endif
+
+static grpc_error* CFStreamAnnotateError(grpc_error* src_error,
+ CFStreamEndpoint* ep) {
+ return grpc_error_set_str(
+ grpc_error_set_int(src_error, GRPC_ERROR_INT_GRPC_STATUS,
+ GRPC_STATUS_UNAVAILABLE),
+ GRPC_ERROR_STR_TARGET_ADDRESS,
+ grpc_slice_from_copied_string(ep->peer_string));
+}
+
+static void CallReadCb(CFStreamEndpoint* ep, grpc_error* error) {
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "CFStream endpoint:%p call_read_cb %p %p:%p", ep,
+ ep->read_cb, ep->read_cb->cb, ep->read_cb->cb_arg);
+ size_t i;
+ const char* str = grpc_error_string(error);
+ gpr_log(GPR_DEBUG, "read: error=%s", str);
+
+ for (i = 0; i < ep->read_slices->count; i++) {
+ char* dump = grpc_dump_slice(ep->read_slices->slices[i],
+ GPR_DUMP_HEX | GPR_DUMP_ASCII);
+ gpr_log(GPR_DEBUG, "READ %p (peer=%s): %s", ep, ep->peer_string, dump);
+ gpr_free(dump);
+ }
+ }
+ grpc_closure* cb = ep->read_cb;
+ ep->read_cb = nullptr;
+ ep->read_slices = nullptr;
+ GRPC_CLOSURE_SCHED(cb, error);
+}
+
+static void CallWriteCb(CFStreamEndpoint* ep, grpc_error* error) {
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "CFStream endpoint:%p call_write_cb %p %p:%p", ep,
+ ep->write_cb, ep->write_cb->cb, ep->write_cb->cb_arg);
+ const char* str = grpc_error_string(error);
+ gpr_log(GPR_DEBUG, "write: error=%s", str);
+ }
+ grpc_closure* cb = ep->write_cb;
+ ep->write_cb = nullptr;
+ ep->write_slices = nullptr;
+ GRPC_CLOSURE_SCHED(cb, error);
+}
+
+static void ReadAction(void* arg, grpc_error* error) {
+ CFStreamEndpoint* ep = static_cast<CFStreamEndpoint*>(arg);
+ GPR_ASSERT(ep->read_cb != nullptr);
+ if (error) {
+ grpc_slice_buffer_reset_and_unref_internal(ep->read_slices);
+ CallReadCb(ep, GRPC_ERROR_REF(error));
+ EP_UNREF(ep, "read");
+ return;
+ }
+
+ GPR_ASSERT(ep->read_slices->count == 1);
+ grpc_slice slice = ep->read_slices->slices[0];
+ size_t len = GRPC_SLICE_LENGTH(slice);
+ CFIndex read_size =
+ CFReadStreamRead(ep->read_stream, GRPC_SLICE_START_PTR(slice), len);
+ if (read_size == -1) {
+ grpc_slice_buffer_reset_and_unref_internal(ep->read_slices);
+ CFErrorRef stream_error = CFReadStreamCopyError(ep->read_stream);
+ if (stream_error != nullptr) {
+ error = CFStreamAnnotateError(
+ GRPC_ERROR_CREATE_FROM_CFERROR(stream_error, "Read error"), ep);
+ CFRelease(stream_error);
+ } else {
+ error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Read error");
+ }
+ CallReadCb(ep, error);
+ EP_UNREF(ep, "read");
+ } else if (read_size == 0) {
+ grpc_slice_buffer_reset_and_unref_internal(ep->read_slices);
+ CallReadCb(ep,
+ CFStreamAnnotateError(
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Socket closed"), ep));
+ EP_UNREF(ep, "read");
+ } else {
+ if (read_size < len) {
+ grpc_slice_buffer_trim_end(ep->read_slices, len - read_size, nullptr);
+ }
+ CallReadCb(ep, GRPC_ERROR_NONE);
+ EP_UNREF(ep, "read");
+ }
+}
+
+static void WriteAction(void* arg, grpc_error* error) {
+ CFStreamEndpoint* ep = static_cast<CFStreamEndpoint*>(arg);
+ GPR_ASSERT(ep->write_cb != nullptr);
+ if (error) {
+ grpc_slice_buffer_reset_and_unref_internal(ep->write_slices);
+ CallWriteCb(ep, GRPC_ERROR_REF(error));
+ EP_UNREF(ep, "write");
+ return;
+ }
+
+ grpc_slice slice = grpc_slice_buffer_take_first(ep->write_slices);
+ size_t slice_len = GRPC_SLICE_LENGTH(slice);
+ CFIndex write_size = CFWriteStreamWrite(
+ ep->write_stream, GRPC_SLICE_START_PTR(slice), slice_len);
+ if (write_size == -1) {
+ grpc_slice_buffer_reset_and_unref_internal(ep->write_slices);
+ CFErrorRef stream_error = CFWriteStreamCopyError(ep->write_stream);
+ if (stream_error != nullptr) {
+ error = CFStreamAnnotateError(
+ GRPC_ERROR_CREATE_FROM_CFERROR(stream_error, "write failed."), ep);
+ CFRelease(stream_error);
+ } else {
+ error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("write failed.");
+ }
+ CallWriteCb(ep, error);
+ EP_UNREF(ep, "write");
+ } else {
+ if (write_size < GRPC_SLICE_LENGTH(slice)) {
+ grpc_slice_buffer_undo_take_first(
+ ep->write_slices, grpc_slice_sub(slice, write_size, slice_len));
+ }
+ if (ep->write_slices->length > 0) {
+ ep->stream_sync->NotifyOnWrite(&ep->write_action);
+ } else {
+ CallWriteCb(ep, GRPC_ERROR_NONE);
+ EP_UNREF(ep, "write");
+ }
+
+ if (grpc_tcp_trace.enabled()) {
+ grpc_slice trace_slice = grpc_slice_sub(slice, 0, write_size);
+ char* dump = grpc_dump_slice(trace_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
+ gpr_log(GPR_DEBUG, "WRITE %p (peer=%s): %s", ep, ep->peer_string, dump);
+ gpr_free(dump);
+ grpc_slice_unref_internal(trace_slice);
+ }
+ }
+ grpc_slice_unref_internal(slice);
+}
+
+static void CFStreamReadAllocationDone(void* arg, grpc_error* error) {
+ CFStreamEndpoint* ep = static_cast<CFStreamEndpoint*>(arg);
+ if (error == GRPC_ERROR_NONE) {
+ ep->stream_sync->NotifyOnRead(&ep->read_action);
+ } else {
+ grpc_slice_buffer_reset_and_unref_internal(ep->read_slices);
+ CallReadCb(ep, error);
+ EP_UNREF(ep, "read");
+ }
+}
+
+static void CFStreamRead(grpc_endpoint* ep, grpc_slice_buffer* slices,
+ grpc_closure* cb) {
+ CFStreamEndpoint* ep_impl = reinterpret_cast<CFStreamEndpoint*>(ep);
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "CFStream endpoint:%p read (%p, %p) length:%zu", ep_impl,
+ slices, cb, slices->length);
+ }
+ GPR_ASSERT(ep_impl->read_cb == nullptr);
+ ep_impl->read_cb = cb;
+ ep_impl->read_slices = slices;
+ grpc_slice_buffer_reset_and_unref_internal(slices);
+ grpc_resource_user_alloc_slices(&ep_impl->slice_allocator,
+ GRPC_TCP_DEFAULT_READ_SLICE_SIZE, 1,
+ ep_impl->read_slices);
+ EP_REF(ep_impl, "read");
+}
+
+static void CFStreamWrite(grpc_endpoint* ep, grpc_slice_buffer* slices,
+ grpc_closure* cb) {
+ CFStreamEndpoint* ep_impl = reinterpret_cast<CFStreamEndpoint*>(ep);
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "CFStream endpoint:%p write (%p, %p) length:%zu",
+ ep_impl, slices, cb, slices->length);
+ }
+ GPR_ASSERT(ep_impl->write_cb == nullptr);
+ ep_impl->write_cb = cb;
+ ep_impl->write_slices = slices;
+ EP_REF(ep_impl, "write");
+ ep_impl->stream_sync->NotifyOnWrite(&ep_impl->write_action);
+}
+
+void CFStreamShutdown(grpc_endpoint* ep, grpc_error* why) {
+ CFStreamEndpoint* ep_impl = reinterpret_cast<CFStreamEndpoint*>(ep);
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "CFStream endpoint:%p shutdown (%p)", ep_impl, why);
+ }
+ CFReadStreamClose(ep_impl->read_stream);
+ CFWriteStreamClose(ep_impl->write_stream);
+ ep_impl->stream_sync->Shutdown(why);
+ grpc_resource_user_shutdown(ep_impl->resource_user);
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "CFStream endpoint:%p shutdown DONE (%p)", ep_impl, why);
+ }
+}
+
+void CFStreamDestroy(grpc_endpoint* ep) {
+ CFStreamEndpoint* ep_impl = reinterpret_cast<CFStreamEndpoint*>(ep);
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "CFStream endpoint:%p destroy", ep_impl);
+ }
+ EP_UNREF(ep_impl, "destroy");
+}
+
+grpc_resource_user* CFStreamGetResourceUser(grpc_endpoint* ep) {
+ CFStreamEndpoint* ep_impl = reinterpret_cast<CFStreamEndpoint*>(ep);
+ return ep_impl->resource_user;
+}
+
+char* CFStreamGetPeer(grpc_endpoint* ep) {
+ CFStreamEndpoint* ep_impl = reinterpret_cast<CFStreamEndpoint*>(ep);
+ return gpr_strdup(ep_impl->peer_string);
+}
+
+int CFStreamGetFD(grpc_endpoint* ep) { return 0; }
+
+void CFStreamAddToPollset(grpc_endpoint* ep, grpc_pollset* pollset) {}
+void CFStreamAddToPollsetSet(grpc_endpoint* ep, grpc_pollset_set* pollset) {}
+void CFStreamDeleteFromPollsetSet(grpc_endpoint* ep,
+ grpc_pollset_set* pollset) {}
+
+static const grpc_endpoint_vtable vtable = {CFStreamRead,
+ CFStreamWrite,
+ CFStreamAddToPollset,
+ CFStreamAddToPollsetSet,
+ CFStreamDeleteFromPollsetSet,
+ CFStreamShutdown,
+ CFStreamDestroy,
+ CFStreamGetResourceUser,
+ CFStreamGetPeer,
+ CFStreamGetFD};
+
+grpc_endpoint* grpc_cfstream_endpoint_create(
+ CFReadStreamRef read_stream, CFWriteStreamRef write_stream,
+ const char* peer_string, grpc_resource_quota* resource_quota,
+ CFStreamHandle* stream_sync) {
+ CFStreamEndpoint* ep_impl =
+ static_cast<CFStreamEndpoint*>(gpr_malloc(sizeof(CFStreamEndpoint)));
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "CFStream endpoint:%p create readStream:%p writeStream: %p",
+ ep_impl, read_stream, write_stream);
+ }
+ ep_impl->base.vtable = &vtable;
+ gpr_ref_init(&ep_impl->refcount, 1);
+ ep_impl->read_stream = read_stream;
+ ep_impl->write_stream = write_stream;
+ CFRetain(read_stream);
+ CFRetain(write_stream);
+ ep_impl->stream_sync = stream_sync;
+ CFSTREAM_HANDLE_REF(ep_impl->stream_sync, "endpoint create");
+
+ ep_impl->peer_string = gpr_strdup(peer_string);
+ ep_impl->read_cb = nil;
+ ep_impl->write_cb = nil;
+ ep_impl->read_slices = nil;
+ ep_impl->write_slices = nil;
+ GRPC_CLOSURE_INIT(&ep_impl->read_action, ReadAction,
+ static_cast<void*>(ep_impl), grpc_schedule_on_exec_ctx);
+ GRPC_CLOSURE_INIT(&ep_impl->write_action, WriteAction,
+ static_cast<void*>(ep_impl), grpc_schedule_on_exec_ctx);
+ ep_impl->resource_user =
+ grpc_resource_user_create(resource_quota, peer_string);
+ grpc_resource_user_slice_allocator_init(&ep_impl->slice_allocator,
+ ep_impl->resource_user,
+ CFStreamReadAllocationDone, ep_impl);
+
+ return &ep_impl->base;
+}
+
+#endif /* GRPC_CFSTREAM_ENDPOINT */
diff --git a/src/core/lib/iomgr/endpoint_cfstream.h b/src/core/lib/iomgr/endpoint_cfstream.h
new file mode 100644
index 0000000000..ef957c1f11
--- /dev/null
+++ b/src/core/lib/iomgr/endpoint_cfstream.h
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_IOMGR_ENDPOINT_CFSTREAM_H
+#define GRPC_CORE_LIB_IOMGR_ENDPOINT_CFSTREAM_H
+/*
+ Low level TCP "bottom half" implementation, for use by transports built on
+ top of a TCP connection.
+
+ Note that this file does not (yet) include APIs for creating the socket in
+ the first place.
+
+ All calls passing slice transfer ownership of a slice refcount unless
+ otherwise specified.
+*/
+
+#include <grpc/support/port_platform.h>
+
+#ifdef GRPC_CFSTREAM
+
+#import <CoreFoundation/CoreFoundation.h>
+
+#include "src/core/lib/debug/trace.h"
+#include "src/core/lib/iomgr/cfstream_handle.h"
+#include "src/core/lib/iomgr/endpoint.h"
+
+grpc_endpoint* grpc_cfstream_endpoint_create(
+ CFReadStreamRef read_stream, CFWriteStreamRef write_stream,
+ const char* peer_string, grpc_resource_quota* resource_quota,
+ CFStreamHandle* stream_sync);
+
+#endif /* GRPC_CFSTREAM */
+
+#endif /* GRPC_CORE_LIB_IOMGR_ENDPOINT_CFSTREAM_H */
diff --git a/src/core/lib/iomgr/endpoint_pair_posix.cc b/src/core/lib/iomgr/endpoint_pair_posix.cc
index 49850ab3a1..5c5c246f99 100644
--- a/src/core/lib/iomgr/endpoint_pair_posix.cc
+++ b/src/core/lib/iomgr/endpoint_pair_posix.cc
@@ -59,11 +59,11 @@ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char* name,
grpc_core::ExecCtx exec_ctx;
gpr_asprintf(&final_name, "%s:client", name);
- p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name), args,
+ p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, false), args,
"socketpair-server");
gpr_free(final_name);
gpr_asprintf(&final_name, "%s:server", name);
- p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name), args,
+ p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, false), args,
"socketpair-client");
gpr_free(final_name);
diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc
index 4088cf612e..90ed34da11 100644
--- a/src/core/lib/iomgr/error.cc
+++ b/src/core/lib/iomgr/error.cc
@@ -312,6 +312,12 @@ static void internal_add_error(grpc_error** err, grpc_error* new_err) {
// It is very common to include and extra int and string in an error
#define SURPLUS_CAPACITY (2 * SLOTS_PER_INT + SLOTS_PER_TIME)
+static bool g_error_creation_allowed = true;
+
+void grpc_disable_error_creation() { g_error_creation_allowed = false; }
+
+void grpc_enable_error_creation() { g_error_creation_allowed = true; }
+
grpc_error* grpc_error_create(const char* file, int line, grpc_slice desc,
grpc_error** referencing,
size_t num_referencing) {
@@ -326,6 +332,12 @@ grpc_error* grpc_error_create(const char* file, int line, grpc_slice desc,
return GRPC_ERROR_OOM;
}
#ifndef NDEBUG
+ if (!g_error_creation_allowed) {
+ gpr_log(GPR_ERROR,
+ "Error creation occurred when error creation was disabled [%s:%d]",
+ file, line);
+ abort();
+ }
if (grpc_trace_error_refcount.enabled()) {
gpr_log(GPR_DEBUG, "%p create [%s:%d]", err, file, line);
}
diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h
index f8cae4da82..27c4d22fd1 100644
--- a/src/core/lib/iomgr/error.h
+++ b/src/core/lib/iomgr/error.h
@@ -123,6 +123,11 @@ typedef enum {
#define GRPC_ERROR_OOM ((grpc_error*)2)
#define GRPC_ERROR_CANCELLED ((grpc_error*)4)
+// debug only toggles that allow for a sanity to check that ensures we will
+// never create any errors in the per-RPC hotpath.
+void grpc_disable_error_creation();
+void grpc_enable_error_creation();
+
const char* grpc_error_string(grpc_error* error);
/// Create an error - but use GRPC_ERROR_CREATE instead
diff --git a/src/core/lib/iomgr/error_cfstream.cc b/src/core/lib/iomgr/error_cfstream.cc
new file mode 100644
index 0000000000..d7af8c377f
--- /dev/null
+++ b/src/core/lib/iomgr/error_cfstream.cc
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2018 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>
+
+#ifdef GRPC_CFSTREAM
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/lib/iomgr/error.h"
+
+#define MAX_ERROR_DESCRIPTION 256
+
+grpc_error* grpc_error_create_from_cferror(const char* file, int line,
+ void* arg, const char* custom_desc) {
+ CFErrorRef error = static_cast<CFErrorRef>(arg);
+ char buf_domain[MAX_ERROR_DESCRIPTION];
+ char buf_desc[MAX_ERROR_DESCRIPTION];
+ char* error_msg;
+ CFErrorDomain domain = CFErrorGetDomain((error));
+ CFIndex code = CFErrorGetCode((error));
+ CFStringRef desc = CFErrorCopyDescription((error));
+ CFStringGetCString(domain, buf_domain, MAX_ERROR_DESCRIPTION,
+ kCFStringEncodingUTF8);
+ CFStringGetCString(desc, buf_desc, MAX_ERROR_DESCRIPTION,
+ kCFStringEncodingUTF8);
+ gpr_asprintf(&error_msg, "%s (error domain:%s, code:%ld, description:%s)",
+ custom_desc, buf_domain, code, buf_desc);
+ CFRelease(desc);
+ grpc_error* return_error = grpc_error_create(
+ file, line, grpc_slice_from_copied_string(error_msg), NULL, 0);
+ gpr_free(error_msg);
+ return return_error;
+}
+#endif /* GRPC_CFSTREAM */
diff --git a/src/core/lib/iomgr/error_cfstream.h b/src/core/lib/iomgr/error_cfstream.h
new file mode 100644
index 0000000000..06ab751329
--- /dev/null
+++ b/src/core/lib/iomgr/error_cfstream.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * Copyright 2018 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.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_IOMGR_ERROR_CFSTREAM_H
+#define GRPC_CORE_LIB_IOMGR_ERROR_CFSTREAM_H
+
+#ifdef GRPC_CFSTREAM
+// Create an error from Apple Core Foundation CFError object
+#define GRPC_ERROR_CREATE_FROM_CFERROR(error, desc) \
+ grpc_error_create_from_cferror(__FILE__, __LINE__, \
+ static_cast<void*>((error)), (desc))
+grpc_error* grpc_error_create_from_cferror(const char* file, int line,
+ void* arg, const char* desc);
+#endif /* GRPC_CFSTREAM */
+
+#endif /* GRPC_CORE_LIB_IOMGR_ERROR_CFSTREAM_H */
diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc
index e5db1be0e0..86a0243d2e 100644
--- a/src/core/lib/iomgr/ev_epoll1_linux.cc
+++ b/src/core/lib/iomgr/ev_epoll1_linux.cc
@@ -136,6 +136,7 @@ struct grpc_fd {
grpc_core::ManualConstructor<grpc_core::LockfreeEvent> read_closure;
grpc_core::ManualConstructor<grpc_core::LockfreeEvent> write_closure;
+ grpc_core::ManualConstructor<grpc_core::LockfreeEvent> error_closure;
struct grpc_fd* freelist_next;
@@ -272,7 +273,7 @@ static void fd_global_shutdown(void) {
gpr_mu_destroy(&fd_freelist_mu);
}
-static grpc_fd* fd_create(int fd, const char* name) {
+static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
grpc_fd* new_fd = nullptr;
gpr_mu_lock(&fd_freelist_mu);
@@ -286,11 +287,12 @@ static grpc_fd* fd_create(int fd, const char* name) {
new_fd = static_cast<grpc_fd*>(gpr_malloc(sizeof(grpc_fd)));
new_fd->read_closure.Init();
new_fd->write_closure.Init();
+ new_fd->error_closure.Init();
}
-
new_fd->fd = fd;
new_fd->read_closure->InitEvent();
new_fd->write_closure->InitEvent();
+ new_fd->error_closure->InitEvent();
gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
new_fd->freelist_next = nullptr;
@@ -307,7 +309,13 @@ static grpc_fd* fd_create(int fd, const char* name) {
struct epoll_event ev;
ev.events = static_cast<uint32_t>(EPOLLIN | EPOLLOUT | EPOLLET);
- ev.data.ptr = new_fd;
+ /* Use the least significant bit of ev.data.ptr to store track_err. We expect
+ * the addresses to be word aligned. We need to store track_err to avoid
+ * synchronization issues when accessing it after receiving an event.
+ * Accessing fd would be a data race there because the fd might have been
+ * returned to the free list at that point. */
+ ev.data.ptr = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(new_fd) |
+ (track_err ? 1 : 0));
if (epoll_ctl(g_epoll_set.epfd, EPOLL_CTL_ADD, fd, &ev) != 0) {
gpr_log(GPR_ERROR, "epoll_ctl failed: %s", strerror(errno));
}
@@ -327,6 +335,7 @@ static void fd_shutdown_internal(grpc_fd* fd, grpc_error* why,
shutdown(fd->fd, SHUT_RDWR);
}
fd->write_closure->SetShutdown(GRPC_ERROR_REF(why));
+ fd->error_closure->SetShutdown(GRPC_ERROR_REF(why));
}
GRPC_ERROR_UNREF(why);
}
@@ -337,7 +346,7 @@ static void fd_shutdown(grpc_fd* fd, grpc_error* why) {
}
static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
- bool already_closed, const char* reason) {
+ const char* reason) {
grpc_error* error = GRPC_ERROR_NONE;
bool is_release_fd = (release_fd != nullptr);
@@ -350,7 +359,7 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
descriptor fd->fd (but we still own the grpc_fd structure). */
if (is_release_fd) {
*release_fd = fd->fd;
- } else if (!already_closed) {
+ } else {
close(fd->fd);
}
@@ -359,6 +368,7 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
grpc_iomgr_unregister_object(&fd->iomgr_object);
fd->read_closure->DestroyEvent();
fd->write_closure->DestroyEvent();
+ fd->error_closure->DestroyEvent();
gpr_mu_lock(&fd_freelist_mu);
fd->freelist_next = fd_freelist;
@@ -383,6 +393,10 @@ static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) {
fd->write_closure->NotifyOn(closure);
}
+static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) {
+ fd->error_closure->NotifyOn(closure);
+}
+
static void fd_become_readable(grpc_fd* fd, grpc_pollset* notifier) {
fd->read_closure->SetReady();
/* Use release store to match with acquire load in fd_get_read_notifier */
@@ -391,6 +405,8 @@ static void fd_become_readable(grpc_fd* fd, grpc_pollset* notifier) {
static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); }
+static void fd_has_errors(grpc_fd* fd) { fd->error_closure->SetReady(); }
+
/*******************************************************************************
* Pollset Definitions
*/
@@ -611,16 +627,25 @@ static grpc_error* process_epoll_events(grpc_pollset* pollset) {
append_error(&error, grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd),
err_desc);
} else {
- grpc_fd* fd = static_cast<grpc_fd*>(data_ptr);
- bool cancel = (ev->events & (EPOLLERR | EPOLLHUP)) != 0;
+ grpc_fd* fd = reinterpret_cast<grpc_fd*>(
+ reinterpret_cast<intptr_t>(data_ptr) & ~static_cast<intptr_t>(1));
+ bool track_err =
+ reinterpret_cast<intptr_t>(data_ptr) & static_cast<intptr_t>(1);
+ bool cancel = (ev->events & EPOLLHUP) != 0;
+ bool error = (ev->events & EPOLLERR) != 0;
bool read_ev = (ev->events & (EPOLLIN | EPOLLPRI)) != 0;
bool write_ev = (ev->events & EPOLLOUT) != 0;
+ bool err_fallback = error && !track_err;
+
+ if (error && !err_fallback) {
+ fd_has_errors(fd);
+ }
- if (read_ev || cancel) {
+ if (read_ev || cancel || err_fallback) {
fd_become_readable(fd, pollset);
}
- if (write_ev || cancel) {
+ if (write_ev || cancel || err_fallback) {
fd_become_writable(fd);
}
}
@@ -1183,6 +1208,7 @@ static void shutdown_engine(void) {
static const grpc_event_engine_vtable vtable = {
sizeof(grpc_pollset),
+ true,
fd_create,
fd_wrapped_fd,
@@ -1190,6 +1216,7 @@ static const grpc_event_engine_vtable vtable = {
fd_shutdown,
fd_notify_on_read,
fd_notify_on_write,
+ fd_notify_on_error,
fd_is_shutdown,
fd_get_read_notifier_pollset,
@@ -1237,12 +1264,12 @@ const grpc_event_engine_vtable* grpc_init_epoll1_linux(bool explicit_request) {
}
#else /* defined(GRPC_LINUX_EPOLL) */
-#if defined(GRPC_POSIX_SOCKET)
+#if defined(GRPC_POSIX_SOCKET_EV_EPOLL1)
#include "src/core/lib/iomgr/ev_epoll1_linux.h"
/* If GRPC_LINUX_EPOLL is not defined, it means epoll is not available. Return
* NULL */
const grpc_event_engine_vtable* grpc_init_epoll1_linux(bool explicit_request) {
return nullptr;
}
-#endif /* defined(GRPC_POSIX_SOCKET) */
+#endif /* defined(GRPC_POSIX_SOCKET_EV_EPOLL1) */
#endif /* !defined(GRPC_LINUX_EPOLL) */
diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc
index 12f23ea1d6..55a2b98372 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.cc
+++ b/src/core/lib/iomgr/ev_epollex_linux.cc
@@ -63,7 +63,7 @@
// a keepalive ping timeout issue. We may want to revert https://github
// .com/grpc/grpc/pull/14943 once we figure out the root cause.
#define MAX_EPOLL_EVENTS_HANDLED_EACH_POLL_CALL 16
-#define MAX_PROBE_EPOLL_FDS 32
+#define MAX_FDS_IN_CACHE 32
grpc_core::DebugOnlyTraceFlag grpc_trace_pollable_refcount(false,
"pollable_refcount");
@@ -77,8 +77,14 @@ typedef enum { PO_MULTI, PO_FD, PO_EMPTY } pollable_type;
typedef struct pollable pollable;
typedef struct cached_fd {
+ // Set to the grpc_fd's salt value. See 'salt' variable' in grpc_fd for more
+ // details
intptr_t salt;
+
+ // The underlying fd
int fd;
+
+ // A recency time counter that helps to determine the LRU fd in the cache
uint64_t last_used;
} cached_fd;
@@ -111,10 +117,32 @@ struct pollable {
int event_count;
struct epoll_event events[MAX_EPOLL_EVENTS];
- // Maintain a LRU-eviction cache of fds in this pollable
- cached_fd fd_cache[MAX_PROBE_EPOLL_FDS];
+ // We may be calling pollable_add_fd() on the same (pollable, fd) multiple
+ // times. To prevent pollable_add_fd() from making multiple sys calls to
+ // epoll_ctl() to add the fd, we maintain a cache of what fds are already
+ // present in the underlying epoll-set.
+ //
+ // Since this is not a correctness issue, we do not need to maintain all the
+ // fds in the cache. Hence we just use an LRU cache of size 'MAX_FDS_IN_CACHE'
+ //
+ // NOTE: An ideal implementation of this should do the following:
+ // 1) Add fds to the cache in pollable_add_fd() function (i.e whenever the fd
+ // is added to the pollable's epoll set)
+ // 2) Remove the fd from the cache whenever the fd is removed from the
+ // underlying epoll set (i.e whenever fd_orphan() is called).
+ //
+ // Implementing (2) above (i.e removing fds from cache on fd_orphan) adds a
+ // lot of complexity since an fd can be present in multiple pollalbles. So our
+ // implementation ONLY DOES (1) and NOT (2).
+ //
+ // The cache_fd.salt variable helps here to maintain correctness (it serves as
+ // an epoch that differentiates one grpc_fd from the other even though both of
+ // them may have the same fd number)
+ //
+ // The following implements LRU-eviction cache of fds in this pollable
+ cached_fd fd_cache[MAX_FDS_IN_CACHE];
int fd_cache_size;
- uint64_t fd_cache_counter;
+ uint64_t fd_cache_counter; // Recency timer tick counter
};
static const char* pollable_type_string(pollable_type t) {
@@ -157,15 +185,24 @@ static void pollable_unref(pollable* p, int line, const char* reason);
* Fd Declarations
*/
+// Monotonically increasing Epoch counter that is assinged to each grpc_fd. See
+// the description of 'salt' variable in 'grpc_fd' for more details
+// TODO: (sreek/kpayson) gpr_atm is intptr_t which may not be wide-enough on
+// 32-bit systems. Change this to int_64 - atleast on 32-bit systems
static gpr_atm g_fd_salt;
struct grpc_fd {
int fd;
+
+ // Since fd numbers can be reused (after old fds are closed), this serves as
+ // an epoch that uniquely identifies this fd (i.e the pair (salt, fd) is
+ // unique (until the salt counter (i.e g_fd_salt) overflows)
intptr_t salt;
- /* refst format:
- bit 0 : 1=Active / 0=Orphaned
- bits 1-n : refcount
- Ref/Unref by two to avoid altering the orphaned bit */
+
+ // refst format:
+ // bit 0 : 1=Active / 0=Orphaned
+ // bits 1-n : refcount
+ // Ref/Unref by two to avoid altering the orphaned bit
gpr_atm refst;
gpr_mu orphan_mu;
@@ -175,15 +212,19 @@ struct grpc_fd {
grpc_core::ManualConstructor<grpc_core::LockfreeEvent> read_closure;
grpc_core::ManualConstructor<grpc_core::LockfreeEvent> write_closure;
+ grpc_core::ManualConstructor<grpc_core::LockfreeEvent> error_closure;
struct grpc_fd* freelist_next;
grpc_closure* on_done_closure;
- /* The pollset that last noticed that the fd is readable. The actual type
- * stored in this is (grpc_pollset *) */
+ // The pollset that last noticed that the fd is readable. The actual type
+ // stored in this is (grpc_pollset *)
gpr_atm read_notifier_pollset;
grpc_iomgr_object iomgr_object;
+
+ // Do we need to track EPOLLERR events separately?
+ bool track_err;
};
static void fd_global_init(void);
@@ -309,6 +350,7 @@ static void fd_destroy(void* arg, grpc_error* error) {
fd->read_closure->DestroyEvent();
fd->write_closure->DestroyEvent();
+ fd->error_closure->DestroyEvent();
gpr_mu_unlock(&fd_freelist_mu);
}
@@ -348,7 +390,7 @@ static void fd_global_shutdown(void) {
gpr_mu_destroy(&fd_freelist_mu);
}
-static grpc_fd* fd_create(int fd, const char* name) {
+static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
grpc_fd* new_fd = nullptr;
gpr_mu_lock(&fd_freelist_mu);
@@ -362,6 +404,7 @@ static grpc_fd* fd_create(int fd, const char* name) {
new_fd = static_cast<grpc_fd*>(gpr_malloc(sizeof(grpc_fd)));
new_fd->read_closure.Init();
new_fd->write_closure.Init();
+ new_fd->error_closure.Init();
}
gpr_mu_init(&new_fd->pollable_mu);
@@ -369,9 +412,11 @@ static grpc_fd* fd_create(int fd, const char* name) {
new_fd->pollable_obj = nullptr;
gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1);
new_fd->fd = fd;
+ new_fd->track_err = track_err;
new_fd->salt = gpr_atm_no_barrier_fetch_add(&g_fd_salt, 1);
new_fd->read_closure->InitEvent();
new_fd->write_closure->InitEvent();
+ new_fd->error_closure->InitEvent();
gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
new_fd->freelist_next = nullptr;
@@ -395,8 +440,8 @@ static int fd_wrapped_fd(grpc_fd* fd) {
}
static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
- bool already_closed, const char* reason) {
- bool is_fd_closed = already_closed;
+ const char* reason) {
+ bool is_fd_closed = false;
gpr_mu_lock(&fd->orphan_mu);
@@ -406,7 +451,7 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
descriptor fd->fd (but we still own the grpc_fd structure). */
if (release_fd != nullptr) {
*release_fd = fd->fd;
- } else if (!is_fd_closed) {
+ } else {
close(fd->fd);
is_fd_closed = true;
}
@@ -438,8 +483,14 @@ static bool fd_is_shutdown(grpc_fd* fd) {
/* Might be called multiple times */
static void fd_shutdown(grpc_fd* fd, grpc_error* why) {
if (fd->read_closure->SetShutdown(GRPC_ERROR_REF(why))) {
- shutdown(fd->fd, SHUT_RDWR);
+ if (shutdown(fd->fd, SHUT_RDWR)) {
+ if (errno != ENOTCONN) {
+ gpr_log(GPR_ERROR, "Error shutting down fd %d. errno: %d",
+ grpc_fd_wrapped_fd(fd), errno);
+ }
+ }
fd->write_closure->SetShutdown(GRPC_ERROR_REF(why));
+ fd->error_closure->SetShutdown(GRPC_ERROR_REF(why));
}
GRPC_ERROR_UNREF(why);
}
@@ -452,6 +503,10 @@ static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) {
fd->write_closure->NotifyOn(closure);
}
+static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) {
+ fd->error_closure->NotifyOn(closure);
+}
+
/*******************************************************************************
* Pollable Definitions
*/
@@ -544,6 +599,7 @@ static grpc_error* pollable_add_fd(pollable* p, grpc_fd* fd) {
const int epfd = p->epfd;
gpr_mu_lock(&p->mu);
p->fd_cache_counter++;
+
// Handle the case of overflow for our cache counter by
// reseting the recency-counter on all cache objects
if (p->fd_cache_counter == 0) {
@@ -563,8 +619,9 @@ static grpc_error* pollable_add_fd(pollable* p, grpc_fd* fd) {
lru_idx = i;
}
}
+
// Add to cache
- if (p->fd_cache_size < MAX_PROBE_EPOLL_FDS) {
+ if (p->fd_cache_size < MAX_FDS_IN_CACHE) {
lru_idx = p->fd_cache_size;
p->fd_cache_size++;
}
@@ -572,6 +629,7 @@ static grpc_error* pollable_add_fd(pollable* p, grpc_fd* fd) {
p->fd_cache[lru_idx].salt = fd->salt;
p->fd_cache[lru_idx].last_used = p->fd_cache_counter;
gpr_mu_unlock(&p->mu);
+
if (grpc_polling_trace.enabled()) {
gpr_log(GPR_INFO, "add fd %p (%d) to pollable %p", fd, fd->fd, p);
}
@@ -579,7 +637,12 @@ static grpc_error* pollable_add_fd(pollable* p, grpc_fd* fd) {
struct epoll_event ev_fd;
ev_fd.events =
static_cast<uint32_t>(EPOLLET | EPOLLIN | EPOLLOUT | EPOLLEXCLUSIVE);
- ev_fd.data.ptr = fd;
+ /* Use the second least significant bit of ev_fd.data.ptr to store track_err
+ * to avoid synchronization issues when accessing it after receiving an event.
+ * Accessing fd would be a data race there because the fd might have been
+ * returned to the free list at that point. */
+ ev_fd.data.ptr = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(fd) |
+ (fd->track_err ? 2 : 0));
GRPC_STATS_INC_SYSCALL_EPOLL_CTL();
if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd->fd, &ev_fd) != 0) {
switch (errno) {
@@ -780,6 +843,8 @@ static void fd_become_readable(grpc_fd* fd, grpc_pollset* notifier) {
static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); }
+static void fd_has_errors(grpc_fd* fd) { fd->error_closure->SetReady(); }
+
static grpc_error* fd_get_or_become_pollable(grpc_fd* fd, pollable** p) {
gpr_mu_lock(&fd->pollable_mu);
grpc_error* error = GRPC_ERROR_NONE;
@@ -848,20 +913,28 @@ static grpc_error* pollable_process_events(grpc_pollset* pollset,
(intptr_t)data_ptr)),
err_desc);
} else {
- grpc_fd* fd = static_cast<grpc_fd*>(data_ptr);
- bool cancel = (ev->events & (EPOLLERR | EPOLLHUP)) != 0;
+ grpc_fd* fd =
+ reinterpret_cast<grpc_fd*>(reinterpret_cast<intptr_t>(data_ptr) & ~2);
+ bool track_err = reinterpret_cast<intptr_t>(data_ptr) & 2;
+ bool cancel = (ev->events & EPOLLHUP) != 0;
+ bool error = (ev->events & EPOLLERR) != 0;
bool read_ev = (ev->events & (EPOLLIN | EPOLLPRI)) != 0;
bool write_ev = (ev->events & EPOLLOUT) != 0;
+ bool err_fallback = error && !track_err;
+
if (grpc_polling_trace.enabled()) {
gpr_log(GPR_INFO,
"PS:%p got fd %p: cancel=%d read=%d "
"write=%d",
pollset, fd, cancel, read_ev, write_ev);
}
- if (read_ev || cancel) {
+ if (error && !err_fallback) {
+ fd_has_errors(fd);
+ }
+ if (read_ev || cancel || err_fallback) {
fd_become_readable(fd, pollset);
}
- if (write_ev || cancel) {
+ if (write_ev || cancel || err_fallback) {
fd_become_writable(fd);
}
}
@@ -1503,6 +1576,7 @@ static void shutdown_engine(void) {
static const grpc_event_engine_vtable vtable = {
sizeof(grpc_pollset),
+ true,
fd_create,
fd_wrapped_fd,
@@ -1510,6 +1584,7 @@ static const grpc_event_engine_vtable vtable = {
fd_shutdown,
fd_notify_on_read,
fd_notify_on_write,
+ fd_notify_on_error,
fd_is_shutdown,
fd_get_read_notifier_pollset,
@@ -1556,7 +1631,7 @@ const grpc_event_engine_vtable* grpc_init_epollex_linux(
}
#else /* defined(GRPC_LINUX_EPOLL_CREATE1) */
-#if defined(GRPC_POSIX_SOCKET)
+#if defined(GRPC_POSIX_SOCKET_EV_EPOLLEX)
#include "src/core/lib/iomgr/ev_epollex_linux.h"
/* If GRPC_LINUX_EPOLL_CREATE1 is not defined, it means
epoll_create1 is not available. Return NULL */
@@ -1564,6 +1639,6 @@ const grpc_event_engine_vtable* grpc_init_epollex_linux(
bool explicitly_requested) {
return nullptr;
}
-#endif /* defined(GRPC_POSIX_SOCKET) */
+#endif /* defined(GRPC_POSIX_SOCKET_EV_EPOLLEX) */
#endif /* !defined(GRPC_LINUX_EPOLL_CREATE1) */
diff --git a/src/core/lib/iomgr/ev_epollsig_linux.cc b/src/core/lib/iomgr/ev_epollsig_linux.cc
index 494bc71c1d..2189801c18 100644
--- a/src/core/lib/iomgr/ev_epollsig_linux.cc
+++ b/src/core/lib/iomgr/ev_epollsig_linux.cc
@@ -132,6 +132,7 @@ struct grpc_fd {
grpc_core::ManualConstructor<grpc_core::LockfreeEvent> read_closure;
grpc_core::ManualConstructor<grpc_core::LockfreeEvent> write_closure;
+ grpc_core::ManualConstructor<grpc_core::LockfreeEvent> error_closure;
struct grpc_fd* freelist_next;
grpc_closure* on_done_closure;
@@ -141,6 +142,9 @@ struct grpc_fd {
gpr_atm read_notifier_pollset;
grpc_iomgr_object iomgr_object;
+
+ /* Do we need to track EPOLLERR events separately? */
+ bool track_err;
};
/* Reference counting for fds */
@@ -352,7 +356,10 @@ static void polling_island_add_fds_locked(polling_island* pi, grpc_fd** fds,
for (i = 0; i < fd_count; i++) {
ev.events = static_cast<uint32_t>(EPOLLIN | EPOLLOUT | EPOLLET);
- ev.data.ptr = fds[i];
+ /* Use the least significant bit of ev.data.ptr to store track_err to avoid
+ * synchronization issues when accessing it after receiving an event */
+ ev.data.ptr = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(fds[i]) |
+ (fds[i]->track_err ? 1 : 0));
err = epoll_ctl(pi->epoll_fd, EPOLL_CTL_ADD, fds[i]->fd, &ev);
if (err < 0) {
@@ -435,7 +442,6 @@ static void polling_island_remove_all_fds_locked(polling_island* pi,
/* The caller is expected to hold pi->mu lock before calling this function */
static void polling_island_remove_fd_locked(polling_island* pi, grpc_fd* fd,
- bool is_fd_closed,
grpc_error** error) {
int err;
size_t i;
@@ -444,16 +450,14 @@ static void polling_island_remove_fd_locked(polling_island* pi, grpc_fd* fd,
/* If fd is already closed, then it would have been automatically been removed
from the epoll set */
- if (!is_fd_closed) {
- err = epoll_ctl(pi->epoll_fd, EPOLL_CTL_DEL, fd->fd, nullptr);
- if (err < 0 && errno != ENOENT) {
- gpr_asprintf(
- &err_msg,
- "epoll_ctl (epoll_fd: %d) del fd: %d failed with error: %d (%s)",
- pi->epoll_fd, fd->fd, errno, strerror(errno));
- append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc);
- gpr_free(err_msg);
- }
+ err = epoll_ctl(pi->epoll_fd, EPOLL_CTL_DEL, fd->fd, nullptr);
+ if (err < 0 && errno != ENOENT) {
+ gpr_asprintf(
+ &err_msg,
+ "epoll_ctl (epoll_fd: %d) del fd: %d failed with error: %d (%s)",
+ pi->epoll_fd, fd->fd, errno, strerror(errno));
+ append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc);
+ gpr_free(err_msg);
}
for (i = 0; i < pi->fd_cnt; i++) {
@@ -769,6 +773,7 @@ static void unref_by(grpc_fd* fd, int n) {
fd->read_closure->DestroyEvent();
fd->write_closure->DestroyEvent();
+ fd->error_closure->DestroyEvent();
gpr_mu_unlock(&fd_freelist_mu);
} else {
@@ -806,7 +811,7 @@ static void fd_global_shutdown(void) {
gpr_mu_destroy(&fd_freelist_mu);
}
-static grpc_fd* fd_create(int fd, const char* name) {
+static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
grpc_fd* new_fd = nullptr;
gpr_mu_lock(&fd_freelist_mu);
@@ -821,6 +826,7 @@ static grpc_fd* fd_create(int fd, const char* name) {
gpr_mu_init(&new_fd->po.mu);
new_fd->read_closure.Init();
new_fd->write_closure.Init();
+ new_fd->error_closure.Init();
}
/* Note: It is not really needed to get the new_fd->po.mu lock here. If this
@@ -837,6 +843,8 @@ static grpc_fd* fd_create(int fd, const char* name) {
new_fd->orphaned = false;
new_fd->read_closure->InitEvent();
new_fd->write_closure->InitEvent();
+ new_fd->error_closure->InitEvent();
+ new_fd->track_err = track_err;
gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
new_fd->freelist_next = nullptr;
@@ -863,7 +871,7 @@ static int fd_wrapped_fd(grpc_fd* fd) {
}
static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
- bool already_closed, const char* reason) {
+ const char* reason) {
grpc_error* error = GRPC_ERROR_NONE;
polling_island* unref_pi = nullptr;
@@ -884,7 +892,7 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
before doing this.) */
if (fd->po.pi != nullptr) {
polling_island* pi_latest = polling_island_lock(fd->po.pi);
- polling_island_remove_fd_locked(pi_latest, fd, already_closed, &error);
+ polling_island_remove_fd_locked(pi_latest, fd, &error);
gpr_mu_unlock(&pi_latest->mu);
unref_pi = fd->po.pi;
@@ -933,6 +941,7 @@ static void fd_shutdown(grpc_fd* fd, grpc_error* why) {
if (fd->read_closure->SetShutdown(GRPC_ERROR_REF(why))) {
shutdown(fd->fd, SHUT_RDWR);
fd->write_closure->SetShutdown(GRPC_ERROR_REF(why));
+ fd->error_closure->SetShutdown(GRPC_ERROR_REF(why));
}
GRPC_ERROR_UNREF(why);
}
@@ -945,6 +954,10 @@ static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) {
fd->write_closure->NotifyOn(closure);
}
+static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) {
+ fd->error_closure->NotifyOn(closure);
+}
+
/*******************************************************************************
* Pollset Definitions
*/
@@ -1116,6 +1129,8 @@ static void fd_become_readable(grpc_fd* fd, grpc_pollset* notifier) {
static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); }
+static void fd_has_errors(grpc_fd* fd) { fd->error_closure->SetReady(); }
+
static void pollset_release_polling_island(grpc_pollset* ps,
const char* reason) {
if (ps->po.pi != nullptr) {
@@ -1254,14 +1269,23 @@ static void pollset_work_and_unlock(grpc_pollset* pollset,
to the function pollset_work_and_unlock() will pick up the correct
epoll_fd */
} else {
- grpc_fd* fd = static_cast<grpc_fd*>(data_ptr);
- int cancel = ep_ev[i].events & (EPOLLERR | EPOLLHUP);
- int read_ev = ep_ev[i].events & (EPOLLIN | EPOLLPRI);
- int write_ev = ep_ev[i].events & EPOLLOUT;
- if (read_ev || cancel) {
+ grpc_fd* fd = reinterpret_cast<grpc_fd*>(
+ reinterpret_cast<intptr_t>(data_ptr) & ~static_cast<intptr_t>(1));
+ bool track_err =
+ reinterpret_cast<intptr_t>(data_ptr) & ~static_cast<intptr_t>(1);
+ bool cancel = (ep_ev[i].events & EPOLLHUP) != 0;
+ bool error = (ep_ev[i].events & EPOLLERR) != 0;
+ bool read_ev = (ep_ev[i].events & (EPOLLIN | EPOLLPRI)) != 0;
+ bool write_ev = (ep_ev[i].events & EPOLLOUT) != 0;
+ bool err_fallback = error && !track_err;
+
+ if (error && !err_fallback) {
+ fd_has_errors(fd);
+ }
+ if (read_ev || cancel || err_fallback) {
fd_become_readable(fd, pollset);
}
- if (write_ev || cancel) {
+ if (write_ev || cancel || err_fallback) {
fd_become_writable(fd);
}
}
@@ -1634,6 +1658,7 @@ static void shutdown_engine(void) {
static const grpc_event_engine_vtable vtable = {
sizeof(grpc_pollset),
+ true,
fd_create,
fd_wrapped_fd,
@@ -1641,6 +1666,7 @@ static const grpc_event_engine_vtable vtable = {
fd_shutdown,
fd_notify_on_read,
fd_notify_on_write,
+ fd_notify_on_error,
fd_is_shutdown,
fd_get_read_notifier_pollset,
@@ -1721,7 +1747,7 @@ const grpc_event_engine_vtable* grpc_init_epollsig_linux(
}
#else /* defined(GRPC_LINUX_EPOLL_CREATE1) */
-#if defined(GRPC_POSIX_SOCKET)
+#if defined(GRPC_POSIX_SOCKET_EV_EPOLLSIG)
#include "src/core/lib/iomgr/ev_epollsig_linux.h"
/* If GRPC_LINUX_EPOLL_CREATE1 is not defined, it means
epoll_create1 is not available. Return NULL */
diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc
index 504787e659..c9c09881a2 100644
--- a/src/core/lib/iomgr/ev_poll_posix.cc
+++ b/src/core/lib/iomgr/ev_poll_posix.cc
@@ -20,7 +20,7 @@
#include "src/core/lib/iomgr/port.h"
-#ifdef GRPC_POSIX_SOCKET
+#ifdef GRPC_POSIX_SOCKET_EV_POLL
#include "src/core/lib/iomgr/ev_poll_posix.h"
@@ -330,7 +330,8 @@ static void unref_by(grpc_fd* fd, int n) {
}
}
-static grpc_fd* fd_create(int fd, const char* name) {
+static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
+ GPR_DEBUG_ASSERT(track_err == false);
grpc_fd* r = static_cast<grpc_fd*>(gpr_malloc(sizeof(*r)));
gpr_mu_init(&r->mu);
gpr_atm_rel_store(&r->refst, 1);
@@ -424,14 +425,12 @@ static int fd_wrapped_fd(grpc_fd* fd) {
}
static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
- bool already_closed, const char* reason) {
+ const char* reason) {
fd->on_done_closure = on_done;
fd->released = release_fd != nullptr;
if (release_fd != nullptr) {
*release_fd = fd->fd;
fd->released = true;
- } else if (already_closed) {
- fd->released = true;
}
gpr_mu_lock(&fd->mu);
REF_BY(fd, 1, reason); /* remove active status, but keep referenced */
@@ -553,6 +552,11 @@ static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) {
gpr_mu_unlock(&fd->mu);
}
+static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) {
+ gpr_log(GPR_ERROR, "Polling engine does not support tracking errors.");
+ abort();
+}
+
static uint32_t fd_begin_poll(grpc_fd* fd, grpc_pollset* pollset,
grpc_pollset_worker* worker, uint32_t read_mask,
uint32_t write_mask, grpc_fd_watcher* watcher) {
@@ -1710,6 +1714,7 @@ static void shutdown_engine(void) {
static const grpc_event_engine_vtable vtable = {
sizeof(grpc_pollset),
+ false,
fd_create,
fd_wrapped_fd,
@@ -1717,6 +1722,7 @@ static const grpc_event_engine_vtable vtable = {
fd_shutdown,
fd_notify_on_read,
fd_notify_on_write,
+ fd_notify_on_error,
fd_is_shutdown,
fd_get_read_notifier_pollset,
@@ -1761,4 +1767,4 @@ const grpc_event_engine_vtable* grpc_init_poll_cv_posix(bool explicit_request) {
return &vtable;
}
-#endif
+#endif /* GRPC_POSIX_SOCKET_EV_POLL */
diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc
index 902dca934a..1139b3273a 100644
--- a/src/core/lib/iomgr/ev_posix.cc
+++ b/src/core/lib/iomgr/ev_posix.cc
@@ -20,7 +20,7 @@
#include "src/core/lib/iomgr/port.h"
-#ifdef GRPC_POSIX_SOCKET
+#ifdef GRPC_POSIX_SOCKET_EV
#include "src/core/lib/iomgr/ev_posix.h"
@@ -193,10 +193,15 @@ void grpc_event_engine_shutdown(void) {
g_event_engine = nullptr;
}
-grpc_fd* grpc_fd_create(int fd, const char* name) {
- GRPC_POLLING_API_TRACE("fd_create(%d, %s)", fd, name);
- GRPC_FD_TRACE("fd_create(%d, %s)", fd, name);
- return g_event_engine->fd_create(fd, name);
+bool grpc_event_engine_can_track_errors(void) {
+ return g_event_engine->can_track_err;
+}
+
+grpc_fd* grpc_fd_create(int fd, const char* name, bool track_err) {
+ GRPC_POLLING_API_TRACE("fd_create(%d, %s, %d)", fd, name, track_err);
+ GRPC_FD_TRACE("fd_create(%d, %s, %d)", fd, name, track_err);
+ GPR_DEBUG_ASSERT(!track_err || g_event_engine->can_track_err);
+ return g_event_engine->fd_create(fd, name, track_err);
}
int grpc_fd_wrapped_fd(grpc_fd* fd) {
@@ -204,13 +209,12 @@ int grpc_fd_wrapped_fd(grpc_fd* fd) {
}
void grpc_fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
- bool already_closed, const char* reason) {
- GRPC_POLLING_API_TRACE("fd_orphan(%d, %p, %p, %d, %s)",
- grpc_fd_wrapped_fd(fd), on_done, release_fd,
- already_closed, reason);
+ const char* reason) {
+ GRPC_POLLING_API_TRACE("fd_orphan(%d, %p, %p, %s)", grpc_fd_wrapped_fd(fd),
+ on_done, release_fd, reason);
GRPC_FD_TRACE("grpc_fd_orphan, fd:%d closed", grpc_fd_wrapped_fd(fd));
- g_event_engine->fd_orphan(fd, on_done, release_fd, already_closed, reason);
+ g_event_engine->fd_orphan(fd, on_done, release_fd, reason);
}
void grpc_fd_shutdown(grpc_fd* fd, grpc_error* why) {
@@ -231,6 +235,10 @@ void grpc_fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) {
g_event_engine->fd_notify_on_write(fd, closure);
}
+void grpc_fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) {
+ g_event_engine->fd_notify_on_error(fd, closure);
+}
+
static size_t pollset_size(void) { return g_event_engine->pollset_size; }
static void pollset_init(grpc_pollset* pollset, gpr_mu** mu) {
@@ -334,4 +342,4 @@ void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd) {
g_event_engine->pollset_set_del_fd(pollset_set, fd);
}
-#endif // GRPC_POSIX_SOCKET
+#endif // GRPC_POSIX_SOCKET_EV
diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h
index 82cbce9a7b..b4c17fc80d 100644
--- a/src/core/lib/iomgr/ev_posix.h
+++ b/src/core/lib/iomgr/ev_posix.h
@@ -41,14 +41,16 @@ typedef struct grpc_fd grpc_fd;
typedef struct grpc_event_engine_vtable {
size_t pollset_size;
+ bool can_track_err;
- grpc_fd* (*fd_create)(int fd, const char* name);
+ grpc_fd* (*fd_create)(int fd, const char* name, bool track_err);
int (*fd_wrapped_fd)(grpc_fd* fd);
void (*fd_orphan)(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
- bool already_closed, const char* reason);
+ const char* reason);
void (*fd_shutdown)(grpc_fd* fd, grpc_error* why);
void (*fd_notify_on_read)(grpc_fd* fd, grpc_closure* closure);
void (*fd_notify_on_write)(grpc_fd* fd, grpc_closure* closure);
+ void (*fd_notify_on_error)(grpc_fd* fd, grpc_closure* closure);
bool (*fd_is_shutdown)(grpc_fd* fd);
grpc_pollset* (*fd_get_read_notifier_pollset)(grpc_fd* fd);
@@ -84,10 +86,20 @@ void grpc_event_engine_shutdown(void);
/* Return the name of the poll strategy */
const char* grpc_get_poll_strategy_name();
+/* Returns true if polling engine can track errors separately, false otherwise.
+ * If this is true, fd can be created with track_err set. After this, error
+ * events will be reported using fd_notify_on_error. If it is not set, errors
+ * will continue to be reported through fd_notify_on_read and
+ * fd_notify_on_write.
+ */
+bool grpc_event_engine_can_track_errors();
+
/* Create a wrapped file descriptor.
Requires fd is a non-blocking file descriptor.
+ \a track_err if true means that error events would be tracked separately
+ using grpc_fd_notify_on_error. Currently, valid only for linux systems.
This takes ownership of closing fd. */
-grpc_fd* grpc_fd_create(int fd, const char* name);
+grpc_fd* grpc_fd_create(int fd, const char* name, bool track_err);
/* Return the wrapped fd, or -1 if it has been released or closed. */
int grpc_fd_wrapped_fd(grpc_fd* fd);
@@ -100,7 +112,7 @@ int grpc_fd_wrapped_fd(grpc_fd* fd);
notify_on_write.
MUST NOT be called with a pollset lock taken */
void grpc_fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
- bool already_closed, const char* reason);
+ const char* reason);
/* Has grpc_fd_shutdown been called on an fd? */
bool grpc_fd_is_shutdown(grpc_fd* fd);
@@ -126,6 +138,10 @@ void grpc_fd_notify_on_read(grpc_fd* fd, grpc_closure* closure);
/* Exactly the same semantics as above, except based on writable events. */
void grpc_fd_notify_on_write(grpc_fd* fd, grpc_closure* closure);
+/* Exactly the same semantics as above, except based on error events. track_err
+ * needs to have been set on grpc_fd_create */
+void grpc_fd_notify_on_error(grpc_fd* fd, grpc_closure* closure);
+
/* Return the read notifier pollset from the fd */
grpc_pollset* grpc_fd_get_read_notifier_pollset(grpc_fd* fd);
diff --git a/src/core/lib/iomgr/iomgr_posix.cc b/src/core/lib/iomgr/iomgr_posix.cc
index 66c9cb7ff7..ca7334c9a4 100644
--- a/src/core/lib/iomgr/iomgr_posix.cc
+++ b/src/core/lib/iomgr/iomgr_posix.cc
@@ -20,7 +20,7 @@
#include "src/core/lib/iomgr/port.h"
-#ifdef GRPC_POSIX_SOCKET
+#ifdef GRPC_POSIX_SOCKET_IOMGR
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/ev_posix.h"
@@ -64,4 +64,4 @@ void grpc_set_default_iomgr_platform() {
grpc_set_iomgr_platform_vtable(&vtable);
}
-#endif /* GRPC_POSIX_SOCKET */
+#endif /* GRPC_POSIX_SOCKET_IOMGR */
diff --git a/src/core/lib/iomgr/polling_entity.cc b/src/core/lib/iomgr/polling_entity.cc
index 9f164f65b0..dea07cae53 100644
--- a/src/core/lib/iomgr/polling_entity.cc
+++ b/src/core/lib/iomgr/polling_entity.cc
@@ -61,8 +61,11 @@ bool grpc_polling_entity_is_empty(const grpc_polling_entity* pollent) {
void grpc_polling_entity_add_to_pollset_set(grpc_polling_entity* pollent,
grpc_pollset_set* pss_dst) {
if (pollent->tag == GRPC_POLLS_POLLSET) {
- GPR_ASSERT(pollent->pollent.pollset != nullptr);
- grpc_pollset_set_add_pollset(pss_dst, pollent->pollent.pollset);
+ // CFStream does not use file destriptors. When CFStream is used, the fd
+ // pollset is possible to be null.
+ if (pollent->pollent.pollset != nullptr) {
+ grpc_pollset_set_add_pollset(pss_dst, pollent->pollent.pollset);
+ }
} else if (pollent->tag == GRPC_POLLS_POLLSET_SET) {
GPR_ASSERT(pollent->pollent.pollset_set != nullptr);
grpc_pollset_set_add_pollset_set(pss_dst, pollent->pollent.pollset_set);
@@ -75,8 +78,14 @@ void grpc_polling_entity_add_to_pollset_set(grpc_polling_entity* pollent,
void grpc_polling_entity_del_from_pollset_set(grpc_polling_entity* pollent,
grpc_pollset_set* pss_dst) {
if (pollent->tag == GRPC_POLLS_POLLSET) {
+#ifdef GRPC_CFSTREAM
+ if (pollent->pollent.pollset != nullptr) {
+ grpc_pollset_set_del_pollset(pss_dst, pollent->pollent.pollset);
+ }
+#else
GPR_ASSERT(pollent->pollent.pollset != nullptr);
grpc_pollset_set_del_pollset(pss_dst, pollent->pollent.pollset);
+#endif
} else if (pollent->tag == GRPC_POLLS_POLLSET_SET) {
GPR_ASSERT(pollent->pollent.pollset_set != nullptr);
grpc_pollset_set_del_pollset_set(pss_dst, pollent->pollent.pollset_set);
diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h
index a397012003..80d8e63cdd 100644
--- a/src/core/lib/iomgr/port.h
+++ b/src/core/lib/iomgr/port.h
@@ -97,7 +97,26 @@
#define GRPC_MSG_IOVLEN_TYPE int
#define GRPC_POSIX_FORK 1
#define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1
+#ifdef GRPC_CFSTREAM
+#define GRPC_POSIX_SOCKET_IOMGR 1
+#define GRPC_CFSTREAM_ENDPOINT 1
+#define GRPC_CFSTREAM_CLIENT 1
+#define GRPC_POSIX_SOCKET_ARES_EV_DRIVER 1
+#define GRPC_POSIX_SOCKET_EV 1
+#define GRPC_POSIX_SOCKET_EV_EPOLL1 1
+#define GRPC_POSIX_SOCKET_EV_EPOLLEX 1
+#define GRPC_POSIX_SOCKET_EV_EPOLLSIG 1
+#define GRPC_POSIX_SOCKET_EV_POLL 1
+#define GRPC_POSIX_SOCKET_RESOLVE_ADDRESS 1
+#define GRPC_POSIX_SOCKET_SOCKADDR 1
+#define GRPC_POSIX_SOCKET_SOCKET_FACTORY 1
+#define GRPC_POSIX_SOCKET_TCP 1
+#define GRPC_POSIX_SOCKET_TCP_SERVER 1
+#define GRPC_POSIX_SOCKET_TCP_SERVER_UTILS_COMMON 1
+#define GRPC_POSIX_SOCKET_UTILS_COMMON 1
+#else
#define GRPC_POSIX_SOCKET 1
+#endif
#define GRPC_POSIX_SOCKETUTILS 1
#define GRPC_POSIX_SYSCONF 1
#define GRPC_POSIX_WAKEUP_FD 1
@@ -131,12 +150,30 @@
#endif
#if defined(GRPC_POSIX_SOCKET) + defined(GRPC_WINSOCK_SOCKET) + \
- defined(GRPC_CUSTOM_SOCKET) != \
+ defined(GRPC_CUSTOM_SOCKET) + defined(GRPC_CFSTREAM) != \
1
#error \
"Must define exactly one of GRPC_POSIX_SOCKET, GRPC_WINSOCK_SOCKET, GRPC_CUSTOM_SOCKET"
#endif
+#ifdef GRPC_POSIX_SOCKET
+#define GRPC_POSIX_SOCKET_ARES_EV_DRIVER 1
+#define GRPC_POSIX_SOCKET_EV 1
+#define GRPC_POSIX_SOCKET_EV_EPOLLEX 1
+#define GRPC_POSIX_SOCKET_EV_EPOLLSIG 1
+#define GRPC_POSIX_SOCKET_EV_POLL 1
+#define GRPC_POSIX_SOCKET_EV_EPOLL1 1
+#define GRPC_POSIX_SOCKET_IOMGR 1
+#define GRPC_POSIX_SOCKET_RESOLVE_ADDRESS 1
+#define GRPC_POSIX_SOCKET_SOCKADDR 1
+#define GRPC_POSIX_SOCKET_SOCKET_FACTORY 1
+#define GRPC_POSIX_SOCKET_TCP 1
+#define GRPC_POSIX_SOCKET_TCP_CLIENT 1
+#define GRPC_POSIX_SOCKET_TCP_SERVER 1
+#define GRPC_POSIX_SOCKET_TCP_SERVER_UTILS_COMMON 1
+#define GRPC_POSIX_SOCKET_UTILS_COMMON 1
+#endif
+
#if defined(GRPC_POSIX_HOST_NAME_MAX) && defined(GRPC_POSIX_SYSCONF)
#error "Cannot define both GRPC_POSIX_HOST_NAME_MAX and GRPC_POSIX_SYSCONF"
#endif
diff --git a/src/core/lib/iomgr/resolve_address.h b/src/core/lib/iomgr/resolve_address.h
index fe0d834582..6afe94a7a9 100644
--- a/src/core/lib/iomgr/resolve_address.h
+++ b/src/core/lib/iomgr/resolve_address.h
@@ -33,7 +33,7 @@
#include <ws2tcpip.h>
#endif
-#ifdef GRPC_POSIX_SOCKET
+#if defined(GRPC_POSIX_SOCKET) || defined(GRPC_CFSTREAM)
#include <sys/socket.h>
#endif
diff --git a/src/core/lib/iomgr/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc
index a82075542f..7a825643e1 100644
--- a/src/core/lib/iomgr/resolve_address_posix.cc
+++ b/src/core/lib/iomgr/resolve_address_posix.cc
@@ -19,7 +19,7 @@
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/port.h"
-#ifdef GRPC_POSIX_SOCKET
+#ifdef GRPC_POSIX_SOCKET_RESOLVE_ADDRESS
#include "src/core/lib/iomgr/sockaddr.h"
diff --git a/src/core/lib/iomgr/resource_quota.cc b/src/core/lib/iomgr/resource_quota.cc
index 539bc120ce..8a308f71bb 100644
--- a/src/core/lib/iomgr/resource_quota.cc
+++ b/src/core/lib/iomgr/resource_quota.cc
@@ -30,6 +30,7 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/combiner.h"
@@ -670,18 +671,9 @@ size_t grpc_resource_quota_peek_size(grpc_resource_quota* resource_quota) {
grpc_resource_quota* grpc_resource_quota_from_channel_args(
const grpc_channel_args* channel_args) {
- for (size_t i = 0; i < channel_args->num_args; i++) {
- if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
- if (channel_args->args[i].type == GRPC_ARG_POINTER) {
- return grpc_resource_quota_ref_internal(
- static_cast<grpc_resource_quota*>(
- channel_args->args[i].value.pointer.p));
- } else {
- gpr_log(GPR_DEBUG, GRPC_ARG_RESOURCE_QUOTA " should be a pointer");
- }
- }
- }
- return grpc_resource_quota_create(nullptr);
+ grpc_resource_quota* rq = grpc_channel_args_get_pointer<grpc_resource_quota>(
+ channel_args, GRPC_ARG_RESOURCE_QUOTA);
+ return rq == nullptr ? grpc_resource_quota_create(nullptr) : rq;
}
static void* rq_copy(void* rq) {
diff --git a/src/core/lib/iomgr/sockaddr_posix.h b/src/core/lib/iomgr/sockaddr_posix.h
index 5b18bbc465..3cedd9082d 100644
--- a/src/core/lib/iomgr/sockaddr_posix.h
+++ b/src/core/lib/iomgr/sockaddr_posix.h
@@ -23,7 +23,7 @@
#include "src/core/lib/iomgr/port.h"
-#ifdef GRPC_POSIX_SOCKET
+#ifdef GRPC_POSIX_SOCKET_SOCKADDR
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
diff --git a/src/core/lib/iomgr/socket_factory_posix.cc b/src/core/lib/iomgr/socket_factory_posix.cc
index 1d1e36c0e3..57137769c8 100644
--- a/src/core/lib/iomgr/socket_factory_posix.cc
+++ b/src/core/lib/iomgr/socket_factory_posix.cc
@@ -20,7 +20,7 @@
#include "src/core/lib/iomgr/port.h"
-#ifdef GRPC_POSIX_SOCKET
+#ifdef GRPC_POSIX_SOCKET_SOCKET_FACTORY
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/useful.h"
diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc
index 04a1767731..caee652307 100644
--- a/src/core/lib/iomgr/socket_utils_common_posix.cc
+++ b/src/core/lib/iomgr/socket_utils_common_posix.cc
@@ -20,7 +20,7 @@
#include "src/core/lib/iomgr/port.h"
-#ifdef GRPC_POSIX_SOCKET
+#ifdef GRPC_POSIX_SOCKET_UTILS_COMMON
#include "src/core/lib/iomgr/socket_utils.h"
#include "src/core/lib/iomgr/socket_utils_posix.h"
diff --git a/src/core/lib/iomgr/tcp_client_cfstream.cc b/src/core/lib/iomgr/tcp_client_cfstream.cc
new file mode 100644
index 0000000000..5acea91792
--- /dev/null
+++ b/src/core/lib/iomgr/tcp_client_cfstream.cc
@@ -0,0 +1,216 @@
+
+/*
+ *
+ * Copyright 2018 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/iomgr/port.h"
+
+#ifdef GRPC_CFSTREAM_CLIENT
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+
+#include <netinet/in.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/host_port.h"
+#include "src/core/lib/iomgr/cfstream_handle.h"
+#include "src/core/lib/iomgr/closure.h"
+#include "src/core/lib/iomgr/endpoint_cfstream.h"
+#include "src/core/lib/iomgr/error.h"
+#include "src/core/lib/iomgr/error_cfstream.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
+#include "src/core/lib/iomgr/tcp_client.h"
+#include "src/core/lib/iomgr/timer.h"
+
+extern grpc_core::TraceFlag grpc_tcp_trace;
+
+typedef struct CFStreamConnect {
+ gpr_mu mu;
+ gpr_refcount refcount;
+
+ CFReadStreamRef read_stream;
+ CFWriteStreamRef write_stream;
+ CFStreamHandle* stream_handle;
+
+ grpc_timer alarm;
+ grpc_closure on_alarm;
+ grpc_closure on_open;
+
+ bool read_stream_open;
+ bool write_stream_open;
+ bool failed;
+
+ grpc_closure* closure;
+ grpc_endpoint** endpoint;
+ int refs;
+ char* addr_name;
+ grpc_resource_quota* resource_quota;
+} CFStreamConnect;
+
+static void CFStreamConnectCleanup(CFStreamConnect* connect) {
+ grpc_resource_quota_unref_internal(connect->resource_quota);
+ CFSTREAM_HANDLE_UNREF(connect->stream_handle, "async connect clean up");
+ CFRelease(connect->read_stream);
+ CFRelease(connect->write_stream);
+ gpr_mu_destroy(&connect->mu);
+ gpr_free(connect->addr_name);
+ gpr_free(connect);
+}
+
+static void OnAlarm(void* arg, grpc_error* error) {
+ CFStreamConnect* connect = static_cast<CFStreamConnect*>(arg);
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "CLIENT_CONNECT :%p OnAlarm, error:%p", connect, error);
+ }
+ gpr_mu_lock(&connect->mu);
+ grpc_closure* closure = connect->closure;
+ connect->closure = nil;
+ const bool done = (--connect->refs == 0);
+ gpr_mu_unlock(&connect->mu);
+ // Only schedule a callback once, by either OnAlarm or OnOpen. The
+ // first one issues callback while the second one does cleanup.
+ if (done) {
+ CFStreamConnectCleanup(connect);
+ } else {
+ grpc_error* error =
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("connect() timed out");
+ GRPC_CLOSURE_SCHED(closure, error);
+ }
+}
+
+static void OnOpen(void* arg, grpc_error* error) {
+ CFStreamConnect* connect = static_cast<CFStreamConnect*>(arg);
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "CLIENT_CONNECT :%p OnOpen, error:%p", connect, error);
+ }
+ gpr_mu_lock(&connect->mu);
+ grpc_timer_cancel(&connect->alarm);
+ grpc_closure* closure = connect->closure;
+ connect->closure = nil;
+
+ bool done = (--connect->refs == 0);
+ grpc_endpoint** endpoint = connect->endpoint;
+
+ // Only schedule a callback once, by either OnAlarm or OnOpen. The
+ // first one issues callback while the second one does cleanup.
+ if (done) {
+ gpr_mu_unlock(&connect->mu);
+ CFStreamConnectCleanup(connect);
+ } else {
+ if (error == GRPC_ERROR_NONE) {
+ CFErrorRef stream_error = CFReadStreamCopyError(connect->read_stream);
+ if (stream_error == NULL) {
+ stream_error = CFWriteStreamCopyError(connect->write_stream);
+ }
+ if (stream_error) {
+ error = GRPC_ERROR_CREATE_FROM_CFERROR(stream_error, "connect() error");
+ CFRelease(stream_error);
+ }
+ if (error == GRPC_ERROR_NONE) {
+ *endpoint = grpc_cfstream_endpoint_create(
+ connect->read_stream, connect->write_stream, connect->addr_name,
+ connect->resource_quota, connect->stream_handle);
+ }
+ } else {
+ GRPC_ERROR_REF(error);
+ }
+ gpr_mu_unlock(&connect->mu);
+ GRPC_CLOSURE_SCHED(closure, error);
+ }
+}
+
+static void ParseResolvedAddress(const grpc_resolved_address* addr,
+ CFStringRef* host, int* port) {
+ char *host_port, *host_string, *port_string;
+ grpc_sockaddr_to_string(&host_port, addr, 1);
+ gpr_split_host_port(host_port, &host_string, &port_string);
+ *host = CFStringCreateWithCString(NULL, host_string, kCFStringEncodingUTF8);
+ gpr_free(host_string);
+ gpr_free(port_string);
+ gpr_free(host_port);
+ *port = grpc_sockaddr_get_port(addr);
+}
+
+static void CFStreamClientConnect(grpc_closure* closure, grpc_endpoint** ep,
+ grpc_pollset_set* interested_parties,
+ const grpc_channel_args* channel_args,
+ const grpc_resolved_address* resolved_addr,
+ grpc_millis deadline) {
+ CFStreamConnect* connect;
+
+ connect = (CFStreamConnect*)gpr_zalloc(sizeof(CFStreamConnect));
+ connect->closure = closure;
+ connect->endpoint = ep;
+ connect->addr_name = grpc_sockaddr_to_uri(resolved_addr);
+ // connect->resource_quota = resource_quota;
+ connect->refs = 2; // One for the connect operation, one for the timer.
+ gpr_ref_init(&connect->refcount, 1);
+ gpr_mu_init(&connect->mu);
+
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %p, %s: asynchronously connecting",
+ connect, connect->addr_name);
+ }
+
+ grpc_resource_quota* resource_quota = grpc_resource_quota_create(NULL);
+ if (channel_args != NULL) {
+ for (size_t i = 0; i < channel_args->num_args; i++) {
+ if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
+ grpc_resource_quota_unref_internal(resource_quota);
+ resource_quota = grpc_resource_quota_ref_internal(
+ (grpc_resource_quota*)channel_args->args[i].value.pointer.p);
+ }
+ }
+ }
+ connect->resource_quota = resource_quota;
+
+ CFReadStreamRef read_stream;
+ CFWriteStreamRef write_stream;
+
+ CFStringRef host;
+ int port;
+ ParseResolvedAddress(resolved_addr, &host, &port);
+ CFStreamCreatePairWithSocketToHost(NULL, host, port, &read_stream,
+ &write_stream);
+ CFRelease(host);
+ connect->read_stream = read_stream;
+ connect->write_stream = write_stream;
+ connect->stream_handle =
+ CFStreamHandle::CreateStreamHandle(read_stream, write_stream);
+ GRPC_CLOSURE_INIT(&connect->on_open, OnOpen, static_cast<void*>(connect),
+ grpc_schedule_on_exec_ctx);
+ connect->stream_handle->NotifyOnOpen(&connect->on_open);
+ GRPC_CLOSURE_INIT(&connect->on_alarm, OnAlarm, connect,
+ grpc_schedule_on_exec_ctx);
+ gpr_mu_lock(&connect->mu);
+ CFReadStreamOpen(read_stream);
+ CFWriteStreamOpen(write_stream);
+ grpc_timer_init(&connect->alarm, deadline, &connect->on_alarm);
+ gpr_mu_unlock(&connect->mu);
+}
+
+grpc_tcp_client_vtable grpc_posix_tcp_client_vtable = {CFStreamClientConnect};
+
+#endif /* GRPC_CFSTREAM_CLIENT */
diff --git a/src/core/lib/iomgr/tcp_client_custom.cc b/src/core/lib/iomgr/tcp_client_custom.cc
index 932c79ea0b..9389861d07 100644
--- a/src/core/lib/iomgr/tcp_client_custom.cc
+++ b/src/core/lib/iomgr/tcp_client_custom.cc
@@ -140,12 +140,12 @@ static void tcp_connect(grpc_closure* closure, grpc_endpoint** ep,
socket, connect->addr_name);
}
- grpc_custom_socket_vtable->connect(
- socket, (const grpc_sockaddr*)resolved_addr->addr, resolved_addr->len,
- custom_connect_callback);
GRPC_CLOSURE_INIT(&connect->on_alarm, on_alarm, socket,
grpc_schedule_on_exec_ctx);
grpc_timer_init(&connect->alarm, deadline, &connect->on_alarm);
+ grpc_custom_socket_vtable->connect(
+ socket, (const grpc_sockaddr*)resolved_addr->addr, resolved_addr->len,
+ custom_connect_callback);
}
grpc_tcp_client_vtable custom_tcp_client_vtable = {tcp_connect};
diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc
index 900c056575..30015fc203 100644
--- a/src/core/lib/iomgr/tcp_client_posix.cc
+++ b/src/core/lib/iomgr/tcp_client_posix.cc
@@ -20,7 +20,7 @@
#include "src/core/lib/iomgr/port.h"
-#ifdef GRPC_POSIX_SOCKET
+#ifdef GRPC_POSIX_SOCKET_TCP_CLIENT
#include "src/core/lib/iomgr/tcp_client_posix.h"
@@ -66,6 +66,7 @@ typedef struct {
static grpc_error* prepare_socket(const grpc_resolved_address* addr, int fd,
const grpc_channel_args* channel_args) {
grpc_error* err = GRPC_ERROR_NONE;
+ grpc_socket_mutator* mutator = nullptr;
GPR_ASSERT(fd >= 0);
@@ -79,16 +80,11 @@ static grpc_error* prepare_socket(const grpc_resolved_address* addr, int fd,
}
err = grpc_set_socket_no_sigpipe_if_possible(fd);
if (err != GRPC_ERROR_NONE) goto error;
- if (channel_args) {
- for (size_t i = 0; i < channel_args->num_args; i++) {
- if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_SOCKET_MUTATOR)) {
- GPR_ASSERT(channel_args->args[i].type == GRPC_ARG_POINTER);
- grpc_socket_mutator* mutator = static_cast<grpc_socket_mutator*>(
- channel_args->args[i].value.pointer.p);
- err = grpc_set_socket_with_mutator(fd, mutator);
- if (err != GRPC_ERROR_NONE) goto error;
- }
- }
+ mutator = grpc_channel_args_get_pointer<grpc_socket_mutator>(
+ channel_args, GRPC_ARG_SOCKET_MUTATOR);
+ if (mutator != nullptr) {
+ err = grpc_set_socket_with_mutator(fd, mutator);
+ if (err != GRPC_ERROR_NONE) goto error;
}
goto done;
@@ -211,8 +207,7 @@ static void on_writable(void* acp, grpc_error* error) {
finish:
if (fd != nullptr) {
grpc_pollset_set_del_fd(ac->interested_parties, fd);
- grpc_fd_orphan(fd, nullptr, nullptr, false /* already_closed */,
- "tcp_client_orphan");
+ grpc_fd_orphan(fd, nullptr, nullptr, "tcp_client_orphan");
fd = nullptr;
}
done = (--ac->refs == 0);
@@ -280,7 +275,7 @@ grpc_error* grpc_tcp_client_prepare_fd(const grpc_channel_args* channel_args,
}
addr_str = grpc_sockaddr_to_uri(mapped_addr);
gpr_asprintf(&name, "tcp-client:%s", addr_str);
- *fdobj = grpc_fd_create(fd, name);
+ *fdobj = grpc_fd_create(fd, name, false);
gpr_free(name);
gpr_free(addr_str);
return GRPC_ERROR_NONE;
@@ -305,8 +300,7 @@ void grpc_tcp_client_create_from_prepared_fd(
return;
}
if (errno != EWOULDBLOCK && errno != EINPROGRESS) {
- grpc_fd_orphan(fdobj, nullptr, nullptr, false /* already_closed */,
- "tcp_client_connect_error");
+ grpc_fd_orphan(fdobj, nullptr, nullptr, "tcp_client_connect_error");
GRPC_CLOSURE_SCHED(closure, GRPC_OS_ERROR(errno, "connect"));
return;
}
diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc
index b79ffe20f1..9df2e206b2 100644
--- a/src/core/lib/iomgr/tcp_posix.cc
+++ b/src/core/lib/iomgr/tcp_posix.cc
@@ -20,7 +20,7 @@
#include "src/core/lib/iomgr/port.h"
-#ifdef GRPC_POSIX_SOCKET
+#ifdef GRPC_POSIX_SOCKET_TCP
#include "src/core/lib/iomgr/network_status_tracker.h"
#include "src/core/lib/iomgr/tcp_posix.h"
@@ -70,7 +70,9 @@ struct grpc_tcp {
grpc_endpoint base;
grpc_fd* em_fd;
int fd;
- bool finished_edge;
+ /* Used by the endpoint read function to distinguish the very first read call
+ * from the rest */
+ bool is_first_read;
double target_length;
double bytes_read_this_round;
gpr_refcount refcount;
@@ -295,7 +297,7 @@ static void tcp_shutdown(grpc_endpoint* ep, grpc_error* why) {
static void tcp_free(grpc_tcp* tcp) {
grpc_fd_orphan(tcp->em_fd, tcp->release_fd_cb, tcp->release_fd,
- false /* already_closed */, "tcp_unref_orphan");
+ "tcp_unref_orphan");
grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer);
grpc_resource_user_unref(tcp->resource_user);
gpr_free(tcp->peer_string);
@@ -377,7 +379,6 @@ static void tcp_do_read(grpc_tcp* tcp) {
ssize_t read_bytes;
size_t i;
- GPR_ASSERT(!tcp->finished_edge);
GPR_ASSERT(tcp->incoming_buffer->count <= MAX_READ_IOVEC);
for (i = 0; i < tcp->incoming_buffer->count; i++) {
@@ -473,7 +474,6 @@ static void tcp_continue_read(grpc_tcp* tcp) {
static void tcp_handle_read(void* arg /* grpc_tcp */, grpc_error* error) {
grpc_tcp* tcp = static_cast<grpc_tcp*>(arg);
- GPR_ASSERT(!tcp->finished_edge);
if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_INFO, "TCP:%p got_read: %s", tcp, grpc_error_string(error));
}
@@ -497,10 +497,17 @@ static void tcp_read(grpc_endpoint* ep, grpc_slice_buffer* incoming_buffer,
grpc_slice_buffer_reset_and_unref_internal(incoming_buffer);
grpc_slice_buffer_swap(incoming_buffer, &tcp->last_read_buffer);
TCP_REF(tcp, "read");
- if (tcp->finished_edge) {
- tcp->finished_edge = false;
+ if (tcp->is_first_read) {
+ /* Endpoint read called for the very first time. Register read callback with
+ * the polling engine */
+ tcp->is_first_read = false;
notify_on_read(tcp);
} else {
+ /* Not the first time. We may or may not have more bytes available. In any
+ * case call tcp->read_done_closure (i.e tcp_handle_read()) which does the
+ * right thing (i.e calls tcp_do_read() which either reads the available
+ * bytes or calls notify_on_read() to be notified when new bytes become
+ * available */
GRPC_CLOSURE_SCHED(&tcp->read_done_closure, GRPC_ERROR_NONE);
}
}
@@ -778,7 +785,8 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd,
tcp->min_read_chunk_size = tcp_min_read_chunk_size;
tcp->max_read_chunk_size = tcp_max_read_chunk_size;
tcp->bytes_read_this_round = 0;
- tcp->finished_edge = true;
+ /* Will be set to false by the very first endpoint read function */
+ tcp->is_first_read = true;
/* paired with unref in grpc_tcp_destroy */
gpr_ref_init(&tcp->refcount, 1);
gpr_atm_no_barrier_store(&tcp->shutdown_count, 0);
@@ -811,4 +819,4 @@ void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd,
TCP_UNREF(tcp, "destroy");
}
-#endif
+#endif /* GRPC_POSIX_SOCKET_TCP */
diff --git a/src/core/lib/iomgr/tcp_server_custom.cc b/src/core/lib/iomgr/tcp_server_custom.cc
index 019b354473..a3496de336 100644
--- a/src/core/lib/iomgr/tcp_server_custom.cc
+++ b/src/core/lib/iomgr/tcp_server_custom.cc
@@ -26,6 +26,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/iomgr_custom.h"
@@ -80,21 +81,9 @@ static grpc_error* tcp_server_create(grpc_closure* shutdown_complete,
const grpc_channel_args* args,
grpc_tcp_server** server) {
grpc_tcp_server* s = (grpc_tcp_server*)gpr_malloc(sizeof(grpc_tcp_server));
- s->resource_quota = grpc_resource_quota_create(nullptr);
- for (size_t i = 0; i < (args == nullptr ? 0 : args->num_args); i++) {
- if (0 == strcmp(GRPC_ARG_RESOURCE_QUOTA, args->args[i].key)) {
- if (args->args[i].type == GRPC_ARG_POINTER) {
- grpc_resource_quota_unref_internal(s->resource_quota);
- s->resource_quota = grpc_resource_quota_ref_internal(
- (grpc_resource_quota*)args->args[i].value.pointer.p);
- } else {
- grpc_resource_quota_unref_internal(s->resource_quota);
- gpr_free(s);
- return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- GRPC_ARG_RESOURCE_QUOTA " must be a pointer to a buffer pool");
- }
- }
- }
+ grpc_resource_quota* rq = grpc_channel_args_get_pointer<grpc_resource_quota>(
+ args, GRPC_ARG_RESOURCE_QUOTA);
+ s->resource_quota = rq == nullptr ? grpc_resource_quota_create(nullptr) : rq;
gpr_ref_init(&s->refs, 1);
s->on_accept_cb = nullptr;
s->on_accept_cb_arg = nullptr;
diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc
index 484d2b6077..0a9b4bfd5f 100644
--- a/src/core/lib/iomgr/tcp_server_posix.cc
+++ b/src/core/lib/iomgr/tcp_server_posix.cc
@@ -25,7 +25,7 @@
#include "src/core/lib/iomgr/port.h"
-#ifdef GRPC_POSIX_SOCKET
+#ifdef GRPC_POSIX_SOCKET_TCP_SERVER
#include "src/core/lib/iomgr/tcp_server.h"
@@ -64,22 +64,11 @@ static grpc_error* tcp_server_create(grpc_closure* shutdown_complete,
s->expand_wildcard_addrs = false;
for (size_t i = 0; i < (args == nullptr ? 0 : args->num_args); i++) {
if (0 == strcmp(GRPC_ARG_ALLOW_REUSEPORT, args->args[i].key)) {
- if (args->args[i].type == GRPC_ARG_INTEGER) {
- s->so_reuseport = grpc_is_socket_reuse_port_supported() &&
- (args->args[i].value.integer != 0);
- } else {
- gpr_free(s);
- return GRPC_ERROR_CREATE_FROM_STATIC_STRING(GRPC_ARG_ALLOW_REUSEPORT
- " must be an integer");
- }
+ s->so_reuseport = grpc_channel_arg_get_bool(
+ &args->args[i], grpc_is_socket_reuse_port_supported());
} else if (0 == strcmp(GRPC_ARG_EXPAND_WILDCARD_ADDRS, args->args[i].key)) {
- if (args->args[i].type == GRPC_ARG_INTEGER) {
- s->expand_wildcard_addrs = (args->args[i].value.integer != 0);
- } else {
- gpr_free(s);
- return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- GRPC_ARG_EXPAND_WILDCARD_ADDRS " must be an integer");
- }
+ s->expand_wildcard_addrs =
+ grpc_channel_arg_get_bool(&args->args[i], false);
}
}
gpr_ref_init(&s->refs, 1);
@@ -150,7 +139,7 @@ static void deactivated_all_ports(grpc_tcp_server* s) {
GRPC_CLOSURE_INIT(&sp->destroyed_closure, destroyed_port, s,
grpc_schedule_on_exec_ctx);
grpc_fd_orphan(sp->emfd, &sp->destroyed_closure, nullptr,
- false /* already_closed */, "tcp_listener_shutdown");
+ "tcp_listener_shutdown");
}
gpr_mu_unlock(&s->mu);
} else {
@@ -226,7 +215,7 @@ static void on_read(void* arg, grpc_error* err) {
gpr_log(GPR_INFO, "SERVER_CONNECT: incoming connection: %s", addr_str);
}
- grpc_fd* fdobj = grpc_fd_create(fd, name);
+ grpc_fd* fdobj = grpc_fd_create(fd, name, false);
read_notifier_pollset =
sp->server->pollsets[static_cast<size_t>(gpr_atm_no_barrier_fetch_add(
@@ -362,7 +351,7 @@ static grpc_error* clone_port(grpc_tcp_listener* listener, unsigned count) {
listener->sibling = sp;
sp->server = listener->server;
sp->fd = fd;
- sp->emfd = grpc_fd_create(fd, name);
+ sp->emfd = grpc_fd_create(fd, name, false);
memcpy(&sp->addr, &listener->addr, sizeof(grpc_resolved_address));
sp->port = port;
sp->port_index = listener->port_index;
@@ -559,4 +548,4 @@ grpc_tcp_server_vtable grpc_posix_tcp_server_vtable = {
tcp_server_shutdown_starting_add,
tcp_server_unref,
tcp_server_shutdown_listeners};
-#endif
+#endif /* GRPC_POSIX_SOCKET_TCP_SERVER */
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
index 2d95aa66d6..8c254d587b 100644
--- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
+++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
@@ -20,7 +20,7 @@
#include "src/core/lib/iomgr/port.h"
-#ifdef GRPC_POSIX_SOCKET
+#ifdef GRPC_POSIX_SOCKET_TCP_SERVER_UTILS_COMMON
#include "src/core/lib/iomgr/tcp_server_utils_posix.h"
@@ -34,6 +34,7 @@
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
+#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -105,7 +106,7 @@ static grpc_error* add_socket_to_server(grpc_tcp_server* s, int fd,
s->tail = sp;
sp->server = s;
sp->fd = fd;
- sp->emfd = grpc_fd_create(fd, name);
+ sp->emfd = grpc_fd_create(fd, name, false);
memcpy(&sp->addr, addr, sizeof(grpc_resolved_address));
sp->port = port;
sp->port_index = port_index;
@@ -149,6 +150,7 @@ grpc_error* grpc_tcp_server_prepare_socket(grpc_tcp_server* s, int fd,
bool so_reuseport, int* port) {
grpc_resolved_address sockname_temp;
grpc_error* err = GRPC_ERROR_NONE;
+ grpc_socket_mutator* mutator = nullptr;
GPR_ASSERT(fd >= 0);
@@ -169,17 +171,11 @@ grpc_error* grpc_tcp_server_prepare_socket(grpc_tcp_server* s, int fd,
}
err = grpc_set_socket_no_sigpipe_if_possible(fd);
if (err != GRPC_ERROR_NONE) goto error;
-
- if (s->channel_args) {
- for (size_t i = 0; i < s->channel_args->num_args; i++) {
- if (0 == strcmp(s->channel_args->args[i].key, GRPC_ARG_SOCKET_MUTATOR)) {
- GPR_ASSERT(s->channel_args->args[i].type == GRPC_ARG_POINTER);
- grpc_socket_mutator* mutator = static_cast<grpc_socket_mutator*>(
- s->channel_args->args[i].value.pointer.p);
- err = grpc_set_socket_with_mutator(fd, mutator);
- if (err != GRPC_ERROR_NONE) goto error;
- }
- }
+ mutator = grpc_channel_args_get_pointer<grpc_socket_mutator>(
+ s->channel_args, GRPC_ARG_SOCKET_MUTATOR);
+ if (mutator != nullptr) {
+ err = grpc_set_socket_with_mutator(fd, mutator);
+ if (err != GRPC_ERROR_NONE) goto error;
}
if (bind(fd, reinterpret_cast<grpc_sockaddr*>(const_cast<char*>(addr->addr)),
@@ -217,4 +213,4 @@ error:
return ret;
}
-#endif /* GRPC_POSIX_SOCKET */
+#endif /* GRPC_POSIX_SOCKET_TCP_SERVER_UTILS_COMMON */
diff --git a/src/core/lib/iomgr/udp_server.cc b/src/core/lib/iomgr/udp_server.cc
index 51d17eb174..99af977da3 100644
--- a/src/core/lib/iomgr/udp_server.cc
+++ b/src/core/lib/iomgr/udp_server.cc
@@ -152,7 +152,7 @@ GrpcUdpListener::GrpcUdpListener(grpc_udp_server* server, int fd,
grpc_sockaddr_to_string(&addr_str, addr, 1);
gpr_asprintf(&name, "udp-server-listener:%s", addr_str);
gpr_free(addr_str);
- emfd_ = grpc_fd_create(fd, name);
+ emfd_ = grpc_fd_create(fd, name, false);
memcpy(&addr_, addr, sizeof(grpc_resolved_address));
GPR_ASSERT(emfd_);
gpr_free(name);
@@ -197,14 +197,8 @@ struct grpc_udp_server {
};
static grpc_socket_factory* get_socket_factory(const grpc_channel_args* args) {
- if (args) {
- const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_SOCKET_FACTORY);
- if (arg) {
- GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
- return static_cast<grpc_socket_factory*>(arg->value.pointer.p);
- }
- }
- return nullptr;
+ return grpc_channel_args_get_pointer<grpc_socket_factory>(
+ args, GRPC_ARG_SOCKET_FACTORY);
}
grpc_udp_server* grpc_udp_server_create(const grpc_channel_args* args) {
@@ -300,8 +294,7 @@ void GrpcUdpListener::OrphanFd() {
grpc_schedule_on_exec_ctx);
/* Because at this point, all listening sockets have been shutdown already, no
* need to call OnFdAboutToOrphan() to notify the handler again. */
- grpc_fd_orphan(emfd_, &destroyed_closure_, nullptr,
- false /* already_closed */, "udp_listener_shutdown");
+ grpc_fd_orphan(emfd_, &destroyed_closure_, nullptr, "udp_listener_shutdown");
}
void grpc_udp_server_destroy(grpc_udp_server* s, grpc_closure* on_done) {
diff --git a/src/core/lib/security/context/security_context.cc b/src/core/lib/security/context/security_context.cc
index 14051a3f00..1f93416b23 100644
--- a/src/core/lib/security/context/security_context.cc
+++ b/src/core/lib/security/context/security_context.cc
@@ -326,23 +326,8 @@ grpc_arg grpc_auth_context_to_arg(grpc_auth_context* p) {
&auth_context_pointer_vtable);
}
-grpc_auth_context* grpc_auth_context_from_arg(const grpc_arg* arg) {
- if (strcmp(arg->key, GRPC_AUTH_CONTEXT_ARG) != 0) return nullptr;
- if (arg->type != GRPC_ARG_POINTER) {
- gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
- GRPC_AUTH_CONTEXT_ARG);
- return nullptr;
- }
- return static_cast<grpc_auth_context*>(arg->value.pointer.p);
-}
-
grpc_auth_context* grpc_find_auth_context_in_args(
- const grpc_channel_args* args) {
- size_t i;
- if (args == nullptr) return nullptr;
- for (i = 0; i < args->num_args; i++) {
- grpc_auth_context* p = grpc_auth_context_from_arg(&args->args[i]);
- if (p != nullptr) return p;
- }
- return nullptr;
+ const grpc_channel_args* channel_args) {
+ return grpc_channel_args_get_pointer<grpc_auth_context>(
+ channel_args, GRPC_AUTH_CONTEXT_ARG);
}
diff --git a/src/core/lib/security/context/security_context.h b/src/core/lib/security/context/security_context.h
index e782e4f28f..2f73a5482c 100644
--- a/src/core/lib/security/context/security_context.h
+++ b/src/core/lib/security/context/security_context.h
@@ -108,7 +108,6 @@ void grpc_server_security_context_destroy(void* ctx);
#define GRPC_AUTH_CONTEXT_ARG "grpc.auth_context"
grpc_arg grpc_auth_context_to_arg(grpc_auth_context* c);
-grpc_auth_context* grpc_auth_context_from_arg(const grpc_arg* arg);
grpc_auth_context* grpc_find_auth_context_in_args(
const grpc_channel_args* args);
diff --git a/src/core/lib/security/credentials/credentials.cc b/src/core/lib/security/credentials/credentials.cc
index c43cb440eb..edeea29327 100644
--- a/src/core/lib/security/credentials/credentials.cc
+++ b/src/core/lib/security/credentials/credentials.cc
@@ -168,27 +168,10 @@ grpc_arg grpc_channel_credentials_to_arg(
&credentials_pointer_vtable);
}
-grpc_channel_credentials* grpc_channel_credentials_from_arg(
- const grpc_arg* arg) {
- if (strcmp(arg->key, GRPC_ARG_CHANNEL_CREDENTIALS)) return nullptr;
- if (arg->type != GRPC_ARG_POINTER) {
- gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
- GRPC_ARG_CHANNEL_CREDENTIALS);
- return nullptr;
- }
- return static_cast<grpc_channel_credentials*>(arg->value.pointer.p);
-}
-
grpc_channel_credentials* grpc_channel_credentials_find_in_args(
- const grpc_channel_args* args) {
- size_t i;
- if (args == nullptr) return nullptr;
- for (i = 0; i < args->num_args; i++) {
- grpc_channel_credentials* credentials =
- grpc_channel_credentials_from_arg(&args->args[i]);
- if (credentials != nullptr) return credentials;
- }
- return nullptr;
+ const grpc_channel_args* channel_args) {
+ return grpc_channel_args_get_pointer<grpc_channel_credentials>(
+ channel_args, GRPC_ARG_CHANNEL_CREDENTIALS);
}
grpc_server_credentials* grpc_server_credentials_ref(
@@ -263,24 +246,8 @@ grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials* p) {
&cred_ptr_vtable);
}
-grpc_server_credentials* grpc_server_credentials_from_arg(const grpc_arg* arg) {
- if (strcmp(arg->key, GRPC_SERVER_CREDENTIALS_ARG) != 0) return nullptr;
- if (arg->type != GRPC_ARG_POINTER) {
- gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
- GRPC_SERVER_CREDENTIALS_ARG);
- return nullptr;
- }
- return static_cast<grpc_server_credentials*>(arg->value.pointer.p);
-}
-
grpc_server_credentials* grpc_find_server_credentials_in_args(
- const grpc_channel_args* args) {
- size_t i;
- if (args == nullptr) return nullptr;
- for (i = 0; i < args->num_args; i++) {
- grpc_server_credentials* p =
- grpc_server_credentials_from_arg(&args->args[i]);
- if (p != nullptr) return p;
- }
- return nullptr;
+ const grpc_channel_args* channel_args) {
+ return grpc_channel_args_get_pointer<grpc_server_credentials>(
+ channel_args, GRPC_SERVER_CREDENTIALS_ARG);
}
diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h
index b486d25ab2..ba380283cc 100644
--- a/src/core/lib/security/credentials/credentials.h
+++ b/src/core/lib/security/credentials/credentials.h
@@ -131,10 +131,6 @@ grpc_channel_credentials_duplicate_without_call_credentials(
/* Util to encapsulate the channel credentials in a channel arg. */
grpc_arg grpc_channel_credentials_to_arg(grpc_channel_credentials* credentials);
-/* Util to get the channel credentials from a channel arg. */
-grpc_channel_credentials* grpc_channel_credentials_from_arg(
- const grpc_arg* arg);
-
/* Util to find the channel credentials from channel args. */
grpc_channel_credentials* grpc_channel_credentials_find_in_args(
const grpc_channel_args* args);
@@ -227,7 +223,6 @@ void grpc_server_credentials_unref(grpc_server_credentials* creds);
#define GRPC_SERVER_CREDENTIALS_ARG "grpc.server_credentials"
grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials* c);
-grpc_server_credentials* grpc_server_credentials_from_arg(const grpc_arg* arg);
grpc_server_credentials* grpc_find_server_credentials_in_args(
const grpc_channel_args* args);
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.cc b/src/core/lib/security/credentials/fake/fake_credentials.cc
index 858ab6b41b..08321a85c6 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.cc
+++ b/src/core/lib/security/credentials/fake/fake_credentials.cc
@@ -84,9 +84,8 @@ grpc_arg grpc_fake_transport_expected_targets_arg(char* expected_targets) {
const char* grpc_fake_transport_get_expected_targets(
const grpc_channel_args* args) {
- const grpc_arg* expected_target_arg =
- grpc_channel_args_find(args, GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS);
- return grpc_channel_arg_get_string(expected_target_arg);
+ return grpc_channel_args_get_string(args,
+ GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS);
}
/* -- Metadata-only test credentials. -- */
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
index 38c9175717..fa565d4ef8 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
@@ -79,13 +79,10 @@ static grpc_security_status google_default_create_security_connector(
grpc_channel_security_connector** sc, grpc_channel_args** new_args) {
grpc_google_default_channel_credentials* c =
reinterpret_cast<grpc_google_default_channel_credentials*>(creds);
- bool is_grpclb_load_balancer = grpc_channel_arg_get_bool(
- grpc_channel_args_find(args, GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER),
- false);
- bool is_backend_from_grpclb_load_balancer = grpc_channel_arg_get_bool(
- grpc_channel_args_find(
- args, GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER),
- false);
+ bool is_grpclb_load_balancer = grpc_channel_args_get_bool(
+ args, GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER, false);
+ bool is_backend_from_grpclb_load_balancer = grpc_channel_args_get_bool(
+ args, GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER, false);
bool use_alts =
is_grpclb_load_balancer || is_backend_from_grpclb_load_balancer;
grpc_security_status status = GRPC_SECURITY_ERROR;
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
index 2129029737..43dd68e874 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
@@ -219,9 +219,11 @@ static void on_oauth2_token_fetcher_http_response(void* user_data,
gpr_mu_lock(&c->mu);
c->token_fetch_pending = false;
c->access_token_md = GRPC_MDELEM_REF(access_token_md);
- c->token_expiration = status == GRPC_CREDENTIALS_OK
- ? grpc_core::ExecCtx::Get()->Now() + token_lifetime
- : 0;
+ c->token_expiration =
+ status == GRPC_CREDENTIALS_OK
+ ? gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+ gpr_time_from_millis(token_lifetime, GPR_TIMESPAN))
+ : gpr_inf_past(GPR_CLOCK_MONOTONIC);
grpc_oauth2_pending_get_request_metadata* pending_request =
c->pending_requests;
c->pending_requests = nullptr;
@@ -259,8 +261,10 @@ static bool oauth2_token_fetcher_get_request_metadata(
grpc_mdelem cached_access_token_md = GRPC_MDNULL;
gpr_mu_lock(&c->mu);
if (!GRPC_MDISNULL(c->access_token_md) &&
- (c->token_expiration - grpc_core::ExecCtx::Get()->Now() >
- refresh_threshold)) {
+ gpr_time_cmp(
+ gpr_time_sub(c->token_expiration, gpr_now(GPR_CLOCK_MONOTONIC)),
+ gpr_time_from_seconds(GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS,
+ GPR_TIMESPAN)) > 0) {
cached_access_token_md = GRPC_MDELEM_REF(c->access_token_md);
}
if (!GRPC_MDISNULL(cached_access_token_md)) {
@@ -333,7 +337,7 @@ static void init_oauth2_token_fetcher(grpc_oauth2_token_fetcher_credentials* c,
c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
gpr_ref_init(&c->base.refcount, 1);
gpr_mu_init(&c->mu);
- c->token_expiration = 0;
+ c->token_expiration = gpr_inf_past(GPR_CLOCK_MONOTONIC);
c->fetch_func = fetch_func;
c->pollent =
grpc_polling_entity_create_from_pollset_set(grpc_pollset_set_create());
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
index c0dd1546e3..12a1d4484f 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
@@ -71,7 +71,7 @@ typedef struct {
grpc_call_credentials base;
gpr_mu mu;
grpc_mdelem access_token_md;
- grpc_millis token_expiration;
+ gpr_timespec token_expiration;
bool token_fetch_pending;
grpc_oauth2_pending_get_request_metadata* pending_requests;
grpc_httpcli_context httpcli_context;
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.cc b/src/core/lib/security/credentials/ssl/ssl_credentials.cc
index 2b6377d3ec..13dae19b4b 100644
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.cc
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.cc
@@ -60,14 +60,12 @@ static grpc_security_status ssl_create_security_connector(
tsi_ssl_session_cache* ssl_session_cache = nullptr;
for (size_t i = 0; args && i < args->num_args; i++) {
grpc_arg* arg = &args->args[i];
- if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 &&
- arg->type == GRPC_ARG_STRING) {
- overridden_target_name = arg->value.string;
+ if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0) {
+ overridden_target_name = grpc_channel_arg_get_string(arg);
}
- if (strcmp(arg->key, GRPC_SSL_SESSION_CACHE_ARG) == 0 &&
- arg->type == GRPC_ARG_POINTER) {
+ if (strcmp(arg->key, GRPC_SSL_SESSION_CACHE_ARG) == 0) {
ssl_session_cache =
- static_cast<tsi_ssl_session_cache*>(arg->value.pointer.p);
+ grpc_channel_arg_get_pointer<tsi_ssl_session_cache>(arg);
}
}
status = grpc_ssl_channel_security_connector_create(
diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc
index b54a7643e4..ea001d453d 100644
--- a/src/core/lib/security/security_connector/security_connector.cc
+++ b/src/core/lib/security/security_connector/security_connector.cc
@@ -255,26 +255,10 @@ grpc_arg grpc_security_connector_to_arg(grpc_security_connector* sc) {
&connector_arg_vtable);
}
-grpc_security_connector* grpc_security_connector_from_arg(const grpc_arg* arg) {
- if (strcmp(arg->key, GRPC_ARG_SECURITY_CONNECTOR)) return nullptr;
- if (arg->type != GRPC_ARG_POINTER) {
- gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
- GRPC_ARG_SECURITY_CONNECTOR);
- return nullptr;
- }
- return static_cast<grpc_security_connector*>(arg->value.pointer.p);
-}
-
grpc_security_connector* grpc_security_connector_find_in_args(
- const grpc_channel_args* args) {
- size_t i;
- if (args == nullptr) return nullptr;
- for (i = 0; i < args->num_args; i++) {
- grpc_security_connector* sc =
- grpc_security_connector_from_arg(&args->args[i]);
- if (sc != nullptr) return sc;
- }
- return nullptr;
+ const grpc_channel_args* channel_args) {
+ return grpc_channel_args_get_pointer<grpc_security_connector>(
+ channel_args, GRPC_ARG_SECURITY_CONNECTOR);
}
static tsi_client_certificate_request_type
diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h
index f9723166d0..9da66ef01d 100644
--- a/src/core/lib/security/security_connector/security_connector.h
+++ b/src/core/lib/security/security_connector/security_connector.h
@@ -99,9 +99,6 @@ int grpc_security_connector_cmp(grpc_security_connector* sc,
/* Util to encapsulate the connector in a channel arg. */
grpc_arg grpc_security_connector_to_arg(grpc_security_connector* sc);
-/* Util to get the connector from a channel arg. */
-grpc_security_connector* grpc_security_connector_from_arg(const grpc_arg* arg);
-
/* Util to find the connector from channel args. */
grpc_security_connector* grpc_security_connector_find_in_args(
const grpc_channel_args* args);
diff --git a/src/core/lib/security/transport/target_authority_table.cc b/src/core/lib/security/transport/target_authority_table.cc
index 1eeb557f6a..467e681a50 100644
--- a/src/core/lib/security/transport/target_authority_table.cc
+++ b/src/core/lib/security/transport/target_authority_table.cc
@@ -59,17 +59,8 @@ grpc_arg CreateTargetAuthorityTableChannelArg(TargetAuthorityTable* table) {
TargetAuthorityTable* FindTargetAuthorityTableInArgs(
const grpc_channel_args* args) {
- const grpc_arg* arg =
- grpc_channel_args_find(args, GRPC_ARG_TARGET_AUTHORITY_TABLE);
- if (arg != nullptr) {
- if (arg->type == GRPC_ARG_POINTER) {
- return static_cast<TargetAuthorityTable*>(arg->value.pointer.p);
- } else {
- gpr_log(GPR_ERROR, "value of " GRPC_ARG_TARGET_AUTHORITY_TABLE
- " channel arg was not pointer type; ignoring");
- }
- }
- return nullptr;
+ return grpc_channel_args_get_pointer<TargetAuthorityTable>(
+ args, GRPC_ARG_TARGET_AUTHORITY_TABLE);
}
} // namespace grpc_core
diff --git a/src/core/lib/security/util/json_util.cc b/src/core/lib/security/util/json_util.cc
index 75512a19c9..fe9f5fe3d3 100644
--- a/src/core/lib/security/util/json_util.cc
+++ b/src/core/lib/security/util/json_util.cc
@@ -29,6 +29,10 @@ const char* grpc_json_get_string_property(const grpc_json* json,
const char* prop_name) {
grpc_json* child;
for (child = json->child; child != nullptr; child = child->next) {
+ if (child->key == nullptr) {
+ gpr_log(GPR_ERROR, "Invalid (null) JSON key encountered");
+ return nullptr;
+ }
if (strcmp(child->key, prop_name) == 0) break;
}
if (child == nullptr || child->type != GRPC_JSON_STRING) {
diff --git a/src/core/lib/slice/slice_buffer.cc b/src/core/lib/slice/slice_buffer.cc
index fd56997388..1f1c08b159 100644
--- a/src/core/lib/slice/slice_buffer.cc
+++ b/src/core/lib/slice/slice_buffer.cc
@@ -333,14 +333,26 @@ void grpc_slice_buffer_trim_end(grpc_slice_buffer* sb, size_t n,
size_t slice_len = GRPC_SLICE_LENGTH(slice);
if (slice_len > n) {
sb->slices[idx] = grpc_slice_split_head(&slice, slice_len - n);
- grpc_slice_buffer_add_indexed(garbage, slice);
+ if (garbage) {
+ grpc_slice_buffer_add_indexed(garbage, slice);
+ } else {
+ grpc_slice_unref_internal(slice);
+ }
return;
} else if (slice_len == n) {
- grpc_slice_buffer_add_indexed(garbage, slice);
+ if (garbage) {
+ grpc_slice_buffer_add_indexed(garbage, slice);
+ } else {
+ grpc_slice_unref_internal(slice);
+ }
sb->count = idx;
return;
} else {
- grpc_slice_buffer_add_indexed(garbage, slice);
+ if (garbage) {
+ grpc_slice_buffer_add_indexed(garbage, slice);
+ } else {
+ grpc_slice_unref_internal(slice);
+ }
n -= slice_len;
sb->count = idx;
}
diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc
index 86e0afa6ee..1cf8ea94e7 100644
--- a/src/core/lib/surface/call.cc
+++ b/src/core/lib/surface/call.cc
@@ -516,7 +516,6 @@ static void release_call(void* call, grpc_error* error) {
grpc_call* c = static_cast<grpc_call*>(call);
grpc_channel* channel = c->channel;
grpc_call_combiner_destroy(&c->call_combiner);
- gpr_free((char*)c->peer_string);
grpc_channel_update_call_size_estimate(channel, gpr_arena_destroy(c->arena));
GRPC_CHANNEL_INTERNAL_UNREF(channel, "call");
}
diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc
index 6b41e4b37e..039d603394 100644
--- a/src/core/lib/transport/transport.cc
+++ b/src/core/lib/transport/transport.cc
@@ -184,7 +184,8 @@ void grpc_transport_set_pops(grpc_transport* transport, grpc_stream* stream,
nullptr) {
transport->vtable->set_pollset_set(transport, stream, pollset_set);
} else {
- abort();
+ // No-op for empty pollset. Empty pollset is possible when using
+ // non-fd-based event engines such as CFStream.
}
}
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index 10e9df0f7c..b2e252d939 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -168,13 +168,11 @@ struct grpc_transport_stream_op_batch_payload {
/** Iff send_initial_metadata != NULL, flags associated with
send_initial_metadata: a bitfield of GRPC_INITIAL_METADATA_xxx */
uint32_t send_initial_metadata_flags;
- // If non-NULL, will be set by the transport to the peer string
- // (a char*, which the caller takes ownership of).
+ // If non-NULL, will be set by the transport to the peer string (a char*).
+ // The transport retains ownership of the string.
// Note: This pointer may be used by the transport after the
// send_initial_metadata op is completed. It must remain valid
// until the call is destroyed.
- // Note: When a transport sets this, it must free the previous
- // value, if any.
gpr_atm* peer_string;
} send_initial_metadata;
@@ -202,13 +200,11 @@ struct grpc_transport_stream_op_batch_payload {
// immediately available. This may be a signal that we received a
// Trailers-Only response.
bool* trailing_metadata_available;
- // If non-NULL, will be set by the transport to the peer string
- // (a char*, which the caller takes ownership of).
+ // If non-NULL, will be set by the transport to the peer string (a char*).
+ // The transport retains ownership of the string.
// Note: This pointer may be used by the transport after the
// recv_initial_metadata op is completed. It must remain valid
// until the call is destroyed.
- // Note: When a transport sets this, it must free the previous
- // value, if any.
gpr_atm* peer_string;
} recv_initial_metadata;
diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc
index 8065a8b185..e66fc9ba03 100644
--- a/src/core/tsi/ssl_transport_security.cc
+++ b/src/core/tsi/ssl_transport_security.cc
@@ -260,14 +260,13 @@ static tsi_result ssl_get_x509_common_name(X509* cert, unsigned char** utf8,
X509_NAME* subject_name = X509_get_subject_name(cert);
int utf8_returned_size = 0;
if (subject_name == nullptr) {
- gpr_log(GPR_ERROR, "Could not get subject name from certificate.");
+ gpr_log(GPR_INFO, "Could not get subject name from certificate.");
return TSI_NOT_FOUND;
}
common_name_index =
X509_NAME_get_index_by_NID(subject_name, NID_commonName, -1);
if (common_name_index == -1) {
- gpr_log(GPR_ERROR,
- "Could not get common name of subject from certificate.");
+ gpr_log(GPR_INFO, "Could not get common name of subject from certificate.");
return TSI_NOT_FOUND;
}
common_name_entry = X509_NAME_get_entry(subject_name, common_name_index);
diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc
index e951801965..7f5b439dfb 100644
--- a/src/cpp/server/server_builder.cc
+++ b/src/cpp/server/server_builder.cc
@@ -39,8 +39,8 @@ static void do_plugin_list_init(void) {
}
ServerBuilder::ServerBuilder()
- : max_receive_message_size_(-1),
- max_send_message_size_(-1),
+ : max_receive_message_size_(INT_MIN),
+ max_send_message_size_(INT_MIN),
sync_server_settings_(SyncServerSettings()),
resource_quota_(nullptr),
generic_service_(nullptr) {
@@ -186,10 +186,12 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
(*plugin)->UpdateChannelArguments(&args);
}
- if (max_receive_message_size_ >= 0) {
+ if (max_receive_message_size_ >= -1) {
args.SetInt(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, max_receive_message_size_);
}
+ // The default message size is -1 (max), so no need to explicitly set it for
+ // -1.
if (max_send_message_size_ >= 0) {
args.SetInt(GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, max_send_message_size_);
}
diff --git a/src/csharp/Grpc.Core.NativeDebug.nuspec b/src/csharp/Grpc.Core.NativeDebug.nuspec
new file mode 100644
index 0000000000..d4bb8ad223
--- /dev/null
+++ b/src/csharp/Grpc.Core.NativeDebug.nuspec
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<package>
+ <metadata>
+ <id>Grpc.Core.NativeDebug</id>
+ <title>Grpc.Core: Native Debug Symbols</title>
+ <summary>Debug symbols for the native library contained in Grpc.Core</summary>
+ <description>Currently contains grpc_csharp_ext.pdb</description>
+ <version>$version$</version>
+ <authors>Google Inc.</authors>
+ <owners>grpc-packages</owners>
+ <licenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</licenseUrl>
+ <projectUrl>https://github.com/grpc/grpc</projectUrl>
+ <requireLicenseAcceptance>false</requireLicenseAcceptance>
+ <releaseNotes>Release $version$</releaseNotes>
+ <copyright>Copyright 2015, Google Inc.</copyright>
+ <tags>gRPC RPC Protocol HTTP/2</tags>
+ </metadata>
+ <files>
+ <!-- forward slashes in src path enable building on Linux -->
+ <file src="nativelibs/csharp_ext_windows_x86/grpc_csharp_ext.dll" target="runtimes/win/native/grpc_csharp_ext.x86.dll" />
+ <file src="nativelibs/csharp_ext_windows_x86/grpc_csharp_ext.pdb" target="runtimes/win/native/grpc_csharp_ext.x86.pdb" />
+ <file src="nativelibs/csharp_ext_windows_x64/grpc_csharp_ext.dll" target="runtimes/win/native/grpc_csharp_ext.x64.dll" />
+ <file src="nativelibs/csharp_ext_windows_x64/grpc_csharp_ext.pdb" target="runtimes/win/native/grpc_csharp_ext.x64.pdb" />
+ </files>
+</package>
diff --git a/src/csharp/Grpc.Core.Testing/TestCalls.cs b/src/csharp/Grpc.Core.Testing/TestCalls.cs
index ac29a8b974..8c76781bbe 100644
--- a/src/csharp/Grpc.Core.Testing/TestCalls.cs
+++ b/src/csharp/Grpc.Core.Testing/TestCalls.cs
@@ -65,7 +65,7 @@ namespace Grpc.Core.Testing
/// Creates a test double for <c>AsyncDuplexStreamingCall</c>. Only for testing.
/// Note: experimental API that can change or be removed without any prior notice.
/// </summary>
- public static AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TResponse, TRequest>(
+ public static AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(
IClientStreamWriter<TRequest> requestStream, IAsyncStreamReader<TResponse> responseStream,
Task<Metadata> responseHeadersAsync, Func<Status> getStatusFunc,
Func<Metadata> getTrailersFunc, Action disposeAction)
diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
index 3ccc9adfaf..d2cc5bbc65 100755
--- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
+++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
@@ -13,11 +13,13 @@
<ItemGroup>
<ProjectReference Include="../Grpc.Examples/Grpc.Examples.csproj" />
+ <ProjectReference Include="../Grpc.Core.Testing/Grpc.Core.Testing.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NUnit" Version="3.6.0" />
<PackageReference Include="NUnitLite" Version="3.6.0" />
+ <PackageReference Include="Moq" Version="4.8.2" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
diff --git a/src/csharp/Grpc.Examples.Tests/MathClientMockableTest.cs b/src/csharp/Grpc.Examples.Tests/MathClientMockableTest.cs
new file mode 100644
index 0000000000..6ed7b0a937
--- /dev/null
+++ b/src/csharp/Grpc.Examples.Tests/MathClientMockableTest.cs
@@ -0,0 +1,101 @@
+#region Copyright notice and license
+
+// Copyright 2018 The 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.
+
+#endregion
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Testing;
+using NUnit.Framework;
+
+namespace Math.Tests
+{
+ /// <summary>
+ /// Demonstrates how to mock method stubs for all method types in a generated client.
+ /// </summary>
+ public class MathClientMockableTest
+ {
+ [Test]
+ public void ClientBaseBlockingUnaryCallCanBeMocked()
+ {
+ var mockClient = new Moq.Mock<Math.MathClient>();
+
+ var expected = new DivReply();
+ mockClient.Setup(m => m.Div(Moq.It.IsAny<DivArgs>(), null, null, CancellationToken.None)).Returns(expected);
+ Assert.AreSame(expected, mockClient.Object.Div(new DivArgs()));
+ }
+
+ [Test]
+ public void ClientBaseBlockingUnaryCallWithCallOptionsCallCanBeMocked()
+ {
+ var mockClient = new Moq.Mock<Math.MathClient>();
+
+ var expected = new DivReply();
+ mockClient.Setup(m => m.Div(Moq.It.IsAny<DivArgs>(), Moq.It.IsAny<CallOptions>())).Returns(expected);
+ Assert.AreSame(expected, mockClient.Object.Div(new DivArgs(), new CallOptions()));
+ }
+
+ [Test]
+ public void ClientBaseAsyncUnaryCallCanBeMocked()
+ {
+ var mockClient = new Moq.Mock<Math.MathClient>();
+
+ // Use a factory method provided by Grpc.Core.Testing.TestCalls to create an instance of a call.
+ var fakeCall = TestCalls.AsyncUnaryCall<DivReply>(Task.FromResult(new DivReply()), Task.FromResult(new Metadata()), () => Status.DefaultSuccess, () => new Metadata(), () => { });
+ mockClient.Setup(m => m.DivAsync(Moq.It.IsAny<DivArgs>(), null, null, CancellationToken.None)).Returns(fakeCall);
+ Assert.AreSame(fakeCall, mockClient.Object.DivAsync(new DivArgs()));
+ }
+
+ [Test]
+ public void ClientBaseClientStreamingCallCanBeMocked()
+ {
+ var mockClient = new Moq.Mock<Math.MathClient>();
+ var mockRequestStream = new Moq.Mock<IClientStreamWriter<Num>>();
+
+ // Use a factory method provided by Grpc.Core.Testing.TestCalls to create an instance of a call.
+ var fakeCall = TestCalls.AsyncClientStreamingCall<Num, Num>(mockRequestStream.Object, Task.FromResult(new Num()), Task.FromResult(new Metadata()), () => Status.DefaultSuccess, () => new Metadata(), () => { });
+ mockClient.Setup(m => m.Sum(null, null, CancellationToken.None)).Returns(fakeCall);
+ Assert.AreSame(fakeCall, mockClient.Object.Sum());
+ }
+
+ [Test]
+ public void ClientBaseServerStreamingCallCanBeMocked()
+ {
+ var mockClient = new Moq.Mock<Math.MathClient>();
+ var mockResponseStream = new Moq.Mock<IAsyncStreamReader<Num>>();
+
+ // Use a factory method provided by Grpc.Core.Testing.TestCalls to create an instance of a call.
+ var fakeCall = TestCalls.AsyncServerStreamingCall<Num>(mockResponseStream.Object, Task.FromResult(new Metadata()), () => Status.DefaultSuccess, () => new Metadata(), () => { });
+ mockClient.Setup(m => m.Fib(Moq.It.IsAny<FibArgs>(), null, null, CancellationToken.None)).Returns(fakeCall);
+ Assert.AreSame(fakeCall, mockClient.Object.Fib(new FibArgs()));
+ }
+
+ [Test]
+ public void ClientBaseDuplexStreamingCallCanBeMocked()
+ {
+ var mockClient = new Moq.Mock<Math.MathClient>();
+ var mockRequestStream = new Moq.Mock<IClientStreamWriter<DivArgs>>();
+ var mockResponseStream = new Moq.Mock<IAsyncStreamReader<DivReply>>();
+
+ // Use a factory method provided by Grpc.Core.Testing.TestCalls to create an instance of a call.
+ var fakeCall = TestCalls.AsyncDuplexStreamingCall<DivArgs, DivReply>(mockRequestStream.Object, mockResponseStream.Object, Task.FromResult(new Metadata()), () => Status.DefaultSuccess, () => new Metadata(), () => { });
+ mockClient.Setup(m => m.DivMany(null, null, CancellationToken.None)).Returns(fakeCall);
+ Assert.AreSame(fakeCall, mockClient.Object.DivMany());
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Examples.Tests/MathServiceImplTestabilityTest.cs b/src/csharp/Grpc.Examples.Tests/MathServiceImplTestabilityTest.cs
new file mode 100644
index 0000000000..7c5fb94408
--- /dev/null
+++ b/src/csharp/Grpc.Examples.Tests/MathServiceImplTestabilityTest.cs
@@ -0,0 +1,47 @@
+#region Copyright notice and license
+
+// Copyright 2018 The 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.
+
+#endregion
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Testing;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Math.Tests
+{
+ /// <summary>
+ /// Demonstrates how to unit test implementations of generated server stubs.
+ /// </summary>
+ public class MathServiceImplTestabilityTest
+ {
+ [Test]
+ public async Task ServerCallImplIsTestable()
+ {
+ var mathImpl = new MathServiceImpl();
+
+ // Use a factory method provided by Grpc.Core.Testing.TestServerCallContext to create an instance of server call context.
+ // This allows testing even those server-side implementations that rely on the contents of ServerCallContext.
+ var fakeServerCallContext = TestServerCallContext.Create("fooMethod", null, DateTime.UtcNow.AddHours(1), new Metadata(), CancellationToken.None, "127.0.0.1", null, null, (metadata) => TaskUtils.CompletedTask, () => new WriteOptions(), (writeOptions) => { });
+ var response = await mathImpl.Div(new DivArgs { Dividend = 10, Divisor = 2 }, fakeServerCallContext);
+ Assert.AreEqual(5, response.Quotient);
+ Assert.AreEqual(0, response.Remainder);
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index a4739da81d..9578bb4d81 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -27,38 +27,38 @@ namespace Math {
{
static readonly string __ServiceName = "math.Math";
- static readonly grpc::Marshaller<global::Math.DivArgs> __Marshaller_DivArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.DivArgs.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Math.DivReply> __Marshaller_DivReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.DivReply.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Math.FibArgs> __Marshaller_FibArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.FibArgs.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Math.Num> __Marshaller_Num = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.Num.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Math.DivArgs> __Marshaller_math_DivArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.DivArgs.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Math.DivReply> __Marshaller_math_DivReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.DivReply.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Math.FibArgs> __Marshaller_math_FibArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.FibArgs.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Math.Num> __Marshaller_math_Num = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.Num.Parser.ParseFrom);
static readonly grpc::Method<global::Math.DivArgs, global::Math.DivReply> __Method_Div = new grpc::Method<global::Math.DivArgs, global::Math.DivReply>(
grpc::MethodType.Unary,
__ServiceName,
"Div",
- __Marshaller_DivArgs,
- __Marshaller_DivReply);
+ __Marshaller_math_DivArgs,
+ __Marshaller_math_DivReply);
static readonly grpc::Method<global::Math.DivArgs, global::Math.DivReply> __Method_DivMany = new grpc::Method<global::Math.DivArgs, global::Math.DivReply>(
grpc::MethodType.DuplexStreaming,
__ServiceName,
"DivMany",
- __Marshaller_DivArgs,
- __Marshaller_DivReply);
+ __Marshaller_math_DivArgs,
+ __Marshaller_math_DivReply);
static readonly grpc::Method<global::Math.FibArgs, global::Math.Num> __Method_Fib = new grpc::Method<global::Math.FibArgs, global::Math.Num>(
grpc::MethodType.ServerStreaming,
__ServiceName,
"Fib",
- __Marshaller_FibArgs,
- __Marshaller_Num);
+ __Marshaller_math_FibArgs,
+ __Marshaller_math_Num);
static readonly grpc::Method<global::Math.Num, global::Math.Num> __Method_Sum = new grpc::Method<global::Math.Num, global::Math.Num>(
grpc::MethodType.ClientStreaming,
__ServiceName,
"Sum",
- __Marshaller_Num,
- __Marshaller_Num);
+ __Marshaller_math_Num,
+ __Marshaller_math_Num);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index ebd890e48d..5e79c04d2a 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -30,15 +30,15 @@ namespace Grpc.Health.V1 {
{
static readonly string __ServiceName = "grpc.health.v1.Health";
- static readonly grpc::Marshaller<global::Grpc.Health.V1.HealthCheckRequest> __Marshaller_HealthCheckRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1.HealthCheckRequest.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Health.V1.HealthCheckResponse> __Marshaller_HealthCheckResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1.HealthCheckResponse.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Health.V1.HealthCheckRequest> __Marshaller_grpc_health_v1_HealthCheckRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1.HealthCheckRequest.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Health.V1.HealthCheckResponse> __Marshaller_grpc_health_v1_HealthCheckResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1.HealthCheckResponse.Parser.ParseFrom);
static readonly grpc::Method<global::Grpc.Health.V1.HealthCheckRequest, global::Grpc.Health.V1.HealthCheckResponse> __Method_Check = new grpc::Method<global::Grpc.Health.V1.HealthCheckRequest, global::Grpc.Health.V1.HealthCheckResponse>(
grpc::MethodType.Unary,
__ServiceName,
"Check",
- __Marshaller_HealthCheckRequest,
- __Marshaller_HealthCheckResponse);
+ __Marshaller_grpc_health_v1_HealthCheckRequest,
+ __Marshaller_grpc_health_v1_HealthCheckResponse);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs
index e2a4b93cef..b5738593f2 100644
--- a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs
@@ -29,43 +29,43 @@ namespace Grpc.Testing {
{
static readonly string __ServiceName = "grpc.testing.BenchmarkService";
- static readonly grpc::Marshaller<global::Grpc.Testing.SimpleRequest> __Marshaller_SimpleRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleRequest.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.SimpleResponse> __Marshaller_SimpleResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleResponse.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.SimpleRequest> __Marshaller_grpc_testing_SimpleRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleRequest.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.SimpleResponse> __Marshaller_grpc_testing_SimpleResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleResponse.Parser.ParseFrom);
static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_UnaryCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
grpc::MethodType.Unary,
__ServiceName,
"UnaryCall",
- __Marshaller_SimpleRequest,
- __Marshaller_SimpleResponse);
+ __Marshaller_grpc_testing_SimpleRequest,
+ __Marshaller_grpc_testing_SimpleResponse);
static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
grpc::MethodType.DuplexStreaming,
__ServiceName,
"StreamingCall",
- __Marshaller_SimpleRequest,
- __Marshaller_SimpleResponse);
+ __Marshaller_grpc_testing_SimpleRequest,
+ __Marshaller_grpc_testing_SimpleResponse);
static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingFromClient = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
grpc::MethodType.ClientStreaming,
__ServiceName,
"StreamingFromClient",
- __Marshaller_SimpleRequest,
- __Marshaller_SimpleResponse);
+ __Marshaller_grpc_testing_SimpleRequest,
+ __Marshaller_grpc_testing_SimpleResponse);
static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingFromServer = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
grpc::MethodType.ServerStreaming,
__ServiceName,
"StreamingFromServer",
- __Marshaller_SimpleRequest,
- __Marshaller_SimpleResponse);
+ __Marshaller_grpc_testing_SimpleRequest,
+ __Marshaller_grpc_testing_SimpleResponse);
static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingBothWays = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
grpc::MethodType.DuplexStreaming,
__ServiceName,
"StreamingBothWays",
- __Marshaller_SimpleRequest,
- __Marshaller_SimpleResponse);
+ __Marshaller_grpc_testing_SimpleRequest,
+ __Marshaller_grpc_testing_SimpleResponse);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
diff --git a/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs b/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs
index 2462606879..c8bcb7a93f 100644
--- a/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs
@@ -34,29 +34,6 @@ namespace Grpc.IntegrationTesting
TestService.TestServiceClient unimplementedClient = new UnimplementedTestServiceClient();
[Test]
- public void ExpandedParamOverloadCanBeMocked()
- {
- var expected = new SimpleResponse();
-
- var mockClient = new Moq.Mock<TestService.TestServiceClient>();
- // mocking is relatively clumsy because one needs to specify value for all the optional params.
- mockClient.Setup(m => m.UnaryCall(Moq.It.IsAny<SimpleRequest>(), null, null, CancellationToken.None)).Returns(expected);
-
- Assert.AreSame(expected, mockClient.Object.UnaryCall(new SimpleRequest()));
- }
-
- [Test]
- public void CallOptionsOverloadCanBeMocked()
- {
- var expected = new SimpleResponse();
-
- var mockClient = new Moq.Mock<TestService.TestServiceClient>();
- mockClient.Setup(m => m.UnaryCall(Moq.It.IsAny<SimpleRequest>(), Moq.It.IsAny<CallOptions>())).Returns(expected);
-
- Assert.AreSame(expected, mockClient.Object.UnaryCall(new SimpleRequest(), new CallOptions()));
- }
-
- [Test]
public void DefaultMethodStubThrows_UnaryCall()
{
Assert.Throws(typeof(NotImplementedException), () => unimplementedClient.UnaryCall(new SimpleRequest()));
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
index ba2107a576..e4f36d8810 100755
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -19,7 +19,6 @@
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="$(GoogleProtobufVersion)" />
<PackageReference Include="CommandLineParser" Version="2.1.1-beta" />
- <PackageReference Include="Moq" Version="4.8.2" />
<PackageReference Include="NUnit" Version="3.6.0" />
<PackageReference Include="NUnitLite" Version="3.6.0" />
</ItemGroup>
diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
index e8c566e167..9f16f41ac1 100644
--- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
@@ -33,23 +33,23 @@ namespace Grpc.Testing {
{
static readonly string __ServiceName = "grpc.testing.MetricsService";
- static readonly grpc::Marshaller<global::Grpc.Testing.EmptyMessage> __Marshaller_EmptyMessage = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.EmptyMessage.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.GaugeResponse> __Marshaller_GaugeResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.GaugeResponse.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.GaugeRequest> __Marshaller_GaugeRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.GaugeRequest.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.EmptyMessage> __Marshaller_grpc_testing_EmptyMessage = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.EmptyMessage.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.GaugeResponse> __Marshaller_grpc_testing_GaugeResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.GaugeResponse.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.GaugeRequest> __Marshaller_grpc_testing_GaugeRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.GaugeRequest.Parser.ParseFrom);
static readonly grpc::Method<global::Grpc.Testing.EmptyMessage, global::Grpc.Testing.GaugeResponse> __Method_GetAllGauges = new grpc::Method<global::Grpc.Testing.EmptyMessage, global::Grpc.Testing.GaugeResponse>(
grpc::MethodType.ServerStreaming,
__ServiceName,
"GetAllGauges",
- __Marshaller_EmptyMessage,
- __Marshaller_GaugeResponse);
+ __Marshaller_grpc_testing_EmptyMessage,
+ __Marshaller_grpc_testing_GaugeResponse);
static readonly grpc::Method<global::Grpc.Testing.GaugeRequest, global::Grpc.Testing.GaugeResponse> __Method_GetGauge = new grpc::Method<global::Grpc.Testing.GaugeRequest, global::Grpc.Testing.GaugeResponse>(
grpc::MethodType.Unary,
__ServiceName,
"GetGauge",
- __Marshaller_GaugeRequest,
- __Marshaller_GaugeResponse);
+ __Marshaller_grpc_testing_GaugeRequest,
+ __Marshaller_grpc_testing_GaugeResponse);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
diff --git a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs
index 60a3890f21..1da0548cb4 100644
--- a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs
@@ -29,15 +29,15 @@ namespace Grpc.Testing {
{
static readonly string __ServiceName = "grpc.testing.ReportQpsScenarioService";
- static readonly grpc::Marshaller<global::Grpc.Testing.ScenarioResult> __Marshaller_ScenarioResult = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ScenarioResult.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.Void> __Marshaller_Void = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Void.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.ScenarioResult> __Marshaller_grpc_testing_ScenarioResult = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ScenarioResult.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.Void> __Marshaller_grpc_testing_Void = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Void.Parser.ParseFrom);
static readonly grpc::Method<global::Grpc.Testing.ScenarioResult, global::Grpc.Testing.Void> __Method_ReportScenario = new grpc::Method<global::Grpc.Testing.ScenarioResult, global::Grpc.Testing.Void>(
grpc::MethodType.Unary,
__ServiceName,
"ReportScenario",
- __Marshaller_ScenarioResult,
- __Marshaller_Void);
+ __Marshaller_grpc_testing_ScenarioResult,
+ __Marshaller_grpc_testing_Void);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index aec4ce7be7..2176916b43 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -34,69 +34,69 @@ namespace Grpc.Testing {
{
static readonly string __ServiceName = "grpc.testing.TestService";
- static readonly grpc::Marshaller<global::Grpc.Testing.Empty> __Marshaller_Empty = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Empty.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.SimpleRequest> __Marshaller_SimpleRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleRequest.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.SimpleResponse> __Marshaller_SimpleResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleResponse.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.StreamingOutputCallRequest> __Marshaller_StreamingOutputCallRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingOutputCallRequest.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.StreamingOutputCallResponse> __Marshaller_StreamingOutputCallResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingOutputCallResponse.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.StreamingInputCallRequest> __Marshaller_StreamingInputCallRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingInputCallRequest.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.StreamingInputCallResponse> __Marshaller_StreamingInputCallResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingInputCallResponse.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.Empty> __Marshaller_grpc_testing_Empty = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Empty.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.SimpleRequest> __Marshaller_grpc_testing_SimpleRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleRequest.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.SimpleResponse> __Marshaller_grpc_testing_SimpleResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleResponse.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.StreamingOutputCallRequest> __Marshaller_grpc_testing_StreamingOutputCallRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingOutputCallRequest.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.StreamingOutputCallResponse> __Marshaller_grpc_testing_StreamingOutputCallResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingOutputCallResponse.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.StreamingInputCallRequest> __Marshaller_grpc_testing_StreamingInputCallRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingInputCallRequest.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.StreamingInputCallResponse> __Marshaller_grpc_testing_StreamingInputCallResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingInputCallResponse.Parser.ParseFrom);
static readonly grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty> __Method_EmptyCall = new grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty>(
grpc::MethodType.Unary,
__ServiceName,
"EmptyCall",
- __Marshaller_Empty,
- __Marshaller_Empty);
+ __Marshaller_grpc_testing_Empty,
+ __Marshaller_grpc_testing_Empty);
static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_UnaryCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
grpc::MethodType.Unary,
__ServiceName,
"UnaryCall",
- __Marshaller_SimpleRequest,
- __Marshaller_SimpleResponse);
+ __Marshaller_grpc_testing_SimpleRequest,
+ __Marshaller_grpc_testing_SimpleResponse);
static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_CacheableUnaryCall = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
grpc::MethodType.Unary,
__ServiceName,
"CacheableUnaryCall",
- __Marshaller_SimpleRequest,
- __Marshaller_SimpleResponse);
+ __Marshaller_grpc_testing_SimpleRequest,
+ __Marshaller_grpc_testing_SimpleResponse);
static readonly grpc::Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> __Method_StreamingOutputCall = new grpc::Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse>(
grpc::MethodType.ServerStreaming,
__ServiceName,
"StreamingOutputCall",
- __Marshaller_StreamingOutputCallRequest,
- __Marshaller_StreamingOutputCallResponse);
+ __Marshaller_grpc_testing_StreamingOutputCallRequest,
+ __Marshaller_grpc_testing_StreamingOutputCallResponse);
static readonly grpc::Method<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> __Method_StreamingInputCall = new grpc::Method<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse>(
grpc::MethodType.ClientStreaming,
__ServiceName,
"StreamingInputCall",
- __Marshaller_StreamingInputCallRequest,
- __Marshaller_StreamingInputCallResponse);
+ __Marshaller_grpc_testing_StreamingInputCallRequest,
+ __Marshaller_grpc_testing_StreamingInputCallResponse);
static readonly grpc::Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> __Method_FullDuplexCall = new grpc::Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse>(
grpc::MethodType.DuplexStreaming,
__ServiceName,
"FullDuplexCall",
- __Marshaller_StreamingOutputCallRequest,
- __Marshaller_StreamingOutputCallResponse);
+ __Marshaller_grpc_testing_StreamingOutputCallRequest,
+ __Marshaller_grpc_testing_StreamingOutputCallResponse);
static readonly grpc::Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> __Method_HalfDuplexCall = new grpc::Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse>(
grpc::MethodType.DuplexStreaming,
__ServiceName,
"HalfDuplexCall",
- __Marshaller_StreamingOutputCallRequest,
- __Marshaller_StreamingOutputCallResponse);
+ __Marshaller_grpc_testing_StreamingOutputCallRequest,
+ __Marshaller_grpc_testing_StreamingOutputCallResponse);
static readonly grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty> __Method_UnimplementedCall = new grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty>(
grpc::MethodType.Unary,
__ServiceName,
"UnimplementedCall",
- __Marshaller_Empty,
- __Marshaller_Empty);
+ __Marshaller_grpc_testing_Empty,
+ __Marshaller_grpc_testing_Empty);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
@@ -548,14 +548,14 @@ namespace Grpc.Testing {
{
static readonly string __ServiceName = "grpc.testing.UnimplementedService";
- static readonly grpc::Marshaller<global::Grpc.Testing.Empty> __Marshaller_Empty = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Empty.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.Empty> __Marshaller_grpc_testing_Empty = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Empty.Parser.ParseFrom);
static readonly grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty> __Method_UnimplementedCall = new grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty>(
grpc::MethodType.Unary,
__ServiceName,
"UnimplementedCall",
- __Marshaller_Empty,
- __Marshaller_Empty);
+ __Marshaller_grpc_testing_Empty,
+ __Marshaller_grpc_testing_Empty);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
@@ -669,23 +669,23 @@ namespace Grpc.Testing {
{
static readonly string __ServiceName = "grpc.testing.ReconnectService";
- static readonly grpc::Marshaller<global::Grpc.Testing.ReconnectParams> __Marshaller_ReconnectParams = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ReconnectParams.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.Empty> __Marshaller_Empty = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Empty.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.ReconnectInfo> __Marshaller_ReconnectInfo = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ReconnectInfo.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.ReconnectParams> __Marshaller_grpc_testing_ReconnectParams = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ReconnectParams.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.Empty> __Marshaller_grpc_testing_Empty = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Empty.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.ReconnectInfo> __Marshaller_grpc_testing_ReconnectInfo = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ReconnectInfo.Parser.ParseFrom);
static readonly grpc::Method<global::Grpc.Testing.ReconnectParams, global::Grpc.Testing.Empty> __Method_Start = new grpc::Method<global::Grpc.Testing.ReconnectParams, global::Grpc.Testing.Empty>(
grpc::MethodType.Unary,
__ServiceName,
"Start",
- __Marshaller_ReconnectParams,
- __Marshaller_Empty);
+ __Marshaller_grpc_testing_ReconnectParams,
+ __Marshaller_grpc_testing_Empty);
static readonly grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.ReconnectInfo> __Method_Stop = new grpc::Method<global::Grpc.Testing.Empty, global::Grpc.Testing.ReconnectInfo>(
grpc::MethodType.Unary,
__ServiceName,
"Stop",
- __Marshaller_Empty,
- __Marshaller_ReconnectInfo);
+ __Marshaller_grpc_testing_Empty,
+ __Marshaller_grpc_testing_ReconnectInfo);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs
index 85f2cfd871..b9e8f91231 100644
--- a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs
@@ -29,41 +29,41 @@ namespace Grpc.Testing {
{
static readonly string __ServiceName = "grpc.testing.WorkerService";
- static readonly grpc::Marshaller<global::Grpc.Testing.ServerArgs> __Marshaller_ServerArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerArgs.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.ServerStatus> __Marshaller_ServerStatus = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerStatus.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.ClientArgs> __Marshaller_ClientArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientArgs.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.ClientStatus> __Marshaller_ClientStatus = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientStatus.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.CoreRequest> __Marshaller_CoreRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreRequest.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.CoreResponse> __Marshaller_CoreResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreResponse.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Testing.Void> __Marshaller_Void = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Void.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.ServerArgs> __Marshaller_grpc_testing_ServerArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerArgs.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.ServerStatus> __Marshaller_grpc_testing_ServerStatus = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerStatus.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.ClientArgs> __Marshaller_grpc_testing_ClientArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientArgs.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.ClientStatus> __Marshaller_grpc_testing_ClientStatus = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientStatus.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.CoreRequest> __Marshaller_grpc_testing_CoreRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreRequest.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.CoreResponse> __Marshaller_grpc_testing_CoreResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreResponse.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.Void> __Marshaller_grpc_testing_Void = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Void.Parser.ParseFrom);
static readonly grpc::Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> __Method_RunServer = new grpc::Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus>(
grpc::MethodType.DuplexStreaming,
__ServiceName,
"RunServer",
- __Marshaller_ServerArgs,
- __Marshaller_ServerStatus);
+ __Marshaller_grpc_testing_ServerArgs,
+ __Marshaller_grpc_testing_ServerStatus);
static readonly grpc::Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> __Method_RunClient = new grpc::Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus>(
grpc::MethodType.DuplexStreaming,
__ServiceName,
"RunClient",
- __Marshaller_ClientArgs,
- __Marshaller_ClientStatus);
+ __Marshaller_grpc_testing_ClientArgs,
+ __Marshaller_grpc_testing_ClientStatus);
static readonly grpc::Method<global::Grpc.Testing.CoreRequest, global::Grpc.Testing.CoreResponse> __Method_CoreCount = new grpc::Method<global::Grpc.Testing.CoreRequest, global::Grpc.Testing.CoreResponse>(
grpc::MethodType.Unary,
__ServiceName,
"CoreCount",
- __Marshaller_CoreRequest,
- __Marshaller_CoreResponse);
+ __Marshaller_grpc_testing_CoreRequest,
+ __Marshaller_grpc_testing_CoreResponse);
static readonly grpc::Method<global::Grpc.Testing.Void, global::Grpc.Testing.Void> __Method_QuitWorker = new grpc::Method<global::Grpc.Testing.Void, global::Grpc.Testing.Void>(
grpc::MethodType.Unary,
__ServiceName,
"QuitWorker",
- __Marshaller_Void,
- __Marshaller_Void);
+ __Marshaller_grpc_testing_Void,
+ __Marshaller_grpc_testing_Void);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
index 387c9fb52f..c00075b7c6 100644
--- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
+++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
@@ -29,15 +29,15 @@ namespace Grpc.Reflection.V1Alpha {
{
static readonly string __ServiceName = "grpc.reflection.v1alpha.ServerReflection";
- static readonly grpc::Marshaller<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest> __Marshaller_ServerReflectionRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Reflection.V1Alpha.ServerReflectionRequest.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> __Marshaller_ServerReflectionResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Reflection.V1Alpha.ServerReflectionResponse.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest> __Marshaller_grpc_reflection_v1alpha_ServerReflectionRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Reflection.V1Alpha.ServerReflectionRequest.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> __Marshaller_grpc_reflection_v1alpha_ServerReflectionResponse = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Reflection.V1Alpha.ServerReflectionResponse.Parser.ParseFrom);
static readonly grpc::Method<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> __Method_ServerReflectionInfo = new grpc::Method<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse>(
grpc::MethodType.DuplexStreaming,
__ServiceName,
"ServerReflectionInfo",
- __Marshaller_ServerReflectionRequest,
- __Marshaller_ServerReflectionResponse);
+ __Marshaller_grpc_reflection_v1alpha_ServerReflectionRequest,
+ __Marshaller_grpc_reflection_v1alpha_ServerReflectionResponse);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat
index 924d7b1697..f1111781e2 100755
--- a/src/csharp/build_packages_dotnetcli.bat
+++ b/src/csharp/build_packages_dotnetcli.bat
@@ -47,6 +47,7 @@ xcopy /Y /I nativelibs\csharp_ext_windows_x64\grpc_csharp_ext.dll ..\..\cmake\bu
%DOTNET% pack --configuration Release Grpc.Reflection --output ..\..\..\artifacts || goto :error
%NUGET% pack Grpc.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts || goto :error
+%NUGET% pack Grpc.Core.NativeDebug.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts
%NUGET% pack Grpc.Tools.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts
@rem copy resulting nuget packages to artifacts directory
diff --git a/src/csharp/build_packages_dotnetcli.sh b/src/csharp/build_packages_dotnetcli.sh
index 5c73a8f95f..fb4138a4b2 100755
--- a/src/csharp/build_packages_dotnetcli.sh
+++ b/src/csharp/build_packages_dotnetcli.sh
@@ -46,6 +46,7 @@ dotnet pack --configuration Release Grpc.HealthCheck --output ../../../artifacts
dotnet pack --configuration Release Grpc.Reflection --output ../../../artifacts
nuget pack Grpc.nuspec -Version "1.13.0-dev" -OutputDirectory ../../artifacts
+nuget pack Grpc.Core.NativeDebug.nuspec -Version "1.13.0-dev" -OutputDirectory ../../artifacts
nuget pack Grpc.Tools.nuspec -Version "1.13.0-dev" -OutputDirectory ../../artifacts
(cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg)
diff --git a/src/csharp/tests.json b/src/csharp/tests.json
index 60f67ff3c9..c2f243fe0a 100644
--- a/src/csharp/tests.json
+++ b/src/csharp/tests.json
@@ -41,7 +41,9 @@
"Grpc.Core.Tests.UserAgentStringTest"
],
"Grpc.Examples.Tests": [
- "Math.Tests.MathClientServerTest"
+ "Math.Tests.MathClientMockableTest",
+ "Math.Tests.MathClientServerTest",
+ "Math.Tests.MathServiceImplTestabilityTest"
],
"Grpc.HealthCheck.Tests": [
"Grpc.HealthCheck.Tests.HealthClientServerTest",
diff --git a/src/objective-c/BoringSSL.podspec b/src/objective-c/BoringSSL.podspec
index d55a56ec18..363983183e 100644
--- a/src/objective-c/BoringSSL.podspec
+++ b/src/objective-c/BoringSSL.podspec
@@ -31,7 +31,7 @@
Pod::Spec.new do |s|
s.name = 'BoringSSL'
- version = '10.0.4'
+ version = '10.0.5'
s.version = version
s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google’s needs.'
# Adapted from the homepage:
@@ -61,8 +61,7 @@ Pod::Spec.new do |s|
Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it’s not part of the
NDK) and a number of other apps/programs.
DESC
- s.homepage = 'https://boringssl.googlesource.com/boringssl/'
- s.documentation_url = 'https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html'
+ s.homepage = 'https://github.com/google/boringssl'
s.license = { :type => 'Mixed', :file => 'LICENSE' }
# "The name and email addresses of the library maintainers, not the Podspec maintainer."
s.authors = 'Adam Langley', 'David Benjamin', 'Matt Braithwaite'
diff --git a/src/objective-c/GRPCClient/GRPCCall+MobileLog.h b/src/objective-c/GRPCClient/GRPCCall+MobileLog.h
deleted file mode 100644
index 53b347d9ca..0000000000
--- a/src/objective-c/GRPCClient/GRPCCall+MobileLog.h
+++ /dev/null
@@ -1,30 +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.
- *
- */
-
-#import "GRPCCall.h"
-
-@interface GRPCCall (MobileLog)
-// Set the object to be passed down along channel stack with channel arg
-// GRPC_ARG_MOBILE_LOG_CONFIG. The setting may be used by custom channel
-// filters for metrics logging.
-+ (void)setLogConfig:(id)logConfig;
-
-// Obtain the object to be passed down along channel stack with channel arg
-// GRPC_ARG_MOBILE_LOG_CONFIG.
-+ (id)logConfig;
-@end
diff --git a/src/objective-c/GRPCClient/GRPCCall+MobileLog.m b/src/objective-c/GRPCClient/GRPCCall+MobileLog.m
deleted file mode 100644
index 4dedb7de8b..0000000000
--- a/src/objective-c/GRPCClient/GRPCCall+MobileLog.m
+++ /dev/null
@@ -1,33 +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.
- *
- */
-
-#import "GRPCCall+MobileLog.h"
-
-static id globalLogConfig = nil;
-
-@implementation GRPCCall (MobileLog)
-
-+ (void)setLogConfig:(id)logConfig {
- globalLogConfig = logConfig;
-}
-
-+ (id)logConfig {
- return globalLogConfig;
-}
-
-@end
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m
index 5b48d06158..9783b06440 100644
--- a/src/objective-c/GRPCClient/GRPCCall.m
+++ b/src/objective-c/GRPCClient/GRPCCall.m
@@ -206,8 +206,9 @@ static NSString *const kBearerPrefix = @"Bearer ";
} else {
[_responseWriteable enqueueSuccessfulCompletion];
}
-
+#ifndef GRPC_CFSTREAM
[GRPCConnectivityMonitor unregisterObserver:self];
+#endif
// If the call isn't retained anywhere else, it can be deallocated now.
_retainSelf = nil;
@@ -462,7 +463,9 @@ static NSString *const kBearerPrefix = @"Bearer ";
[self sendHeaders:_requestHeaders];
[self invokeCall];
+#ifndef GRPC_CFSTREAM
[GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)];
+#endif
}
- (void)startWithWriteable:(id<GRXWriteable>)writeable {
diff --git a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
index 57dbde8d04..bda1c3360b 100644
--- a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
+++ b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
@@ -20,6 +20,14 @@
#import <grpc/grpc.h>
+#ifdef GRPC_CFSTREAM
+const grpc_completion_queue_attributes kCompletionQueueAttr = {GRPC_CQ_CURRENT_VERSION,
+ GRPC_CQ_NEXT, GRPC_CQ_NON_POLLING};
+#else
+const grpc_completion_queue_attributes kCompletionQueueAttr = {
+ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING};
+#endif
+
@implementation GRPCCompletionQueue
+ (instancetype)completionQueue {
@@ -33,7 +41,8 @@
- (instancetype)init {
if ((self = [super init])) {
- _unmanagedQueue = grpc_completion_queue_create_for_next(NULL);
+ _unmanagedQueue = grpc_completion_queue_create(
+ grpc_completion_queue_factory_lookup(&kCompletionQueueAttr), &kCompletionQueueAttr, NULL);
// This is for the following block to capture the pointer by value (instead
// of retaining self and doing self->_unmanagedQueue). This is essential
diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h
index 6697f61be4..d9916d9303 100644
--- a/src/objective-c/GRPCClient/private/GRPCHost.h
+++ b/src/objective-c/GRPCClient/private/GRPCHost.h
@@ -37,6 +37,7 @@ struct grpc_channel_credentials;
@property(nonatomic) grpc_compression_algorithm compressAlgorithm;
@property(nonatomic) int keepaliveInterval;
@property(nonatomic) int keepaliveTimeout;
+@property(nonatomic) id logContext;
/** The following properties should only be modified for testing: */
diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m
index c3ea9afc37..f4b933751f 100644
--- a/src/objective-c/GRPCClient/private/GRPCHost.m
+++ b/src/objective-c/GRPCClient/private/GRPCHost.m
@@ -18,7 +18,6 @@
#import "GRPCHost.h"
-#import <GRPCClient/GRPCCall+MobileLog.h>
#import <GRPCClient/GRPCCall.h>
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
@@ -50,7 +49,9 @@ static NSMutableDictionary *kHostCache;
if (_channelCreds != nil) {
grpc_channel_credentials_release(_channelCreds);
}
+#ifndef GRPC_CFSTREAM
[GRPCConnectivityMonitor unregisterObserver:self];
+#endif
}
// Default initializer.
@@ -85,7 +86,9 @@ static NSMutableDictionary *kHostCache;
kHostCache[address] = self;
_compressAlgorithm = GRPC_COMPRESS_NONE;
}
+#ifndef GRPC_CFSTREAM
[GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChange:)];
+#endif
}
return self;
}
@@ -126,6 +129,14 @@ static NSMutableDictionary *kHostCache;
completionQueue:queue];
}
+- (NSData *)nullTerminatedDataWithString:(NSString *)string {
+ // dataUsingEncoding: does not return a null-terminated string.
+ NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
+ NSMutableData *nullTerminated = [NSMutableData dataWithData:data];
+ [nullTerminated appendBytes:"\0" length:1];
+ return nullTerminated;
+}
+
- (BOOL)setTLSPEMRootCerts:(nullable NSString *)pemRootCerts
withPrivateKey:(nullable NSString *)pemPrivateKey
withCertChain:(nullable NSString *)pemCertChain
@@ -147,13 +158,12 @@ static NSMutableDictionary *kHostCache;
kDefaultRootsError = error;
return;
}
- kDefaultRootsASCII =
- [contentInUTF8 dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
+ kDefaultRootsASCII = [self nullTerminatedDataWithString:contentInUTF8];
});
NSData *rootsASCII;
if (pemRootCerts != nil) {
- rootsASCII = [pemRootCerts dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
+ rootsASCII = [self nullTerminatedDataWithString:pemRootCerts];
} else {
if (kDefaultRootsASCII == nil) {
if (errorPtr) {
@@ -176,10 +186,8 @@ static NSMutableDictionary *kHostCache;
creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL);
} else {
grpc_ssl_pem_key_cert_pair key_cert_pair;
- NSData *privateKeyASCII =
- [pemPrivateKey dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
- NSData *certChainASCII =
- [pemCertChain dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
+ NSData *privateKeyASCII = [self nullTerminatedDataWithString:pemPrivateKey];
+ NSData *certChainASCII = [self nullTerminatedDataWithString:pemCertChain];
key_cert_pair.private_key = privateKeyASCII.bytes;
key_cert_pair.cert_chain = certChainASCII.bytes;
creds = grpc_ssl_credentials_create(rootsASCII.bytes, &key_cert_pair, NULL);
@@ -223,9 +231,9 @@ static NSMutableDictionary *kHostCache;
args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = [NSNumber numberWithInt:_keepaliveTimeout];
}
- id logConfig = [GRPCCall logConfig];
- if (logConfig != nil) {
- args[@GRPC_ARG_MOBILE_LOG_CONFIG] = logConfig;
+ id logContext = self.logContext;
+ if (logContext != nil) {
+ args[@GRPC_ARG_MOBILE_LOG_CONTEXT] = logContext;
}
if (useCronet) {
diff --git a/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj b/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj
index ab7159cda2..cdd1c6c8f7 100644
--- a/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj
+++ b/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj
@@ -325,6 +325,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = Sample/Info.plist;
+ LD_GENERATE_MAP_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.grpc.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -337,6 +338,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = Sample/Info.plist;
+ LD_GENERATE_MAP_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.grpc.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
diff --git a/src/objective-c/examples/Sample/Sample.xcodeproj/xcshareddata/xcschemes/Sample.xcscheme b/src/objective-c/examples/Sample/Sample.xcodeproj/xcshareddata/xcschemes/Sample.xcscheme
index d399e22e46..e356ea22a6 100644
--- a/src/objective-c/examples/Sample/Sample.xcodeproj/xcshareddata/xcschemes/Sample.xcscheme
+++ b/src/objective-c/examples/Sample/Sample.xcodeproj/xcshareddata/xcschemes/Sample.xcscheme
@@ -42,7 +42,7 @@
</AdditionalOptions>
</TestAction>
<LaunchAction
- buildConfiguration = "Debug"
+ buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
diff --git a/src/objective-c/tests/Connectivity/ConnectivityTestingApp.xcodeproj/project.pbxproj b/src/objective-c/tests/Connectivity/ConnectivityTestingApp.xcodeproj/project.pbxproj
index 6a4c3519d6..7a03f9b41a 100644
--- a/src/objective-c/tests/Connectivity/ConnectivityTestingApp.xcodeproj/project.pbxproj
+++ b/src/objective-c/tests/Connectivity/ConnectivityTestingApp.xcodeproj/project.pbxproj
@@ -99,7 +99,6 @@
5EC49F8D2043E46B00ED189A /* Sources */,
5EC49F8E2043E46B00ED189A /* Frameworks */,
5EC49F8F2043E46B00ED189A /* Resources */,
- 9F67C72B6B6BAF2781078886 /* [CP] Embed Pods Frameworks */,
735516C793AF7394FBB83B7F /* [CP] Copy Pods Resources */,
);
buildRules = (
@@ -194,21 +193,6 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
- 9F67C72B6B6BAF2781078886 /* [CP] Embed Pods Frameworks */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Embed Pods Frameworks";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ConnectivityTestingApp/Pods-ConnectivityTestingApp-frameworks.sh\"\n";
- showEnvVarsInLog = 0;
- };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -284,6 +268,7 @@
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
+ "GRPC_CFSTREAM=1",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
diff --git a/src/objective-c/tests/Connectivity/ConnectivityTestingApp/ViewController.m b/src/objective-c/tests/Connectivity/ConnectivityTestingApp/ViewController.m
index 88780e39f0..3c77fe2f2c 100644
--- a/src/objective-c/tests/Connectivity/ConnectivityTestingApp/ViewController.m
+++ b/src/objective-c/tests/Connectivity/ConnectivityTestingApp/ViewController.m
@@ -35,7 +35,9 @@ NSString *host = @"grpc-test.sandbox.googleapis.com";
- (void)viewDidLoad {
[super viewDidLoad];
+#ifndef GRPC_CFSTREAM
[GRPCConnectivityMonitor registerObserver:self selector:@selector(reachabilityChanged:)];
+#endif
}
- (void)reachabilityChanged:(NSNotification *)note {
diff --git a/src/objective-c/tests/Connectivity/Podfile b/src/objective-c/tests/Connectivity/Podfile
index cdbc6dde59..c7127b3e78 100644
--- a/src/objective-c/tests/Connectivity/Podfile
+++ b/src/objective-c/tests/Connectivity/Podfile
@@ -5,9 +5,9 @@ platform :ios, '8.0'
GRPC_LOCAL_SRC = '../../../..'
target 'ConnectivityTestingApp' do
- pod 'gRPC', :path => GRPC_LOCAL_SRC
- pod 'gRPC-Core', :path => GRPC_LOCAL_SRC
- pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC
+ pod 'gRPC/CFStream', :path => GRPC_LOCAL_SRC
+ pod 'gRPC-Core/CFStream-Implementation', :path => GRPC_LOCAL_SRC
+ pod 'gRPC-ProtoRPC/CFStream', :path => GRPC_LOCAL_SRC
pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC
pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf"
pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c"
diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m
index 5cd0231db7..d9186561c3 100644
--- a/src/objective-c/tests/GRPCClientTests.m
+++ b/src/objective-c/tests/GRPCClientTests.m
@@ -525,7 +525,8 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
- (void)testErrorCode {
int port = [self findFreePort];
NSString *const kDummyAddress = [NSString stringWithFormat:@"localhost:%d", port];
- __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."];
+ __weak XCTestExpectation *completion =
+ [self expectationWithDescription:@"Received correct error code."];
GRPCCall *call = [[GRPCCall alloc] initWithHost:kDummyAddress
path:kEmptyCallMethod.HTTPPath
diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile
index b6e389715a..3c2a34fb49 100644
--- a/src/objective-c/tests/Podfile
+++ b/src/objective-c/tests/Podfile
@@ -37,6 +37,27 @@ GRPC_LOCAL_SRC = '../../..'
end
%w(
+ InteropTestsRemoteCFStream
+ InteropTestsLocalSSLCFStream
+ InteropTestsLocalCleartextCFStream
+).each do |target_name|
+ target target_name do
+ pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true
+
+ pod '!ProtoCompiler', :path => "#{GRPC_LOCAL_SRC}/src/objective-c"
+ pod '!ProtoCompiler-gRPCPlugin', :path => "#{GRPC_LOCAL_SRC}/src/objective-c"
+
+ pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true
+
+ pod 'gRPC/CFStream', :path => GRPC_LOCAL_SRC
+ pod 'gRPC-Core/CFStream-Implementation', :path => GRPC_LOCAL_SRC
+ pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC
+ pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true
+ pod 'RemoteTest', :path => "RemoteTestClient", :inhibit_warnings => true
+ end
+end
+
+%w(
CoreCronetEnd2EndTests
CronetUnitTests
).each do |target_name|
@@ -65,7 +86,7 @@ end
# TODO(jcanizales): Send a PR to Cocoapods to get rid of this need.
pre_install do |installer|
# This is the gRPC-Core podspec object, as initialized by its podspec file.
- grpc_core_spec = installer.pod_targets.find{|t| t.name == 'gRPC-Core'}.root_spec
+ grpc_core_spec = installer.pod_targets.find{|t| t.name.start_with?('gRPC-Core')}.root_spec
# Copied from gRPC-Core.podspec, except for the adjusted src_root:
src_root = "$(PODS_ROOT)/../#{GRPC_LOCAL_SRC}"
@@ -96,7 +117,11 @@ post_install do |installer|
# GPR_UNREACHABLE_CODE causes "Control may reach end of non-void
# function" warning
config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO'
- config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1'
+ if target.name.include?('CFStream')
+ config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CFSTREAM=1'
+ else
+ config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1'
+ end
end
end
@@ -104,7 +129,7 @@ post_install do |installer|
# the test target 'InteropTestsRemoteWithCronet'
# Activate GRPCCall+InternalTests functions for the dedicated build configuration 'Test', which will
# be used by all test targets using it.
- if target.name == 'gRPC'
+ if target.name == 'gRPC' || target.name.start_with?('gRPC.')
target.build_configurations.each do |config|
if config.name == 'Cronet'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_COMPILE_WITH_CRONET=1 GRPC_TEST_OBJC=1'
diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
index e0f220eaee..8ff4633582 100644
--- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
+++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
@@ -13,11 +13,18 @@
16A9E77B6E336B3C0B9BA6E0 /* libPods-InteropTestsLocalSSL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBEDE45BDA60DF1E1C8950C0 /* libPods-InteropTestsLocalSSL.a */; };
20DFDF829DD993A4A00D5662 /* libPods-RxLibraryUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */; };
333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; };
- 3D7C85F6AA68C4A205E3BA16 /* libPods-Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */; };
5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm */; };
5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; };
5EAD6D271E27047400002378 /* CronetUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EAD6D261E27047400002378 /* CronetUnitTests.m */; };
5EAD6D291E27047400002378 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; };
+ 5EC5E42B2081782C000EF4AD /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */; };
+ 5EC5E42C20817832000EF4AD /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; };
+ 5EC5E43B208185A7000EF4AD /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; };
+ 5EC5E43C208185AD000EF4AD /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; };
+ 5EC5E43D208185B0000EF4AD /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; };
+ 5EC5E44C208185EC000EF4AD /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; };
+ 5EC5E44D208185F0000EF4AD /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; };
+ 5EC5E44E20818948000EF4AD /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; };
5EE84BF41D4717E40050C6CC /* InteropTestsRemoteWithCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EE84BF31D4717E40050C6CC /* InteropTestsRemoteWithCronet.m */; };
5EE84BF61D4717E40050C6CC /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; };
5EE84BFE1D471D400050C6CC /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; };
@@ -44,6 +51,9 @@
63DC84501BE153AA000708E8 /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; };
63E240CE1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; };
63E240D01B6C63DC005F3B0E /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; };
+ 91D4B3C85B6D8562F409CB48 /* libPods-InteropTestsLocalSSLCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */; };
+ BC111C80CBF7068B62869352 /* libPods-InteropTestsRemoteCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */; };
+ C3D6F4270A2FFF634D8849ED /* libPods-InteropTestsLocalCleartextCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */; };
F15EF7852DC70770EFDB1D2C /* libPods-AllTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */; };
/* End PBXBuildFile section */
@@ -120,31 +130,41 @@
/* Begin PBXFileReference section */
02192CF1FF9534E3D18C65FC /* Pods-CronetUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.release.xcconfig"; sourceTree = "<group>"; };
- 060EF32D7EC0DF67ED617507 /* Pods-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.debug.xcconfig"; sourceTree = "<group>"; };
07D10A965323BEA7FE59A74B /* Pods-RxLibraryUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.debug.xcconfig"; sourceTree = "<group>"; };
0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
+ 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartextCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; };
0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.debug.xcconfig"; sourceTree = "<group>"; };
14B09A58FEE53A7A6B838920 /* Pods-InteropTestsLocalSSL.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.cronet.xcconfig"; sourceTree = "<group>"; };
1588C85DEAF7FC0ACDEA4C02 /* Pods-InteropTestsLocalCleartext.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.test.xcconfig"; sourceTree = "<group>"; };
17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; sourceTree = "<group>"; };
20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
2B89F3037963E6EDDD48D8C3 /* Pods-InteropTestsRemoteWithCronet.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.test.xcconfig"; sourceTree = "<group>"; };
+ 303F4A17EB1650FC44603D17 /* Pods-InteropTestsRemoteCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.release.xcconfig"; sourceTree = "<group>"; };
+ 32748C4078AEB05F8F954361 /* Pods-InteropTestsRemoteCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.debug.xcconfig"; sourceTree = "<group>"; };
35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
386712AEACF7C2190C4B8B3F /* Pods-CronetUnitTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.cronet.xcconfig"; sourceTree = "<group>"; };
3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.release.xcconfig"; sourceTree = "<group>"; };
+ 3EB55EF291706E3DDE23C3B7 /* Pods-InteropTestsLocalSSLCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.debug.xcconfig"; sourceTree = "<group>"; };
3F27B2E744482771EB93C394 /* Pods-InteropTestsRemoteWithCronet.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.cronet.xcconfig"; sourceTree = "<group>"; };
+ 41AA59529240A6BBBD3DB904 /* Pods-InteropTestsLocalSSLCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.test.xcconfig"; sourceTree = "<group>"; };
+ 4A1A42B2E941CCD453489E5B /* Pods-InteropTestsRemoteCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.cronet.xcconfig"; sourceTree = "<group>"; };
4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.release.xcconfig"; sourceTree = "<group>"; };
4ADEA1C8BBE10D90940AC68E /* Pods-InteropTestsRemote.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.cronet.xcconfig"; sourceTree = "<group>"; };
51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.release.xcconfig"; sourceTree = "<group>"; };
553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.debug.xcconfig"; sourceTree = "<group>"; };
+ 55B630C1FF8C36D1EFC4E0A4 /* Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig"; sourceTree = "<group>"; };
573450F334B331D0BED8B961 /* Pods-CoreCronetEnd2EndTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; sourceTree = "<group>"; };
5761E98978DDDF136A58CB7E /* Pods-AllTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.release.xcconfig"; sourceTree = "<group>"; };
5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreCronetEnd2EndTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CoreCronetEnd2EndTests.mm; sourceTree = "<group>"; };
+ 5EA908CF4CDA4CE218352A06 /* Pods-InteropTestsLocalSSLCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.release.xcconfig"; sourceTree = "<group>"; };
5EAD6D241E27047400002378 /* CronetUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CronetUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
5EAD6D261E27047400002378 /* CronetUnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CronetUnitTests.m; sourceTree = "<group>"; };
5EAD6D281E27047400002378 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
5EAFE8271F8EFB87007F2189 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
+ 5EC5E421208177CC000EF4AD /* InteropTestsRemoteCFStream.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsRemoteCFStream.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5EC5E4312081856B000EF4AD /* InteropTestsLocalCleartextCFStream.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsLocalCleartextCFStream.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5EC5E442208185CE000EF4AD /* InteropTestsLocalSSLCFStream.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsLocalSSLCFStream.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
5EE84BF11D4717E40050C6CC /* InteropTestsRemoteWithCronet.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsRemoteWithCronet.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
5EE84BF31D4717E40050C6CC /* InteropTestsRemoteWithCronet.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsRemoteWithCronet.m; sourceTree = "<group>"; };
5EE84BF51D4717E40050C6CC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -169,14 +189,17 @@
781089FAE980F51F88A3BE0B /* Pods-RxLibraryUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.test.xcconfig"; sourceTree = "<group>"; };
79C68EFFCB5533475D810B79 /* Pods-RxLibraryUnitTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.cronet.xcconfig"; sourceTree = "<group>"; };
7A2E97E3F469CC2A758D77DE /* Pods-InteropTestsLocalSSL.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.release.xcconfig"; sourceTree = "<group>"; };
+ 7BA53C6D224288D5870FE6F3 /* Pods-InteropTestsLocalCleartextCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; sourceTree = "<group>"; };
+ 8B498B05C6DA0818B2FA91D4 /* Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; sourceTree = "<group>"; };
+ 943138072A9605B5B8DC1FC0 /* Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; sourceTree = "<group>"; };
9E9444C764F0FFF64A7EB58E /* libPods-InteropTestsRemoteWithCronet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemoteWithCronet.a"; sourceTree = BUILT_PRODUCTS_DIR; };
- A0361771A855917162911180 /* Pods-Tests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.test.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.test.xcconfig"; sourceTree = "<group>"; };
A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RxLibraryUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
A6F832FCEFA6F6881E620F12 /* Pods-InteropTestsRemote.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.test.xcconfig"; sourceTree = "<group>"; };
AA7CB64B4DD9915AE7C03163 /* Pods-InteropTestsLocalCleartext.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.cronet.xcconfig"; sourceTree = "<group>"; };
AC414EF7A6BF76ED02B6E480 /* Pods-InteropTestsRemoteWithCronet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.release.xcconfig"; sourceTree = "<group>"; };
B226619DC4E709E0FFFF94B8 /* Pods-CronetUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.test.xcconfig"; sourceTree = "<group>"; };
B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.debug.xcconfig"; sourceTree = "<group>"; };
+ C17F57E5BCB989AB1C2F1F25 /* Pods-InteropTestsRemoteCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.test.xcconfig"; sourceTree = "<group>"; };
C6134277D2EB8B380862A03F /* libPods-CronetUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CronetUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AllTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
D13BEC8181B8E678A1B52F54 /* Pods-InteropTestsLocalSSL.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.test.xcconfig"; sourceTree = "<group>"; };
@@ -186,9 +209,10 @@
DC3CA1D948F068E76957A861 /* Pods-InteropTestsRemote.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.debug.xcconfig"; sourceTree = "<group>"; };
E1486220285AF123EB124008 /* Pods-InteropTestsLocalCleartext.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.debug.xcconfig"; sourceTree = "<group>"; };
E4275A759BDBDF143B9B438F /* Pods-InteropTestsRemote.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.release.xcconfig"; sourceTree = "<group>"; };
- E6733B838B28453434B556E2 /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = "<group>"; };
+ E4FD4606D4AB8D5A314D72F0 /* Pods-InteropTestsLocalCleartextCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.test.xcconfig"; sourceTree = "<group>"; };
E7E4D3FD76E3B745D992AF5F /* Pods-AllTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.cronet.xcconfig"; sourceTree = "<group>"; };
- F671D4CAD2864FB203B920B4 /* Pods-Tests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.cronet.xcconfig"; sourceTree = "<group>"; };
+ F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalSSLCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemoteCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; };
FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CoreCronetEnd2EndTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartext.a"; sourceTree = BUILT_PRODUCTS_DIR; };
FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
@@ -213,6 +237,30 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 5EC5E41E208177CC000EF4AD /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ BC111C80CBF7068B62869352 /* libPods-InteropTestsRemoteCFStream.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 5EC5E42E2081856B000EF4AD /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C3D6F4270A2FFF634D8849ED /* libPods-InteropTestsLocalCleartextCFStream.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 5EC5E43F208185CE000EF4AD /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 91D4B3C85B6D8562F409CB48 /* libPods-InteropTestsLocalSSLCFStream.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
5EE84BEE1D4717E40050C6CC /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -235,7 +283,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 3D7C85F6AA68C4A205E3BA16 /* libPods-Tests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -291,6 +338,9 @@
FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */,
9E9444C764F0FFF64A7EB58E /* libPods-InteropTestsRemoteWithCronet.a */,
C6134277D2EB8B380862A03F /* libPods-CronetUnitTests.a */,
+ F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */,
+ 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */,
+ F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -310,8 +360,6 @@
E4275A759BDBDF143B9B438F /* Pods-InteropTestsRemote.release.xcconfig */,
07D10A965323BEA7FE59A74B /* Pods-RxLibraryUnitTests.debug.xcconfig */,
3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */,
- 060EF32D7EC0DF67ED617507 /* Pods-Tests.debug.xcconfig */,
- E6733B838B28453434B556E2 /* Pods-Tests.release.xcconfig */,
0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */,
4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */,
17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */,
@@ -323,7 +371,6 @@
4ADEA1C8BBE10D90940AC68E /* Pods-InteropTestsRemote.cronet.xcconfig */,
3F27B2E744482771EB93C394 /* Pods-InteropTestsRemoteWithCronet.cronet.xcconfig */,
79C68EFFCB5533475D810B79 /* Pods-RxLibraryUnitTests.cronet.xcconfig */,
- F671D4CAD2864FB203B920B4 /* Pods-Tests.cronet.xcconfig */,
64F68A9A6A63CC930DD30A6E /* Pods-CronetUnitTests.debug.xcconfig */,
386712AEACF7C2190C4B8B3F /* Pods-CronetUnitTests.cronet.xcconfig */,
02192CF1FF9534E3D18C65FC /* Pods-CronetUnitTests.release.xcconfig */,
@@ -335,7 +382,18 @@
A6F832FCEFA6F6881E620F12 /* Pods-InteropTestsRemote.test.xcconfig */,
2B89F3037963E6EDDD48D8C3 /* Pods-InteropTestsRemoteWithCronet.test.xcconfig */,
781089FAE980F51F88A3BE0B /* Pods-RxLibraryUnitTests.test.xcconfig */,
- A0361771A855917162911180 /* Pods-Tests.test.xcconfig */,
+ 32748C4078AEB05F8F954361 /* Pods-InteropTestsRemoteCFStream.debug.xcconfig */,
+ C17F57E5BCB989AB1C2F1F25 /* Pods-InteropTestsRemoteCFStream.test.xcconfig */,
+ 4A1A42B2E941CCD453489E5B /* Pods-InteropTestsRemoteCFStream.cronet.xcconfig */,
+ 303F4A17EB1650FC44603D17 /* Pods-InteropTestsRemoteCFStream.release.xcconfig */,
+ 943138072A9605B5B8DC1FC0 /* Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig */,
+ E4FD4606D4AB8D5A314D72F0 /* Pods-InteropTestsLocalCleartextCFStream.test.xcconfig */,
+ 8B498B05C6DA0818B2FA91D4 /* Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig */,
+ 7BA53C6D224288D5870FE6F3 /* Pods-InteropTestsLocalCleartextCFStream.release.xcconfig */,
+ 3EB55EF291706E3DDE23C3B7 /* Pods-InteropTestsLocalSSLCFStream.debug.xcconfig */,
+ 41AA59529240A6BBBD3DB904 /* Pods-InteropTestsLocalSSLCFStream.test.xcconfig */,
+ 55B630C1FF8C36D1EFC4E0A4 /* Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig */,
+ 5EA908CF4CDA4CE218352A06 /* Pods-InteropTestsLocalSSLCFStream.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
@@ -392,6 +450,9 @@
5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */,
5EE84BF11D4717E40050C6CC /* InteropTestsRemoteWithCronet.xctest */,
5EAD6D241E27047400002378 /* CronetUnitTests.xctest */,
+ 5EC5E421208177CC000EF4AD /* InteropTestsRemoteCFStream.xctest */,
+ 5EC5E4312081856B000EF4AD /* InteropTestsLocalCleartextCFStream.xctest */,
+ 5EC5E442208185CE000EF4AD /* InteropTestsLocalSSLCFStream.xctest */,
);
name = Products;
sourceTree = "<group>";
@@ -433,7 +494,6 @@
5E8A5DA11D3840B4000F8BC4 /* Frameworks */,
5E8A5DA21D3840B4000F8BC4 /* Resources */,
E63468C760D0724F18861822 /* [CP] Embed Pods Frameworks */,
- 6DFE9E77CAB5760196D79E0F /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -454,7 +514,6 @@
5EAD6D211E27047400002378 /* Frameworks */,
5EAD6D221E27047400002378 /* Resources */,
A686B9967BB4CB81B1CBF8F8 /* [CP] Embed Pods Frameworks */,
- 051806D6A59B19C8A0B76BED /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -466,6 +525,63 @@
productReference = 5EAD6D241E27047400002378 /* CronetUnitTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
+ 5EC5E420208177CC000EF4AD /* InteropTestsRemoteCFStream */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 5EC5E42A208177CD000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsRemoteCFStream" */;
+ buildPhases = (
+ 483CDBBAEAEFCB530ADDDDD5 /* [CP] Check Pods Manifest.lock */,
+ 5EC5E41D208177CC000EF4AD /* Sources */,
+ 5EC5E41E208177CC000EF4AD /* Frameworks */,
+ 5EC5E41F208177CC000EF4AD /* Resources */,
+ 95FBC48B743503845678584F /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = InteropTestsRemoteCFStream;
+ productName = InteropTestsRemoteCFStream;
+ productReference = 5EC5E421208177CC000EF4AD /* InteropTestsRemoteCFStream.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ 5EC5E4302081856B000EF4AD /* InteropTestsLocalCleartextCFStream */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 5EC5E4362081856C000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsLocalCleartextCFStream" */;
+ buildPhases = (
+ 252A376345E38FD452A89C3D /* [CP] Check Pods Manifest.lock */,
+ 5EC5E42D2081856B000EF4AD /* Sources */,
+ 5EC5E42E2081856B000EF4AD /* Frameworks */,
+ 5EC5E42F2081856B000EF4AD /* Resources */,
+ A023FB55205A7EA37D413549 /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = InteropTestsLocalCleartextCFStream;
+ productName = InteropTestsLocalCleartextCFStream;
+ productReference = 5EC5E4312081856B000EF4AD /* InteropTestsLocalCleartextCFStream.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ 5EC5E441208185CE000EF4AD /* InteropTestsLocalSSLCFStream */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 5EC5E447208185CE000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsLocalSSLCFStream" */;
+ buildPhases = (
+ F3D5B2CDA172580341682830 /* [CP] Check Pods Manifest.lock */,
+ 5EC5E43E208185CE000EF4AD /* Sources */,
+ 5EC5E43F208185CE000EF4AD /* Frameworks */,
+ 5EC5E440208185CE000EF4AD /* Resources */,
+ 4EB2FFF40BB00AD0C545D7EF /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = InteropTestsLocalSSLCFStream;
+ productName = InteropTestsLocalSSLCFStream;
+ productReference = 5EC5E442208185CE000EF4AD /* InteropTestsLocalSSLCFStream.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
5EE84BF01D4717E40050C6CC /* InteropTestsRemoteWithCronet */ = {
isa = PBXNativeTarget;
buildConfigurationList = 5EE84BFB1D4717E40050C6CC /* Build configuration list for PBXNativeTarget "InteropTestsRemoteWithCronet" */;
@@ -496,7 +612,6 @@
63423F411B150A5F006CF63C /* Frameworks */,
63423F421B150A5F006CF63C /* Resources */,
A441F71824DCB9D0CA297748 /* [CP] Copy Pods Resources */,
- 5F14F59509E10C2852014F9E /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -512,11 +627,9 @@
isa = PBXNativeTarget;
buildConfigurationList = 635697DB1B14FC11007A7283 /* Build configuration list for PBXNativeTarget "Tests" */;
buildPhases = (
- 796680C7599CB4ED736DD62A /* [CP] Check Pods Manifest.lock */,
635697C31B14FC11007A7283 /* Sources */,
635697C41B14FC11007A7283 /* Frameworks */,
635697C51B14FC11007A7283 /* CopyFiles */,
- AEEBFC914CBAEE347382E8C4 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -535,7 +648,6 @@
63DC840F1BE15179000708E8 /* Sources */,
63DC84101BE15179000708E8 /* Frameworks */,
63DC84111BE15179000708E8 /* Resources */,
- 4F5690DC0E6AD6663FE78B8B /* [CP] Embed Pods Frameworks */,
C977426A8727267BBAC7D48E /* [CP] Copy Pods Resources */,
);
buildRules = (
@@ -556,7 +668,6 @@
63DC841F1BE15267000708E8 /* Sources */,
63DC84201BE15267000708E8 /* Frameworks */,
63DC84211BE15267000708E8 /* Resources */,
- 900B6EDD4D16BE7D765C3885 /* [CP] Embed Pods Frameworks */,
C2E09DC4BD239F71160F0CC1 /* [CP] Copy Pods Resources */,
);
buildRules = (
@@ -577,7 +688,6 @@
63DC84301BE15294000708E8 /* Sources */,
63DC84311BE15294000708E8 /* Frameworks */,
63DC84321BE15294000708E8 /* Resources */,
- C591129ACE9F6CC5EE03FCDE /* [CP] Embed Pods Frameworks */,
693DD0B453431D64EA24FD66 /* [CP] Copy Pods Resources */,
);
buildRules = (
@@ -598,7 +708,6 @@
63DC843F1BE152B5000708E8 /* Sources */,
63DC84401BE152B5000708E8 /* Frameworks */,
63DC84411BE152B5000708E8 /* Resources */,
- A8E3AC66DF770B774114A30E /* [CP] Embed Pods Frameworks */,
8AD3130D3C58A0FB32FF2A36 /* [CP] Copy Pods Resources */,
);
buildRules = (
@@ -626,6 +735,18 @@
5EAD6D231E27047400002378 = {
CreatedOnToolsVersion = 7.3.1;
};
+ 5EC5E420208177CC000EF4AD = {
+ CreatedOnToolsVersion = 9.2;
+ ProvisioningStyle = Automatic;
+ };
+ 5EC5E4302081856B000EF4AD = {
+ CreatedOnToolsVersion = 9.2;
+ ProvisioningStyle = Automatic;
+ };
+ 5EC5E441208185CE000EF4AD = {
+ CreatedOnToolsVersion = 9.2;
+ ProvisioningStyle = Automatic;
+ };
5EE84BF01D4717E40050C6CC = {
CreatedOnToolsVersion = 7.3.1;
};
@@ -670,6 +791,9 @@
5E8A5DA31D3840B4000F8BC4 /* CoreCronetEnd2EndTests */,
5EE84BF01D4717E40050C6CC /* InteropTestsRemoteWithCronet */,
5EAD6D231E27047400002378 /* CronetUnitTests */,
+ 5EC5E420208177CC000EF4AD /* InteropTestsRemoteCFStream */,
+ 5EC5E4302081856B000EF4AD /* InteropTestsLocalCleartextCFStream */,
+ 5EC5E441208185CE000EF4AD /* InteropTestsLocalSSLCFStream */,
);
};
/* End PBXProject section */
@@ -689,6 +813,28 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 5EC5E41F208177CC000EF4AD /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 5EC5E42F2081856B000EF4AD /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 5EC5E440208185CE000EF4AD /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5EC5E44E20818948000EF4AD /* TestCertificates.bundle in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
5EE84BEF1D4717E40050C6CC /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -736,22 +882,22 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
- 051806D6A59B19C8A0B76BED /* [CP] Copy Pods Resources */ = {
+ 252A376345E38FD452A89C3D /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
- "${SRCROOT}/Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests-resources.sh",
- "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle",
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
);
- name = "[CP] Copy Pods Resources";
+ name = "[CP] Check Pods Manifest.lock";
outputPaths = (
- "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle",
+ "$(DERIVED_FILE_DIR)/Pods-InteropTestsLocalCleartextCFStream-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests-resources.sh\"\n";
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
31F8D1C407195CBF0C02929B /* [CP] Embed Pods Frameworks */ = {
@@ -772,7 +918,7 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
- 4C406327D3907A5E5FBA8AC9 /* [CP] Check Pods Manifest.lock */ = {
+ 483CDBBAEAEFCB530ADDDDD5 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -783,29 +929,14 @@
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-InteropTestsRemote-checkManifestLockResult.txt",
+ "$(DERIVED_FILE_DIR)/Pods-InteropTestsRemoteCFStream-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
- 4F5690DC0E6AD6663FE78B8B /* [CP] Embed Pods Frameworks */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Embed Pods Frameworks";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-frameworks.sh\"\n";
- showEnvVarsInLog = 0;
- };
- 5C20DCCB71C3991E6FE78C22 /* [CP] Check Pods Manifest.lock */ = {
+ 4C406327D3907A5E5FBA8AC9 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -816,53 +947,56 @@
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-InteropTestsLocalSSL-checkManifestLockResult.txt",
+ "$(DERIVED_FILE_DIR)/Pods-InteropTestsRemote-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
- 5F14F59509E10C2852014F9E /* [CP] Embed Pods Frameworks */ = {
+ 4EB2FFF40BB00AD0C545D7EF /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
+ "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream-resources.sh",
+ "${PODS_CONFIGURATION_BUILD_DIR}/gRPC.default-CFStream/gRPCCertificates.bundle",
);
- name = "[CP] Embed Pods Frameworks";
+ name = "[CP] Copy Pods Resources";
outputPaths = (
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-frameworks.sh\"\n";
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- 693DD0B453431D64EA24FD66 /* [CP] Copy Pods Resources */ = {
+ 5C20DCCB71C3991E6FE78C22 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
- "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh",
- "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle",
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
);
- name = "[CP] Copy Pods Resources";
+ name = "[CP] Check Pods Manifest.lock";
outputPaths = (
- "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle",
+ "$(DERIVED_FILE_DIR)/Pods-InteropTestsLocalSSL-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh\"\n";
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
- 6DFE9E77CAB5760196D79E0F /* [CP] Copy Pods Resources */ = {
+ 693DD0B453431D64EA24FD66 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
- "${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-resources.sh",
+ "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle",
);
name = "[CP] Copy Pods Resources";
@@ -871,7 +1005,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-resources.sh\"\n";
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh\"\n";
showEnvVarsInLog = 0;
};
7418AC7B3844B29E48D24FC7 /* [CP] Check Pods Manifest.lock */ = {
@@ -892,24 +1026,6 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
- 796680C7599CB4ED736DD62A /* [CP] Check Pods Manifest.lock */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
- "${PODS_ROOT}/Manifest.lock",
- );
- name = "[CP] Check Pods Manifest.lock";
- outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-Tests-checkManifestLockResult.txt",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
- showEnvVarsInLog = 0;
- };
80E2DDD2EC04A4009F45E933 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -946,21 +1062,6 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- 900B6EDD4D16BE7D765C3885 /* [CP] Embed Pods Frameworks */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Embed Pods Frameworks";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote-frameworks.sh\"\n";
- showEnvVarsInLog = 0;
- };
914ADDD7106BA9BB8A7E569F /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -979,14 +1080,14 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
- A441F71824DCB9D0CA297748 /* [CP] Copy Pods Resources */ = {
+ 95FBC48B743503845678584F /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
- "${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh",
- "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle",
+ "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream-resources.sh",
+ "${PODS_CONFIGURATION_BUILD_DIR}/gRPC.default-CFStream/gRPCCertificates.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
@@ -994,58 +1095,61 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh\"\n";
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- A686B9967BB4CB81B1CBF8F8 /* [CP] Embed Pods Frameworks */ = {
+ A023FB55205A7EA37D413549 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
- "${SRCROOT}/Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests-frameworks.sh",
- "${PODS_ROOT}/CronetFramework/Cronet.framework",
+ "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream-resources.sh",
+ "${PODS_CONFIGURATION_BUILD_DIR}/gRPC.default-CFStream/gRPCCertificates.bundle",
);
- name = "[CP] Embed Pods Frameworks";
+ name = "[CP] Copy Pods Resources";
outputPaths = (
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests-frameworks.sh\"\n";
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- A8E3AC66DF770B774114A30E /* [CP] Embed Pods Frameworks */ = {
+ A441F71824DCB9D0CA297748 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
+ "${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh",
+ "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle",
);
- name = "[CP] Embed Pods Frameworks";
+ name = "[CP] Copy Pods Resources";
outputPaths = (
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-frameworks.sh\"\n";
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- AEEBFC914CBAEE347382E8C4 /* [CP] Copy Pods Resources */ = {
+ A686B9967BB4CB81B1CBF8F8 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
- "${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-resources.sh",
- "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle",
+ "${SRCROOT}/Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests-frameworks.sh",
+ "${PODS_ROOT}/CronetFramework/Cronet.framework",
);
- name = "[CP] Copy Pods Resources";
+ name = "[CP] Embed Pods Frameworks";
outputPaths = (
- "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-resources.sh\"\n";
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
B2986CEEE8CDD4901C97598B /* [CP] Check Pods Manifest.lock */ = {
@@ -1102,21 +1206,6 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- C591129ACE9F6CC5EE03FCDE /* [CP] Embed Pods Frameworks */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Embed Pods Frameworks";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-frameworks.sh\"\n";
- showEnvVarsInLog = 0;
- };
C977426A8727267BBAC7D48E /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -1171,6 +1260,24 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
+ F3D5B2CDA172580341682830 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-InteropTestsLocalSSLCFStream-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
F58F17E425446B15028B9F74 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -1208,6 +1315,34 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 5EC5E41D208177CC000EF4AD /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5EC5E42B2081782C000EF4AD /* InteropTestsRemote.m in Sources */,
+ 5EC5E42C20817832000EF4AD /* InteropTests.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 5EC5E42D2081856B000EF4AD /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5EC5E43B208185A7000EF4AD /* InteropTestsLocalCleartext.m in Sources */,
+ 5EC5E43D208185B0000EF4AD /* GRPCClientTests.m in Sources */,
+ 5EC5E43C208185AD000EF4AD /* InteropTests.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 5EC5E43E208185CE000EF4AD /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5EC5E44D208185F0000EF4AD /* InteropTestsLocalSSL.m in Sources */,
+ 5EC5E44C208185EC000EF4AD /* InteropTests.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
5EE84BED1D4717E40050C6CC /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -1350,6 +1485,7 @@
"HOST_PORT_LOCALSSL=$(HOST_PORT_LOCALSSL)",
"HOST_PORT_LOCAL=$(HOST_PORT_LOCAL)",
"HOST_PORT_REMOTE=$(HOST_PORT_REMOTE)",
+ "GRPC_TEST_OBJC=1",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
@@ -1368,7 +1504,6 @@
};
5E1228991E4D400F00E8504F /* Test */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = A0361771A855917162911180 /* Pods-Tests.test.xcconfig */;
buildSettings = {
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1668,7 +1803,6 @@
};
5EC3C7A11D4FC18C000330E2 /* Cronet */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = F671D4CAD2864FB203B920B4 /* Pods-Tests.cronet.xcconfig */;
buildSettings = {
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1797,6 +1931,360 @@
};
name = Cronet;
};
+ 5EC5E426208177CC000EF4AD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 32748C4078AEB05F8F954361 /* Pods-InteropTestsRemoteCFStream.debug.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteCFStream;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 5EC5E427208177CC000EF4AD /* Test */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = C17F57E5BCB989AB1C2F1F25 /* Pods-InteropTestsRemoteCFStream.test.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteCFStream;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Test;
+ };
+ 5EC5E428208177CC000EF4AD /* Cronet */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 4A1A42B2E941CCD453489E5B /* Pods-InteropTestsRemoteCFStream.cronet.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteCFStream;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Cronet;
+ };
+ 5EC5E429208177CC000EF4AD /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 303F4A17EB1650FC44603D17 /* Pods-InteropTestsRemoteCFStream.release.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteCFStream;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ 5EC5E4372081856C000EF4AD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 943138072A9605B5B8DC1FC0 /* Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartextCFStream;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 5EC5E4382081856C000EF4AD /* Test */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = E4FD4606D4AB8D5A314D72F0 /* Pods-InteropTestsLocalCleartextCFStream.test.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartextCFStream;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Test;
+ };
+ 5EC5E4392081856C000EF4AD /* Cronet */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 8B498B05C6DA0818B2FA91D4 /* Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartextCFStream;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Cronet;
+ };
+ 5EC5E43A2081856C000EF4AD /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7BA53C6D224288D5870FE6F3 /* Pods-InteropTestsLocalCleartextCFStream.release.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartextCFStream;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ 5EC5E448208185CE000EF4AD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 3EB55EF291706E3DDE23C3B7 /* Pods-InteropTestsLocalSSLCFStream.debug.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSLCFStream;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 5EC5E449208185CE000EF4AD /* Test */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 41AA59529240A6BBBD3DB904 /* Pods-InteropTestsLocalSSLCFStream.test.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSLCFStream;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Test;
+ };
+ 5EC5E44A208185CE000EF4AD /* Cronet */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 55B630C1FF8C36D1EFC4E0A4 /* Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSLCFStream;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Cronet;
+ };
+ 5EC5E44B208185CE000EF4AD /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 5EA908CF4CDA4CE218352A06 /* Pods-InteropTestsLocalSSLCFStream.release.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSLCFStream;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
5EE84BF91D4717E40050C6CC /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */;
@@ -1953,7 +2441,6 @@
};
635697DC1B14FC11007A7283 /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 060EF32D7EC0DF67ED617507 /* Pods-Tests.debug.xcconfig */;
buildSettings = {
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1963,7 +2450,6 @@
};
635697DD1B14FC11007A7283 /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = E6733B838B28453434B556E2 /* Pods-Tests.release.xcconfig */;
buildSettings = {
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2100,6 +2586,39 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 5EC5E42A208177CD000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsRemoteCFStream" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 5EC5E426208177CC000EF4AD /* Debug */,
+ 5EC5E427208177CC000EF4AD /* Test */,
+ 5EC5E428208177CC000EF4AD /* Cronet */,
+ 5EC5E429208177CC000EF4AD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 5EC5E4362081856C000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsLocalCleartextCFStream" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 5EC5E4372081856C000EF4AD /* Debug */,
+ 5EC5E4382081856C000EF4AD /* Test */,
+ 5EC5E4392081856C000EF4AD /* Cronet */,
+ 5EC5E43A2081856C000EF4AD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 5EC5E447208185CE000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsLocalSSLCFStream" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 5EC5E448208185CE000EF4AD /* Debug */,
+ 5EC5E449208185CE000EF4AD /* Test */,
+ 5EC5E44A208185CE000EF4AD /* Cronet */,
+ 5EC5E44B208185CE000EF4AD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
5EE84BFB1D4717E40050C6CC /* Build configuration list for PBXNativeTarget "InteropTestsRemoteWithCronet" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme
index a2560fee02..b0bb933764 100644
--- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme
+++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme
@@ -26,6 +26,7 @@
buildConfiguration = "Test"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
@@ -66,6 +67,7 @@
buildConfiguration = "Test"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme
index 6d85b62fab..510115fc75 100644
--- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme
+++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme
@@ -26,6 +26,7 @@
buildConfiguration = "Test"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
@@ -57,6 +58,7 @@
buildConfiguration = "Test"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartextCFStream.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartextCFStream.xcscheme
new file mode 100644
index 0000000000..fe766de928
--- /dev/null
+++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartextCFStream.xcscheme
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0920"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Test"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ language = ""
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "5EC5E4302081856B000EF4AD"
+ BuildableName = "InteropTestsLocalCleartextCFStream.xctest"
+ BlueprintName = "InteropTestsLocalCleartextCFStream"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ <SkippedTests>
+ <Test
+ Identifier = "InteropTests">
+ </Test>
+ </SkippedTests>
+ </TestableReference>
+ </Testables>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ language = ""
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSLCFStream.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSLCFStream.xcscheme
new file mode 100644
index 0000000000..bd66327649
--- /dev/null
+++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSLCFStream.xcscheme
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0920"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Test"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ language = ""
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "5EC5E441208185CE000EF4AD"
+ BuildableName = "InteropTestsLocalSSLCFStream.xctest"
+ BlueprintName = "InteropTestsLocalSSLCFStream"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ <SkippedTests>
+ <Test
+ Identifier = "InteropTests">
+ </Test>
+ </SkippedTests>
+ </TestableReference>
+ </Testables>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ language = ""
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme
index 412bf6a014..48837e57f9 100644
--- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme
+++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme
@@ -26,6 +26,7 @@
buildConfiguration = "Test"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
@@ -60,6 +61,7 @@
buildConfiguration = "Test"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteCFStream.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteCFStream.xcscheme
new file mode 100644
index 0000000000..33a5ded038
--- /dev/null
+++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteCFStream.xcscheme
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0920"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Test"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "5EC5E420208177CC000EF4AD"
+ BuildableName = "InteropTestsRemoteCFStream.xctest"
+ BlueprintName = "InteropTestsRemoteCFStream"
+ ReferencedContainer = "container:Tests.xcodeproj">
+ </BuildableReference>
+ <SkippedTests>
+ <Test
+ Identifier = "InteropTests">
+ </Test>
+ </SkippedTests>
+ </TestableReference>
+ </Testables>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/src/objective-c/tests/analyze_link_map.py b/src/objective-c/tests/analyze_link_map.py
deleted file mode 100755
index 48e3441087..0000000000
--- a/src/objective-c/tests/analyze_link_map.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/python
-# Copyright 2018 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.
-
-# This script analyzes link map file generated by Xcode. It calculates and
-# prints out the sizes of each dependent library and the total sizes of the
-# symbols.
-# The script takes one parameter, which is the path to the link map file.
-
-import sys
-import re
-
-table_tag = {}
-state = "start"
-
-table_stats_symbol = {}
-table_stats_dead = {}
-section_total_size = 0
-symbol_total_size = 0
-
-
-file_import = sys.argv[1]
-lines = list(open(file_import))
-for line in lines:
- line_stripped = line[:-1]
- if "# Object files:" == line_stripped:
- state = "object"
- continue
- elif "# Sections:" == line_stripped:
- state = "section"
- continue
- elif "# Symbols:" == line_stripped:
- state = "symbol"
- continue
- elif "# Dead Stripped Symbols:" == line_stripped:
- state = "dead"
- continue
-
- if state == "object":
- segs = re.search('(\[ *[0-9]*\]) (.*)', line_stripped)
- table_tag[segs.group(1)] = segs.group(2)
-
- if state == "section":
- if len(line_stripped) == 0 or line_stripped[0] == '#':
- continue
- segs = re.search('^(.+?)\s+(.+?)\s+.*', line_stripped)
- section_total_size += int(segs.group(2), 16)
-
- if state == "symbol":
- if len(line_stripped) == 0 or line_stripped[0] == '#':
- continue
- segs = re.search('^.+?\s+(.+?)\s+(\[.+?\]).*', line_stripped)
- target = table_tag[segs.group(2)]
- target_stripped = re.search('^(.*?)(\(.+?\))?$', target).group(1)
- size = int(segs.group(1), 16)
- if not target_stripped in table_stats_symbol:
- table_stats_symbol[target_stripped] = 0
- table_stats_symbol[target_stripped] += size
-
-print("Sections total size: %d" % section_total_size)
-
-for target in table_stats_symbol:
- print(target)
- print(table_stats_symbol[target])
- symbol_total_size += table_stats_symbol[target]
-
-print("Symbols total size: %d" % symbol_total_size)
diff --git a/src/objective-c/tests/build_one_example.sh b/src/objective-c/tests/build_one_example.sh
index 985d55f3cc..1eace541e6 100755
--- a/src/objective-c/tests/build_one_example.sh
+++ b/src/objective-c/tests/build_one_example.sh
@@ -42,6 +42,9 @@ xcodebuild \
build \
-workspace *.xcworkspace \
-scheme $SCHEME \
- -destination name="iPhone 6" \
+ -destination generic/platform=iOS \
+ -derivedDataPath Build \
+ CODE_SIGN_IDENTITY="" \
+ CODE_SIGNING_REQUIRED=NO \
| egrep -v "$XCODEBUILD_FILTER" \
| egrep -v "^$" -
diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh
index 2fe2326207..9dde07d55c 100755
--- a/src/objective-c/tests/run_tests.sh
+++ b/src/objective-c/tests/run_tests.sh
@@ -53,7 +53,7 @@ while [ $retries -lt 3 ]; do
out=$(xcodebuild \
-workspace Tests.xcworkspace \
-scheme AllTests \
- -destination name="iPhone 6" \
+ -destination name="iPhone 8" \
HOST_PORT_LOCALSSL=localhost:5051 \
HOST_PORT_LOCAL=localhost:5050 \
HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \
@@ -83,7 +83,7 @@ echo "TIME: $(date)"
xcodebuild \
-workspace Tests.xcworkspace \
-scheme CoreCronetEnd2EndTests \
- -destination name="iPhone 6" \
+ -destination name="iPhone 8" \
test \
| egrep -v "$XCODEBUILD_FILTER" \
| egrep -v '^$' \
@@ -113,7 +113,7 @@ echo "TIME: $(date)"
xcodebuild \
-workspace Tests.xcworkspace \
-scheme CronetUnitTests \
- -destination name="iPhone 6" \
+ -destination name="iPhone 8" \
test \
| egrep -v "$XCODEBUILD_FILTER" \
| egrep -v '^$' \
@@ -123,11 +123,44 @@ echo "TIME: $(date)"
xcodebuild \
-workspace Tests.xcworkspace \
-scheme InteropTestsRemoteWithCronet \
- -destination name="iPhone 6" \
+ -destination name="iPhone 8" \
+ HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \
+ test \
+ | egrep -v "$XCODEBUILD_FILTER" \
+ | egrep -v '^$' \
+ | egrep -v "(GPBDictionary|GPBArray)" -
+
+echo "TIME: $(date)"
+xcodebuild \
+ -workspace Tests.xcworkspace \
+ -scheme InteropTestsRemoteCFStream \
+ -destination name="iPhone 8" \
HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \
test \
| egrep -v "$XCODEBUILD_FILTER" \
| egrep -v '^$' \
| egrep -v "(GPBDictionary|GPBArray)" -
+echo "TIME: $(date)"
+xcodebuild \
+ -workspace Tests.xcworkspace \
+ -scheme InteropTestsLocalCleartextCFStream \
+ -destination name="iPhone 8" \
+ HOST_PORT_LOCAL=localhost:5050 \
+ test \
+ | egrep -v "$XCODEBUILD_FILTER" \
+ | egrep -v '^$' \
+ | egrep -v "(GPBDictionary|GPBArray)" -
+
+echo "TIME: $(date)"
+xcodebuild \
+ -workspace Tests.xcworkspace \
+ -scheme InteropTestsLocalSSLCFStream \
+ -destination name="iPhone 8" \
+ HOST_PORT_LOCALSSL=localhost:5051 \
+ test \
+ | egrep -v "$XCODEBUILD_FILTER" \
+ | egrep -v '^$' \
+ | egrep -v "(GPBDictionary|GPBArray)" -
+
exit 0
diff --git a/src/php/README.md b/src/php/README.md
index 11f99e134c..5e9fa38763 100644
--- a/src/php/README.md
+++ b/src/php/README.md
@@ -2,11 +2,15 @@
# Overview
This directory contains source code for PHP implementation of gRPC layered on
-shared C library.
+shared C library. The same installation guides with more examples and
+tutorials can be seen at [grpc.io](https://grpc.io/docs/quickstart/php.html).
+gRPC PHP installation instructions for Google Cloud Platform is in
+[cloud.google.com](https://cloud.google.com/php/grpc).
## Environment
-**Prerequisite:**
+### Prerequisite:
+
* `php` 5.5 or above, 7.0 or above
* `pecl`
* `composer`
@@ -25,6 +29,10 @@ For PHP7:
```sh
$ sudo apt-get install php7.0 php7.0-dev php-pear phpunit
```
+or
+```sh
+$ sudo apt-get install php php-dev php-pear phpunit
+```
**Install PHP and PECL on CentOS/RHEL 7:**
```sh
@@ -33,8 +41,9 @@ $ sudo rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
$ sudo yum install php56w php56w-devel php-pear phpunit gcc zlib-devel
```
-**Install PECL on Mac:**
+**Install PHP and PECL on Mac:**
```sh
+$ brew install homebrew/php/php56-grpc
$ curl -O http://pear.php.net/go-pear.phar
$ sudo php -d detect_unicode=0 go-pear.phar
```
@@ -52,50 +61,33 @@ $ chmod +x phpunit-old.phar
$ sudo mv phpunit-old.phar /usr/bin/phpunit
```
-## Quick Install
+## Install the gRPC PHP extension
-**Install the gRPC PHP extension**
+There are two ways to install gRPC PHP extension.
+* `pecl`
+* `build from source`
+
+### Using PECL
```sh
sudo pecl install grpc
```
-This will compile and install the gRPC PHP extension into the standard PHP
-extension directory. You should be able to run the [unit tests](#unit-tests),
-with the PHP extension installed.
-
-Note: For users on CentOS/RHEL 6, unfortunately this step won't work. Please
-follow the instructions below to compile the extension from source.
-
-
-**Update php.ini**
-
-Add this line to your `php.ini` file, e.g. `/etc/php5/cli/php.ini`
+or specific version
```sh
-extension=grpc.so
-```
-
-
-**Add the gRPC PHP library as a Composer dependency**
-
-You need to add this to your project's `composer.json` file.
-
-```
- "require": {
- "grpc/grpc": "v1.1.0"
- }
+sudo pecl install grpc-1.12.0
```
-To run tests with generated stub code from `.proto` files, you will also need
-the `composer` and `protoc` binaries. You can find out how to get these
-[below](#generated-code-tests).
+Note: for users on CentOS/RHEL 6, unfortunately this step won’t work.
+Please follow the instructions below to compile the PECL extension from source.
+#### Install on Windows
-## Build from Source
+You can download the pre-compiled gRPC extension from the PECL
+[website](https://pecl.php.net/package/grpc)
-
-### gRPC C core library
+### Build from Source with gRPC C core library
Clone this repository
@@ -103,16 +95,16 @@ Clone this repository
$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
```
-Build and install the gRPC C core library
+#### Build and install the gRPC C core library
```sh
$ cd grpc
-$ git pull --recurse-submodules && git submodule update --init --recursive
+$ git submodule update --init
$ make
$ sudo make install
```
-### gRPC PHP extension
+#### Build and install gRPC PHP extension
Compile the gRPC PHP extension
@@ -124,44 +116,69 @@ $ make
$ sudo make install
```
-## Unit Tests
+This will compile and install the gRPC PHP extension into the
+standard PHP extension directory. You should be able to run
+the [unit tests](#unit-tests), with the PHP extension installed.
-You will need the source code to run tests
+
+### Update php.ini
+
+After installing the gRPC extension, make sure you add this line
+to your `php.ini` file, (e.g. `/etc/php5/cli/php.ini`,
+`/etc/php5/apache2/php.ini`, or `/usr/local/etc/php/5.6/php.ini`),
+depending on where your PHP installation is.
```sh
-$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
-$ cd grpc
-$ git pull --recurse-submodules && git submodule update --init --recursive
+extension=grpc.so
```
-Run unit tests
+**Add the gRPC PHP library as a Composer dependency**
-```sh
-$ cd grpc/src/php
-$ ./bin/run_tests.sh
+You need to add this to your project's `composer.json` file.
+
+```
+ "require": {
+ "grpc/grpc": "v1.12.0"
+ }
```
-## Generated Code Tests
+To run tests with generated stub code from `.proto` files, you will also
+need the `composer` and `protoc` binaries. You can find out how to get these below.
-This section specifies the prerequisites for running the generated code tests,
-as well as how to run the tests themselves.
+## Install other prerequisites for both Mac OS X and Linux
-### Composer
+* `protoc: protobuf compiler`
+* `protobuf.so: protobuf runtime library`
+* `grpc_php_plugin: Generates PHP gRPC service interface out of Protobuf IDL`
-Install the runtime dependencies via `composer install`.
+### Install Protobuf compiler
-```sh
-$ cd grpc/src/php
-$ composer install
-```
+If you don't have it already, you need to install the protobuf compiler
+`protoc`, version 3.5.0+ (the newer the better) for the current gRPC version.
+If you installed already, make the protobuf version is compatible to the
+grpc version you installed. If you build grpc.so from the souce, you can check
+the version of grpc inside package.xml file.
-### Protobuf compiler
+The compatibility between the grpc and protobuf version is listed as table below:
-Again if you don't have it already, you need to install the protobuf compiler
-`protoc`, version 3.1.0+ (the newer the better).
+grpc | protobuf
+--- | ---
+v1.0.0 | 3.0.0(GA)
+v1.0.1 | 3.0.2
+v1.1.0 | 3.1.0
+v1.2.0 | 3.2.0
+v1.2.0 | 3.2.0
+v1.3.4 | 3.3.0
+v1.3.5 | 3.2.0
+v1.4.0 | 3.3.0
+v1.6.0 | 3.4.0
+v1.8.0 | 3.5.0
+v1.12.0 | 3.5.2
If `protoc` hasn't been installed, you can download the `protoc` binaries from
[the protocol buffers Github repository](https://github.com/google/protobuf/releases).
+Then unzip this file and update the environment variable `PATH` to include the path to
+the protoc binary file.
If you really must compile `protoc` from source, you can run the following
commands, but this is risky because there is no easy way to uninstall /
@@ -173,32 +190,44 @@ $ ./autogen.sh && ./configure && make
$ sudo make install
```
-
### Protobuf Runtime library
-There are two protobuf runtime libraries to choose from. They are idenfical in terms of APIs offered.
+There are two protobuf runtime libraries to choose from. They are identical
+in terms of APIs offered. The C implementation provides better performance,
+while the native implementation is easier to install. Make sure the installed
+protobuf version works with grpc version.
-1. C implementation (for better performance)
+#### 1. C implementation (for better performance)
``` sh
$ sudo pecl install protobuf
```
+or specific version
-2. PHP implementation (for easier installation)
+``` sh
+$ sudo pecl install protobuf-3.5.1.1
+```
+Add this to your `php.ini` file:
+
+```sh
+extension=protobuf.so
+```
+
+#### 2. PHP implementation (for easier installation)
Add this to your `composer.json` file:
```
"require": {
- "google/protobuf": "^v3.3.0"
+ "google/protobuf": "^v3.5.0"
}
-```
-
+```
### PHP Protoc Plugin
You need the gRPC PHP protoc plugin to generate the client stub classes.
+It can generate server and client code from .proto service definitions.
It should already been compiled when you run `make` from the root directory
of this repo. The plugin can be found in the `bins/opt` directory. We are
@@ -208,10 +237,47 @@ in the future.
You can also just build the gRPC PHP protoc plugin by running:
```sh
+$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
$ cd grpc
+$ git submodule update --init
$ make grpc_php_plugin
```
+Plugin may use the new feature of the new protobuf version, thus please also
+make sure that the protobuf version installed is compatible with the grpc version
+you build this plugin.
+
+## Unit Tests
+
+You will need the source code to run tests
+
+```sh
+$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
+$ cd grpc
+$ git submodule update --init
+```
+
+Run unit tests
+
+```sh
+$ cd grpc/src/php
+$ ./bin/run_tests.sh
+```
+
+## Generated Code Tests
+
+This section specifies the prerequisites for running the generated code tests,
+as well as how to run the tests themselves.
+
+### Composer
+
+Install the runtime dependencies via `composer install`.
+
+```sh
+$ cd grpc/src/php
+$ composer install
+```
+
### Client Stub
diff --git a/src/proto/grpc/testing/messages.proto b/src/proto/grpc/testing/messages.proto
index 0b8c15711e..7b1b7286dc 100644
--- a/src/proto/grpc/testing/messages.proto
+++ b/src/proto/grpc/testing/messages.proto
@@ -27,7 +27,6 @@ message BoolValue {
bool value = 1;
}
-// DEPRECATED, don't use. To be removed shortly.
// The type of payload that should be returned.
enum PayloadType {
// Compressable text format.
@@ -36,7 +35,6 @@ enum PayloadType {
// A block of data, to simply increase gRPC message size.
message Payload {
- // DEPRECATED, don't use. To be removed shortly.
// The type of data in body.
PayloadType type = 1;
// Primary contents of payload.
@@ -52,7 +50,6 @@ message EchoStatus {
// Unary request.
message SimpleRequest {
- // DEPRECATED, don't use. To be removed shortly.
// Desired payload type in the response from the server.
// If response_type is RANDOM, server randomly chooses one from other formats.
PayloadType response_type = 1;
@@ -131,7 +128,6 @@ message ResponseParameters {
// Server-streaming request.
message StreamingOutputCallRequest {
- // DEPRECATED, don't use. To be removed shortly.
// Desired payload type in the response from the server.
// If response_type is RANDOM, the payload from each response in the stream
// might be of different types. This is to simulate a mixed type of payload
diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py
index b7ed0c8563..996d075446 100644
--- a/src/python/grpcio/grpc/__init__.py
+++ b/src/python/grpcio/grpc/__init__.py
@@ -1250,19 +1250,20 @@ class Server(six.with_metaclass(abc.ABCMeta)):
"""Stops this Server.
This method immediately stop service of new RPCs in all cases.
+
If a grace period is specified, this method returns immediately
and all RPCs active at the end of the grace period are aborted.
-
- If a grace period is not specified, then all existing RPCs are
- teriminated immediately and the this method blocks until the last
- RPC handler terminates.
+ If a grace period is not specified (by passing None for `grace`),
+ all existing RPCs are aborted immediately and this method
+ blocks until the last RPC handler terminates.
This method is idempotent and may be called at any time.
- Passing a smaller grace value in subsequent call will have
- the effect of stopping the Server sooner. Passing a larger
- grace value in subsequent call *will not* have the effect of
- stopping the server later (i.e. the most restrictive grace
- value is used).
+ Passing a smaller grace value in a subsequent call will have
+ the effect of stopping the Server sooner (passing None will
+ have the effect of stopping the server immediately). Passing
+ a larger grace value in a subsequent call *will not* have the
+ effect of stopping the server later (i.e. the most restrictive
+ grace value is used).
Args:
grace: A duration of time in seconds or None.
@@ -1481,7 +1482,7 @@ def ssl_server_credentials(private_key_certificate_chain_pairs,
A ServerCredentials for use with an SSL-enabled Server. Typically, this
object is an argument to add_secure_port() method during server setup.
"""
- if len(private_key_certificate_chain_pairs) == 0:
+ if not private_key_certificate_chain_pairs:
raise ValueError(
'At least one private key-certificate chain pair is required!')
elif require_client_auth and root_certificates is None:
@@ -1511,15 +1512,15 @@ def ssl_server_certificate_configuration(private_key_certificate_chain_pairs,
A ServerCertificateConfiguration that can be returned in the certificate
configuration fetching callback.
"""
- if len(private_key_certificate_chain_pairs) == 0:
- raise ValueError(
- 'At least one private key-certificate chain pair is required!')
- else:
+ if private_key_certificate_chain_pairs:
return ServerCertificateConfiguration(
_cygrpc.server_certificate_config_ssl(root_certificates, [
_cygrpc.SslPemKeyCertPair(key, pem)
for key, pem in private_key_certificate_chain_pairs
]))
+ else:
+ raise ValueError(
+ 'At least one private key-certificate chain pair is required!')
def dynamic_ssl_server_credentials(initial_certificate_configuration,
@@ -1655,9 +1656,11 @@ def server(thread_pool,
A Server object.
"""
from grpc import _server # pylint: disable=cyclic-import
- return _server.Server(thread_pool, () if handlers is None else handlers, ()
- if interceptors is None else interceptors, () if
- options is None else options, maximum_concurrent_rpcs)
+ return _server.create_server(thread_pool, ()
+ if handlers is None else handlers, ()
+ if interceptors is None else interceptors, ()
+ if options is None else options,
+ maximum_concurrent_rpcs)
################################### __all__ #################################
diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index 2017d47130..e9246991df 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -24,6 +24,8 @@ from grpc import _grpcio_metadata
from grpc._cython import cygrpc
from grpc.framework.foundation import callable_util
+_LOGGER = logging.getLogger(__name__)
+
_USER_AGENT = 'grpc-python/{}'.format(_grpcio_metadata.__version__)
_EMPTY_FLAGS = 0
@@ -181,7 +183,7 @@ def _consume_request_iterator(request_iterator, state, call, request_serializer,
except Exception: # pylint: disable=broad-except
code = grpc.StatusCode.UNKNOWN
details = 'Exception iterating requests!'
- logging.exception(details)
+ _LOGGER.exception(details)
call.cancel(_common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[code],
details)
_abort(state, code, details)
@@ -190,7 +192,7 @@ def _consume_request_iterator(request_iterator, state, call, request_serializer,
with state.condition:
if state.code is None and not state.cancelled:
if serialized_request is None:
- code = grpc.StatusCode.INTERNAL # pylint: disable=redefined-variable-type
+ code = grpc.StatusCode.INTERNAL
details = 'Exception serializing request!'
call.cancel(
_common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[code],
@@ -811,10 +813,7 @@ def _poll_connectivity(state, channel, initial_try_to_connect):
_common.CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
connectivity])
if not state.delivering:
- # NOTE(nathaniel): The field is only ever used as a
- # sequence so it's fine that both lists and tuples are
- # assigned to it.
- callbacks = _deliveries(state) # pylint: disable=redefined-variable-type
+ callbacks = _deliveries(state)
if callbacks:
_spawn_delivery(state, callbacks)
diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py
index 862987a0cd..8358cbec5b 100644
--- a/src/python/grpcio/grpc/_common.py
+++ b/src/python/grpcio/grpc/_common.py
@@ -20,6 +20,8 @@ import six
import grpc
from grpc._cython import cygrpc
+_LOGGER = logging.getLogger(__name__)
+
CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = {
cygrpc.ConnectivityState.idle:
grpc.ChannelConnectivity.IDLE,
@@ -73,7 +75,7 @@ def decode(b):
try:
return b.decode('utf8')
except UnicodeDecodeError:
- logging.exception('Invalid encoding on %s', b)
+ _LOGGER.exception('Invalid encoding on %s', b)
return b.decode('latin1')
@@ -84,7 +86,7 @@ def _transform(message, transformer, exception_message):
try:
return transformer(message)
except Exception: # pylint: disable=broad-except
- logging.exception(exception_message)
+ _LOGGER.exception(exception_message)
return None
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi
index 65de30884c..aecd3d7b11 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi
@@ -15,10 +15,12 @@
cimport cpython
+# TODO(https://github.com/grpc/grpc/issues/15662): Reform this.
cdef void* _copy_pointer(void* pointer):
return pointer
+# TODO(https://github.com/grpc/grpc/issues/15662): Reform this.
cdef void _destroy_pointer(void* pointer):
pass
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi
index eefc685c0b..f067d76fab 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi
@@ -69,3 +69,6 @@ cdef class Channel:
cdef grpc_arg_pointer_vtable _vtable
cdef _ChannelState _state
+
+ # TODO(https://github.com/grpc/grpc/issues/15662): Eliminate this.
+ cdef tuple _arguments
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
index 72e74e84ae..8c37a3cf85 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
@@ -390,6 +390,7 @@ cdef class Channel:
def __cinit__(
self, bytes target, object arguments,
ChannelCredentials channel_credentials):
+ arguments = () if arguments is None else tuple(arguments)
grpc_init()
self._state = _ChannelState()
self._vtable.copy = &_copy_pointer
@@ -410,6 +411,7 @@ cdef class Channel:
grpc_completion_queue_create_for_next(NULL))
self._state.c_connectivity_completion_queue = (
grpc_completion_queue_create_for_next(NULL))
+ self._arguments = arguments
def target(self):
cdef char *c_target
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
index 7e9ea33ca0..8d73215247 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
@@ -57,6 +57,11 @@ cdef class ChannelCredentials:
cdef grpc_channel_credentials *c_credentials
+cdef class SSLSessionCacheLRU:
+
+ cdef grpc_ssl_session_cache *_cache
+
+
cdef class SSLChannelCredentials(ChannelCredentials):
cdef readonly object _pem_root_certificates
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
index 500086f6cb..f4ccfbc016 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
@@ -17,6 +17,21 @@ cimport cpython
import grpc
import threading
+from libc.stdint cimport uintptr_t
+
+
+def _spawn_callback_in_thread(cb_func, args):
+ threading.Thread(target=cb_func, args=args).start()
+
+async_callback_func = _spawn_callback_in_thread
+
+def set_async_callback_func(callback_func):
+ global async_callback_func
+ async_callback_func = callback_func
+
+def _spawn_callback_async(callback, args):
+ async_callback_func(callback, args)
+
cdef class CallCredentials:
@@ -40,7 +55,7 @@ cdef int _get_metadata(
else:
cb(user_data, NULL, 0, status, error_details)
args = context.service_url, context.method_name, callback,
- threading.Thread(target=<object>state, args=args).start()
+ _spawn_callback_async(<object>state, args)
return 0 # Asynchronous return
@@ -96,6 +111,21 @@ cdef class ChannelCredentials:
raise NotImplementedError()
+cdef class SSLSessionCacheLRU:
+
+ def __cinit__(self, capacity):
+ grpc_init()
+ self._cache = grpc_ssl_session_cache_create_lru(capacity)
+
+ def __int__(self):
+ return <uintptr_t>self._cache
+
+ def __dealloc__(self):
+ if self._cache != NULL:
+ grpc_ssl_session_cache_destroy(self._cache)
+ grpc_shutdown()
+
+
cdef class SSLChannelCredentials(ChannelCredentials):
def __cinit__(self, pem_root_certificates, private_key, certificate_chain):
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
index 2d6c900c54..cfefeaf938 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
@@ -131,6 +131,7 @@ cdef extern from "grpc/grpc.h":
const char *GRPC_ARG_PRIMARY_USER_AGENT_STRING
const char *GRPC_ARG_SECONDARY_USER_AGENT_STRING
const char *GRPC_SSL_TARGET_NAME_OVERRIDE_ARG
+ const char *GRPC_SSL_SESSION_CACHE_ARG
const char *GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM
const char *GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL
const char *GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET
@@ -452,8 +453,16 @@ cdef extern from "grpc/grpc_security.h":
# We don't care about the internals (and in fact don't know them)
pass
+
+ ctypedef struct grpc_ssl_session_cache:
+ # We don't care about the internals (and in fact don't know them)
+ pass
+
ctypedef void (*grpc_ssl_roots_override_callback)(char **pem_root_certs)
+ grpc_ssl_session_cache *grpc_ssl_session_cache_create_lru(size_t capacity)
+ void grpc_ssl_session_cache_destroy(grpc_ssl_session_cache* cache)
+
void grpc_set_ssl_roots_override_callback(
grpc_ssl_roots_override_callback cb) nogil
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi
index f5688d08cd..f5688d08cd 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi
index 31ef671aed..f9a1b2856d 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi
@@ -418,6 +418,11 @@ def init_grpc_gevent():
g_event = gevent.event.Event()
g_pool = gevent.pool.Group()
+
+ def cb_func(cb, args):
+ _spawn_greenlet(cb, *args)
+ set_async_callback_func(cb_func)
+
gevent_resolver_vtable.resolve = socket_resolve
gevent_resolver_vtable.resolve_async = socket_resolve_async
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi
index 53e06a1596..00a1b23a67 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi
@@ -14,6 +14,7 @@
import logging
+_LOGGER = logging.getLogger(__name__)
# This function will ascii encode unicode string inputs if neccesary.
# In Python3, unicode strings are the default str type.
@@ -49,5 +50,5 @@ cdef str _decode(bytes bytestring):
try:
return bytestring.decode('utf8')
except UnicodeDecodeError:
- logging.exception('Invalid encoding on %s', bytestring)
+ _LOGGER.exception('Invalid encoding on %s', bytestring)
return bytestring.decode('latin1')
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
index ecd991685f..37b98ebbdb 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
@@ -51,6 +51,7 @@ class ChannelArgKey:
default_authority = GRPC_ARG_DEFAULT_AUTHORITY
primary_user_agent_string = GRPC_ARG_PRIMARY_USER_AGENT_STRING
secondary_user_agent_string = GRPC_ARG_SECONDARY_USER_AGENT_STRING
+ ssl_session_cache = GRPC_SSL_SESSION_CACHE_ARG
ssl_target_name_override = GRPC_SSL_TARGET_NAME_OVERRIDE_ARG
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi
index 4588db30d3..52cfccb677 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi
@@ -23,6 +23,7 @@ cdef class Server:
cdef bint is_shutdown # notification of complete shutdown received
# used at dealloc when user forgets to shutdown
cdef CompletionQueue backup_shutdown_queue
+ # TODO(https://github.com/grpc/grpc/issues/15662): Elide this.
cdef list references
cdef list registered_completion_queues
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
index 707ec742dd..da3dd21244 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
@@ -18,6 +18,8 @@ import logging
import time
import grpc
+_LOGGER = logging.getLogger(__name__)
+
cdef grpc_ssl_certificate_config_reload_status _server_cert_config_fetcher_wrapper(
void* user_data, grpc_ssl_server_certificate_config **config) with gil:
# This is a credentials.ServerCertificateConfig
@@ -34,13 +36,13 @@ cdef grpc_ssl_certificate_config_reload_status _server_cert_config_fetcher_wrapp
try:
cert_config_wrapper = user_cb()
except Exception:
- logging.exception('Error fetching certificate config')
+ _LOGGER.exception('Error fetching certificate config')
return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL
if cert_config_wrapper is None:
return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED
elif not isinstance(
cert_config_wrapper, grpc.ServerCertificateConfiguration):
- logging.error(
+ _LOGGER.error(
'Error fetching certificate configuration: certificate '
'configuration must be of type grpc.ServerCertificateConfiguration, '
'not %s' % type(cert_config_wrapper).__name__)
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pxd b/src/python/grpcio/grpc/_cython/cygrpc.pxd
index c8ace7c3cc..e33c01c28f 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pxd
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pxd
@@ -29,4 +29,4 @@ include "_cygrpc/server.pxd.pxi"
include "_cygrpc/tag.pxd.pxi"
include "_cygrpc/time.pxd.pxi"
-include "_cygrpc/grpc_gevent.pxd"
+include "_cygrpc/grpc_gevent.pxd.pxi"
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx
index f5f08fc983..fb16fb16bf 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pyx
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx
@@ -36,7 +36,7 @@ include "_cygrpc/server.pyx.pxi"
include "_cygrpc/tag.pyx.pxi"
include "_cygrpc/time.pyx.pxi"
-include "_cygrpc/grpc_gevent.pyx"
+include "_cygrpc/grpc_gevent.pyx.pxi"
#
# initialize gRPC
diff --git a/src/python/grpcio/grpc/_interceptor.py b/src/python/grpcio/grpc/_interceptor.py
index f465e35a9c..6b7a912a94 100644
--- a/src/python/grpcio/grpc/_interceptor.py
+++ b/src/python/grpcio/grpc/_interceptor.py
@@ -100,6 +100,12 @@ class _LocalFailure(grpc.RpcError, grpc.Future, grpc.Call):
def cancelled(self):
return False
+ def is_active(self):
+ return False
+
+ def time_remaining(self):
+ return None
+
def running(self):
return False
@@ -115,6 +121,9 @@ class _LocalFailure(grpc.RpcError, grpc.Future, grpc.Call):
def traceback(self, ignored_timeout=None):
return self._traceback
+ def add_callback(self, callback):
+ return False
+
def add_done_callback(self, fn):
fn(self)
@@ -288,11 +297,11 @@ class _Channel(grpc.Channel):
self._channel = channel
self._interceptor = interceptor
- def subscribe(self, *args, **kwargs):
- self._channel.subscribe(*args, **kwargs)
+ def subscribe(self, callback, try_to_connect=False):
+ self._channel.subscribe(callback, try_to_connect=try_to_connect)
- def unsubscribe(self, *args, **kwargs):
- self._channel.unsubscribe(*args, **kwargs)
+ def unsubscribe(self, callback):
+ self._channel.unsubscribe(callback)
def unary_unary(self,
method,
diff --git a/src/python/grpcio/grpc/_plugin_wrapping.py b/src/python/grpcio/grpc/_plugin_wrapping.py
index 6785e5876a..916ee080b6 100644
--- a/src/python/grpcio/grpc/_plugin_wrapping.py
+++ b/src/python/grpcio/grpc/_plugin_wrapping.py
@@ -20,6 +20,8 @@ import grpc
from grpc import _common
from grpc._cython import cygrpc
+_LOGGER = logging.getLogger(__name__)
+
class _AuthMetadataContext(
collections.namedtuple('AuthMetadataContext', (
@@ -76,7 +78,7 @@ class _Plugin(object):
_AuthMetadataPluginCallback(
callback_state, callback))
except Exception as exception: # pylint: disable=broad-except
- logging.exception(
+ _LOGGER.exception(
'AuthMetadataPluginCallback "%s" raised exception!',
self._metadata_plugin)
with callback_state.lock:
diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py
index d849cadbee..7276a7fd90 100644
--- a/src/python/grpcio/grpc/_server.py
+++ b/src/python/grpcio/grpc/_server.py
@@ -27,6 +27,8 @@ from grpc import _interceptor
from grpc._cython import cygrpc
from grpc.framework.foundation import callable_util
+_LOGGER = logging.getLogger(__name__)
+
_SHUTDOWN_TAG = 'shutdown'
_REQUEST_CALL_TAG = 'request_call'
@@ -279,7 +281,7 @@ class _Context(grpc.ServicerContext):
def abort(self, code, details):
# treat OK like other invalid arguments: fail the RPC
if code == grpc.StatusCode.OK:
- logging.error(
+ _LOGGER.error(
'abort() called with StatusCode.OK; returning UNKNOWN')
code = grpc.StatusCode.UNKNOWN
details = ''
@@ -328,6 +330,8 @@ class _RequestIterator(object):
self._state.request = None
return request
+ raise AssertionError() # should never run
+
def _next(self):
with self._state.condition:
self._raise_or_start_receive_message()
@@ -390,7 +394,7 @@ def _call_behavior(rpc_event, state, behavior, argument, request_deserializer):
b'RPC Aborted')
elif exception not in state.rpc_errors:
details = 'Exception calling application: {}'.format(exception)
- logging.exception(details)
+ _LOGGER.exception(details)
_abort(state, rpc_event.call, cygrpc.StatusCode.unknown,
_common.encode(details))
return None, False
@@ -408,7 +412,7 @@ def _take_response_from_response_iterator(rpc_event, state, response_iterator):
b'RPC Aborted')
elif exception not in state.rpc_errors:
details = 'Exception iterating responses: {}'.format(exception)
- logging.exception(details)
+ _LOGGER.exception(details)
_abort(state, rpc_event.call, cygrpc.StatusCode.unknown,
_common.encode(details))
return None, False
@@ -617,7 +621,7 @@ def _handle_call(rpc_event, generic_handlers, interceptor_pipeline, thread_pool,
interceptor_pipeline)
except Exception as exception: # pylint: disable=broad-except
details = 'Exception servicing handler: {}'.format(exception)
- logging.exception(details)
+ _LOGGER.exception(details)
return _reject_rpc(rpc_event, cygrpc.StatusCode.unknown,
b'Error in service handler!'), None
if method_handler is None:
@@ -785,7 +789,16 @@ def _start(state):
thread.start()
-class Server(grpc.Server):
+def _validate_generic_rpc_handlers(generic_rpc_handlers):
+ for generic_rpc_handler in generic_rpc_handlers:
+ service_attribute = getattr(generic_rpc_handler, 'service', None)
+ if service_attribute is None:
+ raise AttributeError(
+ '"{}" must conform to grpc.GenericRpcHandler type but does '
+ 'not have "service" method!'.format(generic_rpc_handler))
+
+
+class _Server(grpc.Server):
# pylint: disable=too-many-arguments
def __init__(self, thread_pool, generic_handlers, interceptors, options,
@@ -798,6 +811,7 @@ class Server(grpc.Server):
thread_pool, maximum_concurrent_rpcs)
def add_generic_rpc_handlers(self, generic_rpc_handlers):
+ _validate_generic_rpc_handlers(generic_rpc_handlers)
_add_generic_handlers(self._state, generic_rpc_handlers)
def add_insecure_port(self, address):
@@ -815,3 +829,10 @@ class Server(grpc.Server):
def __del__(self):
_stop(self._state, None)
+
+
+def create_server(thread_pool, generic_rpc_handlers, interceptors, options,
+ maximum_concurrent_rpcs):
+ _validate_generic_rpc_handlers(generic_rpc_handlers)
+ return _Server(thread_pool, generic_rpc_handlers, interceptors, options,
+ maximum_concurrent_rpcs)
diff --git a/src/python/grpcio/grpc/_utilities.py b/src/python/grpcio/grpc/_utilities.py
index 25bd1ceae2..d90b34bcbd 100644
--- a/src/python/grpcio/grpc/_utilities.py
+++ b/src/python/grpcio/grpc/_utilities.py
@@ -116,6 +116,8 @@ class _ChannelReadyFuture(grpc.Future):
callable_util.call_logging_exceptions(
done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
+ return True
+
def cancelled(self):
with self._condition:
return self._cancelled
diff --git a/src/python/grpcio/grpc/beta/_server_adaptations.py b/src/python/grpcio/grpc/beta/_server_adaptations.py
index ccafec8951..80ac65b649 100644
--- a/src/python/grpcio/grpc/beta/_server_adaptations.py
+++ b/src/python/grpcio/grpc/beta/_server_adaptations.py
@@ -305,6 +305,7 @@ def _simple_method_handler(implementation, request_deserializer,
response_serializer, None, None, None,
_adapt_stream_stream_event(
implementation.stream_stream_event))
+ raise ValueError()
def _flatten_method_pair_map(method_pair_map):
diff --git a/src/python/grpcio/grpc/beta/utilities.py b/src/python/grpcio/grpc/beta/utilities.py
index b5d8aac71a..fe3ce606c9 100644
--- a/src/python/grpcio/grpc/beta/utilities.py
+++ b/src/python/grpcio/grpc/beta/utilities.py
@@ -85,6 +85,8 @@ class _ChannelReadyFuture(future.Future):
callable_util.call_logging_exceptions(
done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
+ return True
+
def cancelled(self):
with self._condition:
return self._cancelled
diff --git a/src/python/grpcio/grpc/experimental/session_cache.py b/src/python/grpcio/grpc/experimental/session_cache.py
new file mode 100644
index 0000000000..5c55f7c327
--- /dev/null
+++ b/src/python/grpcio/grpc/experimental/session_cache.py
@@ -0,0 +1,45 @@
+# Copyright 2018 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.
+"""gRPC's APIs for TLS Session Resumption support"""
+
+from grpc._cython import cygrpc as _cygrpc
+
+
+def ssl_session_cache_lru(capacity):
+ """Creates an SSLSessionCache with LRU replacement policy
+
+ Args:
+ capacity: Size of the cache
+
+ Returns:
+ An SSLSessionCache with LRU replacement policy that can be passed as a value for
+ the grpc.ssl_session_cache option to a grpc.Channel. SSL session caches are used
+ to store session tickets, which clients can present to resume previous TLS sessions
+ with a server.
+ """
+ return SSLSessionCache(_cygrpc.SSLSessionCacheLRU(capacity))
+
+
+class SSLSessionCache(object):
+ """An encapsulation of a session cache used for TLS session resumption.
+
+ Instances of this class can be passed to a Channel as values for the
+ grpc.ssl_session_cache option
+ """
+
+ def __init__(self, cache):
+ self._cache = cache
+
+ def __int__(self):
+ return int(self._cache)
diff --git a/src/python/grpcio/grpc/framework/foundation/callable_util.py b/src/python/grpcio/grpc/framework/foundation/callable_util.py
index b9b9c49f17..24daf3406f 100644
--- a/src/python/grpcio/grpc/framework/foundation/callable_util.py
+++ b/src/python/grpcio/grpc/framework/foundation/callable_util.py
@@ -21,6 +21,8 @@ import logging
import six
+_LOGGER = logging.getLogger(__name__)
+
class Outcome(six.with_metaclass(abc.ABCMeta)):
"""A sum type describing the outcome of some call.
@@ -53,7 +55,7 @@ def _call_logging_exceptions(behavior, message, *args, **kwargs):
return _EasyOutcome(Outcome.Kind.RETURNED, behavior(*args, **kwargs),
None)
except Exception as e: # pylint: disable=broad-except
- logging.exception(message)
+ _LOGGER.exception(message)
return _EasyOutcome(Outcome.Kind.RAISED, None, e)
diff --git a/src/python/grpcio/grpc/framework/foundation/logging_pool.py b/src/python/grpcio/grpc/framework/foundation/logging_pool.py
index f75df10042..216e3990db 100644
--- a/src/python/grpcio/grpc/framework/foundation/logging_pool.py
+++ b/src/python/grpcio/grpc/framework/foundation/logging_pool.py
@@ -17,6 +17,8 @@ import logging
from concurrent import futures
+_LOGGER = logging.getLogger(__name__)
+
def _wrap(behavior):
"""Wraps an arbitrary callable behavior in exception-logging."""
@@ -25,7 +27,7 @@ def _wrap(behavior):
try:
return behavior(*args, **kwargs)
except Exception:
- logging.exception(
+ _LOGGER.exception(
'Unexpected exception from %s executed in logging pool!',
behavior)
raise
diff --git a/src/python/grpcio/grpc/framework/foundation/stream_util.py b/src/python/grpcio/grpc/framework/foundation/stream_util.py
index 04631d9899..1faaf29bd7 100644
--- a/src/python/grpcio/grpc/framework/foundation/stream_util.py
+++ b/src/python/grpcio/grpc/framework/foundation/stream_util.py
@@ -19,6 +19,7 @@ import threading
from grpc.framework.foundation import stream
_NO_VALUE = object()
+_LOGGER = logging.getLogger(__name__)
class TransformingConsumer(stream.Consumer):
@@ -46,10 +47,10 @@ class IterableConsumer(stream.Consumer):
self._values = []
self._active = True
- def consume(self, stock_reply):
+ def consume(self, value):
with self._condition:
if self._active:
- self._values.append(stock_reply)
+ self._values.append(value)
self._condition.notify()
def terminate(self):
@@ -57,10 +58,10 @@ class IterableConsumer(stream.Consumer):
self._active = False
self._condition.notify()
- def consume_and_terminate(self, stock_reply):
+ def consume_and_terminate(self, value):
with self._condition:
if self._active:
- self._values.append(stock_reply)
+ self._values.append(value)
self._active = False
self._condition.notify()
@@ -103,7 +104,7 @@ class ThreadSwitchingConsumer(stream.Consumer):
else:
sink.consume(value)
except Exception as e: # pylint:disable=broad-except
- logging.exception(e)
+ _LOGGER.exception(e)
with self._lock:
if terminate:
diff --git a/src/python/grpcio_testing/grpc_testing/__init__.py b/src/python/grpcio_testing/grpc_testing/__init__.py
index e87d0ffc96..65fdd1b8ca 100644
--- a/src/python/grpcio_testing/grpc_testing/__init__.py
+++ b/src/python/grpcio_testing/grpc_testing/__init__.py
@@ -14,9 +14,9 @@
"""Objects for use in testing gRPC Python-using application code."""
import abc
+import six
from google.protobuf import descriptor
-import six
import grpc
diff --git a/src/python/grpcio_testing/grpc_testing/_channel/_invocation.py b/src/python/grpcio_testing/grpc_testing/_channel/_invocation.py
index ebce652eeb..191b1c1726 100644
--- a/src/python/grpcio_testing/grpc_testing/_channel/_invocation.py
+++ b/src/python/grpcio_testing/grpc_testing/_channel/_invocation.py
@@ -18,6 +18,7 @@ import threading
import grpc
_NOT_YET_OBSERVED = object()
+_LOGGER = logging.getLogger(__name__)
def _cancel(handler):
@@ -248,7 +249,7 @@ def consume_requests(request_iterator, handler):
break
except Exception: # pylint: disable=broad-except
details = 'Exception iterating requests!'
- logging.exception(details)
+ _LOGGER.exception(details)
handler.cancel(grpc.StatusCode.UNKNOWN, details)
consumption = threading.Thread(target=_consume)
diff --git a/src/python/grpcio_testing/grpc_testing/_server/_handler.py b/src/python/grpcio_testing/grpc_testing/_server/_handler.py
index d4f50f6863..0e3404b0d0 100644
--- a/src/python/grpcio_testing/grpc_testing/_server/_handler.py
+++ b/src/python/grpcio_testing/grpc_testing/_server/_handler.py
@@ -105,10 +105,10 @@ class _Handler(Handler):
self._expiration_future.cancel()
self._condition.notify_all()
- def add_termination_callback(self, termination_callback):
+ def add_termination_callback(self, callback):
with self._condition:
if self._code is None:
- self._termination_callbacks.append(termination_callback)
+ self._termination_callbacks.append(callback)
return True
else:
return False
diff --git a/src/python/grpcio_testing/grpc_testing/_server/_rpc.py b/src/python/grpcio_testing/grpc_testing/_server/_rpc.py
index 2060e8daff..b856da100f 100644
--- a/src/python/grpcio_testing/grpc_testing/_server/_rpc.py
+++ b/src/python/grpcio_testing/grpc_testing/_server/_rpc.py
@@ -18,6 +18,8 @@ import threading
import grpc
from grpc_testing import _common
+_LOGGER = logging.getLogger(__name__)
+
class Rpc(object):
@@ -47,7 +49,7 @@ class Rpc(object):
try:
callback()
except Exception: # pylint: disable=broad-except
- logging.exception('Exception calling server-side callback!')
+ _LOGGER.exception('Exception calling server-side callback!')
callback_calling_thread = threading.Thread(target=call_back)
callback_calling_thread.start()
@@ -86,7 +88,7 @@ class Rpc(object):
def application_exception_abort(self, exception):
with self._condition:
if exception not in self._rpc_errors:
- logging.exception('Exception calling application!')
+ _LOGGER.exception('Exception calling application!')
self._abort(
grpc.StatusCode.UNKNOWN,
'Exception calling application: {}'.format(exception))
diff --git a/src/python/grpcio_testing/grpc_testing/_time.py b/src/python/grpcio_testing/grpc_testing/_time.py
index afbdad3524..75e6db3458 100644
--- a/src/python/grpcio_testing/grpc_testing/_time.py
+++ b/src/python/grpcio_testing/grpc_testing/_time.py
@@ -21,13 +21,15 @@ import time as _time
import grpc
import grpc_testing
+_LOGGER = logging.getLogger(__name__)
+
def _call(behaviors):
for behavior in behaviors:
try:
behavior()
except Exception: # pylint: disable=broad-except
- logging.exception('Exception calling behavior "%r"!', behavior)
+ _LOGGER.exception('Exception calling behavior "%r"!', behavior)
def _call_in_thread(behaviors):
diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py
index 42e01c18d3..a23c980017 100644
--- a/src/python/grpcio_tests/commands.py
+++ b/src/python/grpcio_tests/commands.py
@@ -119,6 +119,8 @@ class TestGevent(setuptools.Command):
# I have no idea why this doesn't work in gevent, but it shouldn't even be
# using the c-core
'testing._client_test.ClientTest.test_infinite_request_stream_real_time',
+ # TODO(https://github.com/grpc/grpc/issues/15743) enable this test
+ 'unit._session_cache_test.SSLSessionCacheTest.testSSLSessionCacheLRU',
# TODO(https://github.com/grpc/grpc/issues/14789) enable this test
'unit._server_ssl_cert_config_test',
# TODO(https://github.com/grpc/grpc/issues/14901) enable this test
diff --git a/src/python/grpcio_tests/tests/_loader.py b/src/python/grpcio_tests/tests/_loader.py
index be0af64646..80c107aa8e 100644
--- a/src/python/grpcio_tests/tests/_loader.py
+++ b/src/python/grpcio_tests/tests/_loader.py
@@ -48,12 +48,13 @@ class Loader(object):
# measure unnecessarily suffers)
coverage_context = coverage.Coverage(data_suffix=True)
coverage_context.start()
- modules = [importlib.import_module(name) for name in names]
- for module in modules:
- self.visit_module(module)
- for module in modules:
+ imported_modules = tuple(
+ importlib.import_module(name) for name in names)
+ for imported_module in imported_modules:
+ self.visit_module(imported_module)
+ for imported_module in imported_modules:
try:
- package_paths = module.__path__
+ package_paths = imported_module.__path__
except AttributeError:
continue
self.walk_packages(package_paths)
diff --git a/src/python/grpcio_tests/tests/_result.py b/src/python/grpcio_tests/tests/_result.py
index b105f18e78..e5378b7ea3 100644
--- a/src/python/grpcio_tests/tests/_result.py
+++ b/src/python/grpcio_tests/tests/_result.py
@@ -144,10 +144,6 @@ class AugmentedResult(unittest.TestResult):
super(AugmentedResult, self).startTestRun()
self.cases = dict()
- def stopTestRun(self):
- """See unittest.TestResult.stopTestRun."""
- super(AugmentedResult, self).stopTestRun()
-
def startTest(self, test):
"""See unittest.TestResult.startTest."""
super(AugmentedResult, self).startTest(test)
@@ -155,19 +151,19 @@ class AugmentedResult(unittest.TestResult):
self.cases[case_id] = CaseResult(
id=case_id, name=test.id(), kind=CaseResult.Kind.RUNNING)
- def addError(self, test, error):
+ def addError(self, test, err):
"""See unittest.TestResult.addError."""
- super(AugmentedResult, self).addError(test, error)
+ super(AugmentedResult, self).addError(test, err)
case_id = self.id_map(test)
self.cases[case_id] = self.cases[case_id].updated(
- kind=CaseResult.Kind.ERROR, traceback=error)
+ kind=CaseResult.Kind.ERROR, traceback=err)
- def addFailure(self, test, error):
+ def addFailure(self, test, err):
"""See unittest.TestResult.addFailure."""
- super(AugmentedResult, self).addFailure(test, error)
+ super(AugmentedResult, self).addFailure(test, err)
case_id = self.id_map(test)
self.cases[case_id] = self.cases[case_id].updated(
- kind=CaseResult.Kind.FAILURE, traceback=error)
+ kind=CaseResult.Kind.FAILURE, traceback=err)
def addSuccess(self, test):
"""See unittest.TestResult.addSuccess."""
@@ -183,12 +179,12 @@ class AugmentedResult(unittest.TestResult):
self.cases[case_id] = self.cases[case_id].updated(
kind=CaseResult.Kind.SKIP, skip_reason=reason)
- def addExpectedFailure(self, test, error):
+ def addExpectedFailure(self, test, err):
"""See unittest.TestResult.addExpectedFailure."""
- super(AugmentedResult, self).addExpectedFailure(test, error)
+ super(AugmentedResult, self).addExpectedFailure(test, err)
case_id = self.id_map(test)
self.cases[case_id] = self.cases[case_id].updated(
- kind=CaseResult.Kind.EXPECTED_FAILURE, traceback=error)
+ kind=CaseResult.Kind.EXPECTED_FAILURE, traceback=err)
def addUnexpectedSuccess(self, test):
"""See unittest.TestResult.addUnexpectedSuccess."""
@@ -249,13 +245,6 @@ class CoverageResult(AugmentedResult):
self.coverage_context.save()
self.coverage_context = None
- def stopTestRun(self):
- """See unittest.TestResult.stopTestRun."""
- super(CoverageResult, self).stopTestRun()
- # TODO(atash): Dig deeper into why the following line fails to properly
- # combine coverage data from the Cython plugin.
- #coverage.Coverage().combine()
-
class _Colors(object):
"""Namespaced constants for terminal color magic numbers."""
@@ -295,16 +284,16 @@ class TerminalResult(CoverageResult):
self.out.write(summary(self))
self.out.flush()
- def addError(self, test, error):
+ def addError(self, test, err):
"""See unittest.TestResult.addError."""
- super(TerminalResult, self).addError(test, error)
+ super(TerminalResult, self).addError(test, err)
self.out.write(
_Colors.FAIL + 'ERROR {}\n'.format(test.id()) + _Colors.END)
self.out.flush()
- def addFailure(self, test, error):
+ def addFailure(self, test, err):
"""See unittest.TestResult.addFailure."""
- super(TerminalResult, self).addFailure(test, error)
+ super(TerminalResult, self).addFailure(test, err)
self.out.write(
_Colors.FAIL + 'FAILURE {}\n'.format(test.id()) + _Colors.END)
self.out.flush()
@@ -323,9 +312,9 @@ class TerminalResult(CoverageResult):
_Colors.INFO + 'SKIP {}\n'.format(test.id()) + _Colors.END)
self.out.flush()
- def addExpectedFailure(self, test, error):
+ def addExpectedFailure(self, test, err):
"""See unittest.TestResult.addExpectedFailure."""
- super(TerminalResult, self).addExpectedFailure(test, error)
+ super(TerminalResult, self).addExpectedFailure(test, err)
self.out.write(
_Colors.INFO + 'FAILURE_OK {}\n'.format(test.id()) + _Colors.END)
self.out.flush()
diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py
index b728ffd704..cda15a68a3 100644
--- a/src/python/grpcio_tests/tests/interop/methods.py
+++ b/src/python/grpcio_tests/tests/interop/methods.py
@@ -144,8 +144,8 @@ def _large_unary_common_behavior(stub, fill_username, fill_oauth_scope,
def _empty_unary(stub):
response = stub.EmptyCall(empty_pb2.Empty())
if not isinstance(response, empty_pb2.Empty):
- raise TypeError('response is of type "%s", not empty_pb2.Empty!',
- type(response))
+ raise TypeError(
+ 'response is of type "%s", not empty_pb2.Empty!' % type(response))
def _large_unary(stub):
diff --git a/src/python/grpcio_tests/tests/interop/server.py b/src/python/grpcio_tests/tests/interop/server.py
index 0810de2394..fd28d498a1 100644
--- a/src/python/grpcio_tests/tests/interop/server.py
+++ b/src/python/grpcio_tests/tests/interop/server.py
@@ -26,6 +26,7 @@ from tests.interop import resources
from tests.unit import test_common
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
+_LOGGER = logging.getLogger(__name__)
def serve():
@@ -52,14 +53,14 @@ def serve():
server.add_insecure_port('[::]:{}'.format(args.port))
server.start()
- logging.info('Server serving.')
+ _LOGGER.info('Server serving.')
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except BaseException as e:
- logging.info('Caught exception "%s"; stopping server...', e)
+ _LOGGER.info('Caught exception "%s"; stopping server...', e)
server.stop(None)
- logging.info('Server stopped; exiting.')
+ _LOGGER.info('Server stopped; exiting.')
if __name__ == '__main__':
diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json
index 0d94426413..ebc41c63f0 100644
--- a/src/python/grpcio_tests/tests/tests.json
+++ b/src/python/grpcio_tests/tests/tests.json
@@ -53,6 +53,8 @@
"unit._server_ssl_cert_config_test.ServerSSLCertReloadTestCertConfigReuse",
"unit._server_ssl_cert_config_test.ServerSSLCertReloadTestWithClientAuth",
"unit._server_ssl_cert_config_test.ServerSSLCertReloadTestWithoutClientAuth",
+ "unit._server_test.ServerTest",
+ "unit._session_cache_test.SSLSessionCacheTest",
"unit.beta._beta_features_test.BetaFeaturesTest",
"unit.beta._beta_features_test.ContextManagementAndLifecycleTest",
"unit.beta._connectivity_channel_test.ConnectivityStatesTest",
diff --git a/src/python/grpcio_tests/tests/unit/_auth_context_test.py b/src/python/grpcio_tests/tests/unit/_auth_context_test.py
index 8c1a30e032..d174051070 100644
--- a/src/python/grpcio_tests/tests/unit/_auth_context_test.py
+++ b/src/python/grpcio_tests/tests/unit/_auth_context_test.py
@@ -18,6 +18,7 @@ import unittest
import grpc
from grpc import _channel
+from grpc.experimental import session_cache
import six
from tests.unit import test_common
@@ -140,6 +141,50 @@ class AuthContextTest(unittest.TestCase):
self.assertSequenceEqual([b'*.test.google.com'],
auth_ctx['x509_common_name'])
+ def _do_one_shot_client_rpc(self, channel_creds, channel_options, port,
+ expect_ssl_session_reused):
+ channel = grpc.secure_channel(
+ 'localhost:{}'.format(port), channel_creds, options=channel_options)
+ response = channel.unary_unary(_UNARY_UNARY)(_REQUEST)
+ auth_data = pickle.loads(response)
+ self.assertEqual(expect_ssl_session_reused,
+ auth_data[_AUTH_CTX]['ssl_session_reused'])
+ channel.close()
+
+ def testSessionResumption(self):
+ # Set up a secure server
+ handler = grpc.method_handlers_generic_handler('test', {
+ 'UnaryUnary':
+ grpc.unary_unary_rpc_method_handler(handle_unary_unary)
+ })
+ server = test_common.test_server()
+ server.add_generic_rpc_handlers((handler,))
+ server_cred = grpc.ssl_server_credentials(_SERVER_CERTS)
+ port = server.add_secure_port('[::]:0', server_cred)
+ server.start()
+
+ # Create a cache for TLS session tickets
+ cache = session_cache.ssl_session_cache_lru(1)
+ channel_creds = grpc.ssl_channel_credentials(
+ root_certificates=_TEST_ROOT_CERTIFICATES)
+ channel_options = _PROPERTY_OPTIONS + (
+ ('grpc.ssl_session_cache', cache),)
+
+ # Initial connection has no session to resume
+ self._do_one_shot_client_rpc(
+ channel_creds,
+ channel_options,
+ port,
+ expect_ssl_session_reused=[b'false'])
+
+ # Subsequent connections resume sessions
+ self._do_one_shot_client_rpc(
+ channel_creds,
+ channel_options,
+ port,
+ expect_ssl_session_reused=[b'true'])
+ server.stop(None)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_junkdrawer/__init__.py b/src/python/grpcio_tests/tests/unit/_junkdrawer/__init__.py
deleted file mode 100644
index 5fb4f3c3cf..0000000000
--- a/src/python/grpcio_tests/tests/unit/_junkdrawer/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2015 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.
diff --git a/src/python/grpcio_tests/tests/unit/_junkdrawer/stock_pb2.py b/src/python/grpcio_tests/tests/unit/_junkdrawer/stock_pb2.py
deleted file mode 100644
index 2bf1e1cc0d..0000000000
--- a/src/python/grpcio_tests/tests/unit/_junkdrawer/stock_pb2.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# Copyright 2015 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.
-
-# TODO(nathaniel): Remove this from source control after having made
-# generation from the stock.proto source part of GRPC's build-and-test
-# process.
-
-# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: stock.proto
-
-import sys
-_b = sys.version_info[0] < 3 and (lambda x: x) or (lambda x: x.encode('latin1'))
-from google.protobuf import descriptor as _descriptor
-from google.protobuf import message as _message
-from google.protobuf import reflection as _reflection
-from google.protobuf import symbol_database as _symbol_database
-from google.protobuf import descriptor_pb2
-# @@protoc_insertion_point(imports)
-
-_sym_db = _symbol_database.Default()
-
-DESCRIPTOR = _descriptor.FileDescriptor(
- name='stock.proto',
- package='stock',
- serialized_pb=_b(
- '\n\x0bstock.proto\x12\x05stock\">\n\x0cStockRequest\x12\x0e\n\x06symbol\x18\x01 \x01(\t\x12\x1e\n\x13num_trades_to_watch\x18\x02 \x01(\x05:\x01\x30\"+\n\nStockReply\x12\r\n\x05price\x18\x01 \x01(\x02\x12\x0e\n\x06symbol\x18\x02 \x01(\t2\x96\x02\n\x05Stock\x12=\n\x11GetLastTradePrice\x12\x13.stock.StockRequest\x1a\x11.stock.StockReply\"\x00\x12I\n\x19GetLastTradePriceMultiple\x12\x13.stock.StockRequest\x1a\x11.stock.StockReply\"\x00(\x01\x30\x01\x12?\n\x11WatchFutureTrades\x12\x13.stock.StockRequest\x1a\x11.stock.StockReply\"\x00\x30\x01\x12\x42\n\x14GetHighestTradePrice\x12\x13.stock.StockRequest\x1a\x11.stock.StockReply\"\x00(\x01'
- ))
-_sym_db.RegisterFileDescriptor(DESCRIPTOR)
-
-_STOCKREQUEST = _descriptor.Descriptor(
- name='StockRequest',
- full_name='stock.StockRequest',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='symbol',
- full_name='stock.StockRequest.symbol',
- index=0,
- number=1,
- type=9,
- cpp_type=9,
- label=1,
- has_default_value=False,
- default_value=_b("").decode('utf-8'),
- message_type=None,
- enum_type=None,
- containing_type=None,
- is_extension=False,
- extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='num_trades_to_watch',
- full_name='stock.StockRequest.num_trades_to_watch',
- index=1,
- number=2,
- type=5,
- cpp_type=1,
- label=1,
- has_default_value=True,
- default_value=0,
- message_type=None,
- enum_type=None,
- containing_type=None,
- is_extension=False,
- extension_scope=None,
- options=None),
- ],
- extensions=[],
- nested_types=[],
- enum_types=[],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[],
- serialized_start=22,
- serialized_end=84,)
-
-_STOCKREPLY = _descriptor.Descriptor(
- name='StockReply',
- full_name='stock.StockReply',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='price',
- full_name='stock.StockReply.price',
- index=0,
- number=1,
- type=2,
- cpp_type=6,
- label=1,
- has_default_value=False,
- default_value=0,
- message_type=None,
- enum_type=None,
- containing_type=None,
- is_extension=False,
- extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='symbol',
- full_name='stock.StockReply.symbol',
- index=1,
- number=2,
- type=9,
- cpp_type=9,
- label=1,
- has_default_value=False,
- default_value=_b("").decode('utf-8'),
- message_type=None,
- enum_type=None,
- containing_type=None,
- is_extension=False,
- extension_scope=None,
- options=None),
- ],
- extensions=[],
- nested_types=[],
- enum_types=[],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[],
- serialized_start=86,
- serialized_end=129,)
-
-DESCRIPTOR.message_types_by_name['StockRequest'] = _STOCKREQUEST
-DESCRIPTOR.message_types_by_name['StockReply'] = _STOCKREPLY
-
-StockRequest = _reflection.GeneratedProtocolMessageType(
- 'StockRequest',
- (_message.Message,),
- dict(
- DESCRIPTOR=_STOCKREQUEST,
- __module__='stock_pb2'
- # @@protoc_insertion_point(class_scope:stock.StockRequest)
- ))
-_sym_db.RegisterMessage(StockRequest)
-
-StockReply = _reflection.GeneratedProtocolMessageType(
- 'StockReply',
- (_message.Message,),
- dict(
- DESCRIPTOR=_STOCKREPLY,
- __module__='stock_pb2'
- # @@protoc_insertion_point(class_scope:stock.StockReply)
- ))
-_sym_db.RegisterMessage(StockReply)
-
-# @@protoc_insertion_point(module_scope)
diff --git a/src/python/grpcio_tests/tests/unit/_server_test.py b/src/python/grpcio_tests/tests/unit/_server_test.py
new file mode 100644
index 0000000000..acf4a17921
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/_server_test.py
@@ -0,0 +1,52 @@
+# Copyright 2018 The 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.
+
+from concurrent import futures
+import unittest
+
+import grpc
+
+
+class _ActualGenericRpcHandler(grpc.GenericRpcHandler):
+
+ def service(self, handler_call_details):
+ return None
+
+
+class ServerTest(unittest.TestCase):
+
+ def test_not_a_generic_rpc_handler_at_construction(self):
+ with self.assertRaises(AttributeError) as exception_context:
+ grpc.server(
+ futures.ThreadPoolExecutor(max_workers=5),
+ handlers=[
+ _ActualGenericRpcHandler(),
+ object(),
+ ])
+ self.assertIn('grpc.GenericRpcHandler',
+ str(exception_context.exception))
+
+ def test_not_a_generic_rpc_handler_after_construction(self):
+ server = grpc.server(futures.ThreadPoolExecutor(max_workers=5))
+ with self.assertRaises(AttributeError) as exception_context:
+ server.add_generic_rpc_handlers([
+ _ActualGenericRpcHandler(),
+ object(),
+ ])
+ self.assertIn('grpc.GenericRpcHandler',
+ str(exception_context.exception))
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_session_cache_test.py b/src/python/grpcio_tests/tests/unit/_session_cache_test.py
new file mode 100644
index 0000000000..b4e4670fa7
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/_session_cache_test.py
@@ -0,0 +1,145 @@
+# Copyright 2018 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.
+"""Tests experimental TLS Session Resumption API"""
+
+import pickle
+import unittest
+
+import grpc
+from grpc import _channel
+from grpc.experimental import session_cache
+
+from tests.unit import test_common
+from tests.unit import resources
+
+_REQUEST = b'\x00\x00\x00'
+_RESPONSE = b'\x00\x00\x00'
+
+_UNARY_UNARY = '/test/UnaryUnary'
+
+_SERVER_HOST_OVERRIDE = 'foo.test.google.fr'
+_ID = 'id'
+_ID_KEY = 'id_key'
+_AUTH_CTX = 'auth_ctx'
+
+_PRIVATE_KEY = resources.private_key()
+_CERTIFICATE_CHAIN = resources.certificate_chain()
+_TEST_ROOT_CERTIFICATES = resources.test_root_certificates()
+_SERVER_CERTS = ((_PRIVATE_KEY, _CERTIFICATE_CHAIN),)
+_PROPERTY_OPTIONS = ((
+ 'grpc.ssl_target_name_override',
+ _SERVER_HOST_OVERRIDE,
+),)
+
+
+def handle_unary_unary(request, servicer_context):
+ return pickle.dumps({
+ _ID: servicer_context.peer_identities(),
+ _ID_KEY: servicer_context.peer_identity_key(),
+ _AUTH_CTX: servicer_context.auth_context()
+ })
+
+
+def start_secure_server():
+ handler = grpc.method_handlers_generic_handler('test', {
+ 'UnaryUnary':
+ grpc.unary_unary_rpc_method_handler(handle_unary_unary)
+ })
+ server = test_common.test_server()
+ server.add_generic_rpc_handlers((handler,))
+ server_cred = grpc.ssl_server_credentials(_SERVER_CERTS)
+ port = server.add_secure_port('[::]:0', server_cred)
+ server.start()
+
+ return server, port
+
+
+class SSLSessionCacheTest(unittest.TestCase):
+
+ def _do_one_shot_client_rpc(self, channel_creds, channel_options, port,
+ expect_ssl_session_reused):
+ channel = grpc.secure_channel(
+ 'localhost:{}'.format(port), channel_creds, options=channel_options)
+ response = channel.unary_unary(_UNARY_UNARY)(_REQUEST)
+ auth_data = pickle.loads(response)
+ self.assertEqual(expect_ssl_session_reused,
+ auth_data[_AUTH_CTX]['ssl_session_reused'])
+ channel.close()
+
+ def testSSLSessionCacheLRU(self):
+ server_1, port_1 = start_secure_server()
+
+ cache = session_cache.ssl_session_cache_lru(1)
+ channel_creds = grpc.ssl_channel_credentials(
+ root_certificates=_TEST_ROOT_CERTIFICATES)
+ channel_options = _PROPERTY_OPTIONS + (
+ ('grpc.ssl_session_cache', cache),)
+
+ # Initial connection has no session to resume
+ self._do_one_shot_client_rpc(
+ channel_creds,
+ channel_options,
+ port_1,
+ expect_ssl_session_reused=[b'false'])
+
+ # Connection to server_1 resumes from initial session
+ self._do_one_shot_client_rpc(
+ channel_creds,
+ channel_options,
+ port_1,
+ expect_ssl_session_reused=[b'true'])
+
+ # Connection to a different server with the same name overwrites the cache entry
+ server_2, port_2 = start_secure_server()
+ self._do_one_shot_client_rpc(
+ channel_creds,
+ channel_options,
+ port_2,
+ expect_ssl_session_reused=[b'false'])
+ self._do_one_shot_client_rpc(
+ channel_creds,
+ channel_options,
+ port_2,
+ expect_ssl_session_reused=[b'true'])
+ server_2.stop(None)
+
+ # Connection to server_1 now falls back to full TLS handshake
+ self._do_one_shot_client_rpc(
+ channel_creds,
+ channel_options,
+ port_1,
+ expect_ssl_session_reused=[b'false'])
+
+ # Re-creating server_1 causes old sessions to become invalid
+ server_1.stop(None)
+ server_1, port_1 = start_secure_server()
+
+ # Old sessions should no longer be valid
+ self._do_one_shot_client_rpc(
+ channel_creds,
+ channel_options,
+ port_1,
+ expect_ssl_session_reused=[b'false'])
+
+ # Resumption should work for subsequent connections
+ self._do_one_shot_client_rpc(
+ channel_creds,
+ channel_options,
+ port_1,
+ expect_ssl_session_reused=[b'true'])
+ server_1.stop(None)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/src/ruby/bin/apis/google/protobuf/empty.rb b/src/ruby/bin/apis/google/protobuf/empty.rb
deleted file mode 100644
index 4743bded3d..0000000000
--- a/src/ruby/bin/apis/google/protobuf/empty.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2015 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.
-
-# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: google/protobuf/empty.proto
-
-require 'google/protobuf'
-
-Google::Protobuf::DescriptorPool.generated_pool.build do
- add_message "google.protobuf.Empty" do
- end
-end
-
-module Google
- module Protobuf
- Empty = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Empty").msgclass
- end
-end
diff --git a/src/ruby/bin/apis/pubsub_demo.rb b/src/ruby/bin/apis/pubsub_demo.rb
deleted file mode 100755
index c565771d45..0000000000
--- a/src/ruby/bin/apis/pubsub_demo.rb
+++ /dev/null
@@ -1,241 +0,0 @@
-#!/usr/bin/env ruby
-
-# Copyright 2015 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.
-
-# pubsub_demo demos accesses the Google PubSub API via its gRPC interface
-#
-# $ GOOGLE_APPLICATION_CREDENTIALS=<path_to_service_account_key_file> \
-# path/to/pubsub_demo.rb \
-# [--action=<chosen_demo_action> ]
-#
-# There are options related to the chosen action, see #parse_args below.
-# - the possible actions are given by the method names of NamedAction class
-# - the default action is list_some_topics
-
-this_dir = File.expand_path(File.dirname(__FILE__))
-lib_dir = File.join(File.dirname(File.dirname(this_dir)), 'lib')
-$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
-$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
-
-require 'optparse'
-
-require 'grpc'
-require 'googleauth'
-require 'google/protobuf'
-
-require 'google/protobuf/empty'
-require 'tech/pubsub/proto/pubsub'
-require 'tech/pubsub/proto/pubsub_services'
-
-# creates a SSL Credentials from the production certificates.
-def ssl_creds
- GRPC::Core::ChannelCredentials.new()
-end
-
-# Builds the metadata authentication update proc.
-def auth_proc(opts)
- auth_creds = Google::Auth.get_application_default
- return auth_creds.updater_proc
-end
-
-# Creates a stub for accessing the publisher service.
-def publisher_stub(opts)
- address = "#{opts.host}:#{opts.port}"
- stub_clz = Tech::Pubsub::PublisherService::Stub # shorter
- GRPC.logger.info("... access PublisherService at #{address}")
- call_creds = GRPC::Core::CallCredentials.new(auth_proc(opts))
- combined_creds = ssl_creds.compose(call_creds)
- stub_clz.new(address, creds: combined_creds,
- GRPC::Core::Channel::SSL_TARGET => opts.host)
-end
-
-# Creates a stub for accessing the subscriber service.
-def subscriber_stub(opts)
- address = "#{opts.host}:#{opts.port}"
- stub_clz = Tech::Pubsub::SubscriberService::Stub # shorter
- GRPC.logger.info("... access SubscriberService at #{address}")
- call_creds = GRPC::Core::CallCredentials.new(auth_proc(opts))
- combined_creds = ssl_creds.compose(call_creds)
- stub_clz.new(address, creds: combined_creds,
- GRPC::Core::Channel::SSL_TARGET => opts.host)
-end
-
-# defines methods corresponding to each interop test case.
-class NamedActions
- include Tech::Pubsub
-
- # Initializes NamedActions
- #
- # @param pub [Stub] a stub for accessing the publisher service
- # @param sub [Stub] a stub for accessing the publisher service
- # @param args [Args] provides access to the command line
- def initialize(pub, sub, args)
- @pub = pub
- @sub = sub
- @args = args
- end
-
- # Removes the test topic if it exists
- def remove_topic
- name = test_topic_name
- p "... removing Topic #{name}"
- @pub.delete_topic(DeleteTopicRequest.new(topic: name))
- p "removed Topic: #{name} OK"
- rescue GRPC::BadStatus => e
- p "Could not delete a topics: rpc failed with '#{e}'"
- end
-
- # Creates a test topic
- def create_topic
- name = test_topic_name
- p "... creating Topic #{name}"
- resp = @pub.create_topic(Topic.new(name: name))
- p "created Topic: #{resp.name} OK"
- rescue GRPC::BadStatus => e
- p "Could not create a topics: rpc failed with '#{e}'"
- end
-
- # Lists topics in the project
- def list_some_topics
- p 'Listing topics'
- p '-------------_'
- list_project_topics.topic.each { |t| p t.name }
- rescue GRPC::BadStatus => e
- p "Could not list topics: rpc failed with '#{e}'"
- end
-
- # Checks if a topics exists in a project
- def check_exists
- name = test_topic_name
- p "... checking for topic #{name}"
- exists = topic_exists?(name)
- p "#{name} is a topic" if exists
- p "#{name} is not a topic" unless exists
- rescue GRPC::BadStatus => e
- p "Could not check for a topics: rpc failed with '#{e}'"
- end
-
- # Publishes some messages
- def random_pub_sub
- topic_name, sub_name = test_topic_name, test_sub_name
- create_topic_if_needed(topic_name)
- @sub.create_subscription(Subscription.new(name: sub_name,
- topic: topic_name))
- msg_count = rand(10..30)
- msg_count.times do |x|
- msg = PubsubMessage.new(data: "message #{x}")
- @pub.publish(PublishRequest.new(topic: topic_name, message: msg))
- end
- p "Sent #{msg_count} messages to #{topic_name}, checking for them now."
- batch = @sub.pull_batch(PullBatchRequest.new(subscription: sub_name,
- max_events: msg_count))
- ack_ids = batch.pull_responses.map { |x| x.ack_id }
- p "Got #{ack_ids.size} messages; acknowledging them.."
- @sub.acknowledge(AcknowledgeRequest.new(subscription: sub_name,
- ack_id: ack_ids))
- p "Test messages were acknowledged OK, deleting the subscription"
- del_req = DeleteSubscriptionRequest.new(subscription: sub_name)
- @sub.delete_subscription(del_req)
- rescue GRPC::BadStatus => e
- p "Could not do random pub sub: rpc failed with '#{e}'"
- end
-
- private
-
- # test_topic_name is the topic name to use in this test.
- def test_topic_name
- unless @args.topic_name.nil?
- return "/topics/#{@args.project_id}/#{@args.topic_name}"
- end
- now_text = Time.now.utc.strftime('%Y%m%d%H%M%S%L')
- "/topics/#{@args.project_id}/#{ENV['USER']}-#{now_text}"
- end
-
- # test_sub_name is the subscription name to use in this test.
- def test_sub_name
- unless @args.sub_name.nil?
- return "/subscriptions/#{@args.project_id}/#{@args.sub_name}"
- end
- now_text = Time.now.utc.strftime('%Y%m%d%H%M%S%L')
- "/subscriptions/#{@args.project_id}/#{ENV['USER']}-#{now_text}"
- end
-
- # determines if the topic name exists
- def topic_exists?(name)
- topics = list_project_topics.topic.map { |t| t.name }
- topics.include?(name)
- end
-
- def create_topic_if_needed(name)
- return if topic_exists?(name)
- @pub.create_topic(Topic.new(name: name))
- end
-
- def list_project_topics
- q = "cloud.googleapis.com/project in (/projects/#{@args.project_id})"
- @pub.list_topics(ListTopicsRequest.new(query: q))
- end
-end
-
-# Args is used to hold the command line info.
-Args = Struct.new(:host, :port, :action, :project_id, :topic_name,
- :sub_name)
-
-# validates the command line options, returning them as an Arg.
-def parse_args
- args = Args.new('pubsub-staging.googleapis.com',
- 443, 'list_some_topics', 'stoked-keyword-656')
- OptionParser.new do |opts|
- opts.on('--server_host SERVER_HOST', 'server hostname') do |v|
- args.host = v
- end
- opts.on('--server_port SERVER_PORT', 'server port') do |v|
- args.port = v
- end
-
- # instance_methods(false) gives only the methods defined in that class.
- scenes = NamedActions.instance_methods(false).map { |t| t.to_s }
- scene_list = scenes.join(',')
- opts.on("--action CODE", scenes, {}, 'pick a demo action',
- " (#{scene_list})") do |v|
- args.action = v
- end
-
- # Set the remaining values.
- %w(project_id topic_name sub_name).each do |o|
- opts.on("--#{o} VALUE", "#{o}") do |v|
- args[o] = v
- end
- end
- end.parse!
- _check_args(args)
-end
-
-def _check_args(args)
- %w(host port action).each do |a|
- if args[a].nil?
- raise OptionParser::MissingArgument.new("please specify --#{a}")
- end
- end
- args
-end
-
-def main
- args = parse_args
- pub, sub = publisher_stub(args), subscriber_stub(args)
- NamedActions.new(pub, sub, args).method(args.action).call
-end
-
-main
diff --git a/src/ruby/bin/apis/tech/pubsub/proto/pubsub.rb b/src/ruby/bin/apis/tech/pubsub/proto/pubsub.rb
deleted file mode 100644
index 73a0d5d9e4..0000000000
--- a/src/ruby/bin/apis/tech/pubsub/proto/pubsub.rb
+++ /dev/null
@@ -1,159 +0,0 @@
-# Copyright 2015 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.
-
-# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: tech/pubsub/proto/pubsub.proto
-
-require 'google/protobuf'
-
-require 'google/protobuf/empty'
-Google::Protobuf::DescriptorPool.generated_pool.build do
- add_message "tech.pubsub.Topic" do
- optional :name, :string, 1
- end
- add_message "tech.pubsub.PubsubMessage" do
- optional :data, :string, 1
- optional :message_id, :string, 3
- end
- add_message "tech.pubsub.GetTopicRequest" do
- optional :topic, :string, 1
- end
- add_message "tech.pubsub.PublishRequest" do
- optional :topic, :string, 1
- optional :message, :message, 2, "tech.pubsub.PubsubMessage"
- end
- add_message "tech.pubsub.PublishBatchRequest" do
- optional :topic, :string, 1
- repeated :messages, :message, 2, "tech.pubsub.PubsubMessage"
- end
- add_message "tech.pubsub.PublishBatchResponse" do
- repeated :message_ids, :string, 1
- end
- add_message "tech.pubsub.ListTopicsRequest" do
- optional :query, :string, 1
- optional :max_results, :int32, 2
- optional :page_token, :string, 3
- end
- add_message "tech.pubsub.ListTopicsResponse" do
- repeated :topic, :message, 1, "tech.pubsub.Topic"
- optional :next_page_token, :string, 2
- end
- add_message "tech.pubsub.DeleteTopicRequest" do
- optional :topic, :string, 1
- end
- add_message "tech.pubsub.Subscription" do
- optional :name, :string, 1
- optional :topic, :string, 2
- optional :query, :string, 3
- optional :truncation_policy, :message, 4, "tech.pubsub.Subscription.TruncationPolicy"
- optional :push_config, :message, 5, "tech.pubsub.PushConfig"
- optional :ack_deadline_seconds, :int32, 6
- optional :garbage_collect_seconds, :int64, 7
- end
- add_message "tech.pubsub.Subscription.TruncationPolicy" do
- optional :max_bytes, :int64, 1
- optional :max_age_seconds, :int64, 2
- end
- add_message "tech.pubsub.PushConfig" do
- optional :push_endpoint, :string, 1
- end
- add_message "tech.pubsub.PubsubEvent" do
- optional :subscription, :string, 1
- optional :message, :message, 2, "tech.pubsub.PubsubMessage"
- optional :truncated, :bool, 3
- optional :deleted, :bool, 4
- end
- add_message "tech.pubsub.GetSubscriptionRequest" do
- optional :subscription, :string, 1
- end
- add_message "tech.pubsub.ListSubscriptionsRequest" do
- optional :query, :string, 1
- optional :max_results, :int32, 3
- optional :page_token, :string, 4
- end
- add_message "tech.pubsub.ListSubscriptionsResponse" do
- repeated :subscription, :message, 1, "tech.pubsub.Subscription"
- optional :next_page_token, :string, 2
- end
- add_message "tech.pubsub.TruncateSubscriptionRequest" do
- optional :subscription, :string, 1
- end
- add_message "tech.pubsub.DeleteSubscriptionRequest" do
- optional :subscription, :string, 1
- end
- add_message "tech.pubsub.ModifyPushConfigRequest" do
- optional :subscription, :string, 1
- optional :push_config, :message, 2, "tech.pubsub.PushConfig"
- end
- add_message "tech.pubsub.PullRequest" do
- optional :subscription, :string, 1
- optional :return_immediately, :bool, 2
- end
- add_message "tech.pubsub.PullResponse" do
- optional :ack_id, :string, 1
- optional :pubsub_event, :message, 2, "tech.pubsub.PubsubEvent"
- end
- add_message "tech.pubsub.PullBatchRequest" do
- optional :subscription, :string, 1
- optional :return_immediately, :bool, 2
- optional :max_events, :int32, 3
- end
- add_message "tech.pubsub.PullBatchResponse" do
- repeated :pull_responses, :message, 2, "tech.pubsub.PullResponse"
- end
- add_message "tech.pubsub.ModifyAckDeadlineRequest" do
- optional :subscription, :string, 1
- optional :ack_id, :string, 2
- optional :ack_deadline_seconds, :int32, 3
- end
- add_message "tech.pubsub.AcknowledgeRequest" do
- optional :subscription, :string, 1
- repeated :ack_id, :string, 2
- end
- add_message "tech.pubsub.NackRequest" do
- optional :subscription, :string, 1
- repeated :ack_id, :string, 2
- end
-end
-
-module Tech
- module Pubsub
- Topic = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.Topic").msgclass
- PubsubMessage = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PubsubMessage").msgclass
- GetTopicRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.GetTopicRequest").msgclass
- PublishRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PublishRequest").msgclass
- PublishBatchRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PublishBatchRequest").msgclass
- PublishBatchResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PublishBatchResponse").msgclass
- ListTopicsRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ListTopicsRequest").msgclass
- ListTopicsResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ListTopicsResponse").msgclass
- DeleteTopicRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.DeleteTopicRequest").msgclass
- Subscription = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.Subscription").msgclass
- Subscription::TruncationPolicy = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.Subscription.TruncationPolicy").msgclass
- PushConfig = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PushConfig").msgclass
- PubsubEvent = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PubsubEvent").msgclass
- GetSubscriptionRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.GetSubscriptionRequest").msgclass
- ListSubscriptionsRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ListSubscriptionsRequest").msgclass
- ListSubscriptionsResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ListSubscriptionsResponse").msgclass
- TruncateSubscriptionRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.TruncateSubscriptionRequest").msgclass
- DeleteSubscriptionRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.DeleteSubscriptionRequest").msgclass
- ModifyPushConfigRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ModifyPushConfigRequest").msgclass
- PullRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PullRequest").msgclass
- PullResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PullResponse").msgclass
- PullBatchRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PullBatchRequest").msgclass
- PullBatchResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PullBatchResponse").msgclass
- ModifyAckDeadlineRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ModifyAckDeadlineRequest").msgclass
- AcknowledgeRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.AcknowledgeRequest").msgclass
- NackRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.NackRequest").msgclass
- end
-end
diff --git a/src/ruby/bin/apis/tech/pubsub/proto/pubsub_services.rb b/src/ruby/bin/apis/tech/pubsub/proto/pubsub_services.rb
deleted file mode 100644
index b34db57b44..0000000000
--- a/src/ruby/bin/apis/tech/pubsub/proto/pubsub_services.rb
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright 2015 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.
-
-# Generated by the protocol buffer compiler. DO NOT EDIT!
-# Source: tech/pubsub/proto/pubsub.proto for package 'tech.pubsub'
-
-require 'grpc'
-require 'google/protobuf/empty'
-require 'tech/pubsub/proto/pubsub'
-
-module Tech
- module Pubsub
- module PublisherService
-
- # TODO: add proto service documentation here
- class Service
-
- include GRPC::GenericService
-
- self.marshal_class_method = :encode
- self.unmarshal_class_method = :decode
- self.service_name = 'tech.pubsub.PublisherService'
-
- rpc :CreateTopic, Topic, Topic
- rpc :Publish, PublishRequest, Google::Protobuf::Empty
- rpc :PublishBatch, PublishBatchRequest, PublishBatchResponse
- rpc :GetTopic, GetTopicRequest, Topic
- rpc :ListTopics, ListTopicsRequest, ListTopicsResponse
- rpc :DeleteTopic, DeleteTopicRequest, Google::Protobuf::Empty
- end
-
- Stub = Service.rpc_stub_class
- end
- module SubscriberService
-
- # TODO: add proto service documentation here
- class Service
-
- include GRPC::GenericService
-
- self.marshal_class_method = :encode
- self.unmarshal_class_method = :decode
- self.service_name = 'tech.pubsub.SubscriberService'
-
- rpc :CreateSubscription, Subscription, Subscription
- rpc :GetSubscription, GetSubscriptionRequest, Subscription
- rpc :ListSubscriptions, ListSubscriptionsRequest, ListSubscriptionsResponse
- rpc :DeleteSubscription, DeleteSubscriptionRequest, Google::Protobuf::Empty
- rpc :TruncateSubscription, TruncateSubscriptionRequest, Google::Protobuf::Empty
- rpc :ModifyPushConfig, ModifyPushConfigRequest, Google::Protobuf::Empty
- rpc :Pull, PullRequest, PullResponse
- rpc :PullBatch, PullBatchRequest, PullBatchResponse
- rpc :ModifyAckDeadline, ModifyAckDeadlineRequest, Google::Protobuf::Empty
- rpc :Acknowledge, AcknowledgeRequest, Google::Protobuf::Empty
- rpc :Nack, NackRequest, Google::Protobuf::Empty
- end
-
- Stub = Service.rpc_stub_class
- end
- module PushEndpointService
-
- # TODO: add proto service documentation here
- class Service
-
- include GRPC::GenericService
-
- self.marshal_class_method = :encode
- self.unmarshal_class_method = :decode
- self.service_name = 'tech.pubsub.PushEndpointService'
-
- rpc :HandlePubsubEvent, PubsubEvent, Google::Protobuf::Empty
- end
-
- Stub = Service.rpc_stub_class
- end
- end
-end