aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--BUILD29
-rw-r--r--CMakeLists.txt16
-rw-r--r--Makefile21
-rw-r--r--binding.gyp3
-rw-r--r--build.yaml6
-rw-r--r--config.m43
-rw-r--r--gRPC-Core.podspec9
-rw-r--r--grpc.def12
-rwxr-xr-xgrpc.gemspec7
-rw-r--r--include/grpc++/support/channel_arguments.h2
-rw-r--r--include/grpc/compression.h8
-rw-r--r--include/grpc/grpc.h10
-rw-r--r--include/grpc/impl/codegen/compression_types.h5
-rw-r--r--include/grpc/impl/codegen/exec_ctx_fwd.h41
-rw-r--r--include/grpc/impl/codegen/grpc_types.h48
-rw-r--r--include/grpc/impl/codegen/slice.h17
-rw-r--r--include/grpc/slice.h31
-rw-r--r--package.xml7
-rw-r--r--src/core/ext/census/grpc_filter.c4
-rw-r--r--src/core/ext/census/grpc_plugin.c3
-rw-r--r--src/core/ext/client_channel/client_channel.c47
-rw-r--r--src/core/ext/client_channel/client_channel_plugin.c11
-rw-r--r--src/core/ext/client_channel/http_connect_handshaker.c15
-rw-r--r--src/core/ext/client_channel/lb_policy_factory.c10
-rw-r--r--src/core/ext/client_channel/lb_policy_factory.h5
-rw-r--r--src/core/ext/client_channel/resolver_factory.c5
-rw-r--r--src/core/ext/client_channel/resolver_factory.h6
-rw-r--r--src/core/ext/client_channel/resolver_registry.c5
-rw-r--r--src/core/ext/client_channel/resolver_registry.h2
-rw-r--r--src/core/ext/client_channel/subchannel.c13
-rw-r--r--src/core/ext/client_channel/subchannel.h2
-rw-r--r--src/core/ext/client_channel/subchannel_index.c2
-rw-r--r--src/core/ext/client_channel/uri_parser.c44
-rw-r--r--src/core/ext/lb_policy/grpclb/grpclb.c83
-rw-r--r--src/core/ext/lb_policy/round_robin/round_robin.c2
-rw-r--r--src/core/ext/load_reporting/load_reporting.c3
-rw-r--r--src/core/ext/load_reporting/load_reporting_filter.c47
-rw-r--r--src/core/ext/resolver/dns/native/dns_resolver.c11
-rw-r--r--src/core/ext/resolver/sockaddr/sockaddr_resolver.c19
-rw-r--r--src/core/ext/transport/chttp2/client/insecure/channel_create.c4
-rw-r--r--src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c2
-rw-r--r--src/core/ext/transport/chttp2/client/secure/secure_channel_create.c16
-rw-r--r--src/core/ext/transport/chttp2/server/insecure/server_chttp2.c2
-rw-r--r--src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c2
-rw-r--r--src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c15
-rw-r--r--src/core/ext/transport/chttp2/transport/bin_decoder.c25
-rw-r--r--src/core/ext/transport/chttp2/transport/bin_decoder.h5
-rw-r--r--src/core/ext/transport/chttp2/transport/bin_encoder.c3
-rw-r--r--src/core/ext/transport/chttp2/transport/bin_encoder.h5
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_plugin.c3
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.c44
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_encoder.c151
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_encoder.h10
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_parser.c79
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_parser.h8
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_table.c70
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_table.h23
-rw-r--r--src/core/ext/transport/chttp2/transport/incoming_metadata.c6
-rw-r--r--src/core/ext/transport/chttp2/transport/incoming_metadata.h4
-rw-r--r--src/core/ext/transport/chttp2/transport/parsing.c70
-rw-r--r--src/core/ext/transport/chttp2/transport/writing.c11
-rw-r--r--src/core/ext/transport/cronet/transport/cronet_transport.c2
-rw-r--r--src/core/lib/channel/channel_args.c10
-rw-r--r--src/core/lib/channel/channel_args.h5
-rw-r--r--src/core/lib/channel/channel_stack.c6
-rw-r--r--src/core/lib/channel/channel_stack.h4
-rw-r--r--src/core/lib/channel/channel_stack_builder.c12
-rw-r--r--src/core/lib/channel/channel_stack_builder.h6
-rw-r--r--src/core/lib/channel/compress_filter.c40
-rw-r--r--src/core/lib/channel/connected_channel.c3
-rw-r--r--src/core/lib/channel/connected_channel.h3
-rw-r--r--src/core/lib/channel/deadline_filter.c3
-rw-r--r--src/core/lib/channel/http_client_filter.c140
-rw-r--r--src/core/lib/channel/http_server_filter.c119
-rw-r--r--src/core/lib/channel/message_size_filter.c18
-rw-r--r--src/core/lib/compression/algorithm_metadata.h8
-rw-r--r--src/core/lib/compression/compression.c41
-rw-r--r--src/core/lib/compression/message_compress.c46
-rw-r--r--src/core/lib/compression/message_compress.h6
-rw-r--r--src/core/lib/http/httpcli.c13
-rw-r--r--src/core/lib/http/httpcli_security_connector.c14
-rw-r--r--src/core/lib/iomgr/closure.h6
-rw-r--r--src/core/lib/iomgr/ev_epoll_linux.c1
-rw-r--r--src/core/lib/iomgr/ev_posix.c2
-rw-r--r--src/core/lib/iomgr/executor.c6
-rw-r--r--src/core/lib/iomgr/executor.h2
-rw-r--r--src/core/lib/iomgr/iomgr.c12
-rw-r--r--src/core/lib/iomgr/iomgr.h6
-rw-r--r--src/core/lib/iomgr/load_file.c2
-rw-r--r--src/core/lib/iomgr/resource_quota.c51
-rw-r--r--src/core/lib/iomgr/resource_quota.h4
-rw-r--r--src/core/lib/iomgr/socket_mutator.c2
-rw-r--r--src/core/lib/iomgr/tcp_client_posix.c10
-rw-r--r--src/core/lib/iomgr/tcp_client_windows.c8
-rw-r--r--src/core/lib/iomgr/tcp_posix.c24
-rw-r--r--src/core/lib/iomgr/tcp_server_posix.c10
-rw-r--r--src/core/lib/iomgr/tcp_server_windows.c8
-rw-r--r--src/core/lib/iomgr/tcp_windows.c6
-rw-r--r--src/core/lib/security/context/security_context.c10
-rw-r--r--src/core/lib/security/credentials/composite/composite_credentials.c31
-rw-r--r--src/core/lib/security/credentials/credentials.c55
-rw-r--r--src/core/lib/security/credentials/credentials.h39
-rw-r--r--src/core/lib/security/credentials/credentials_metadata.c13
-rw-r--r--src/core/lib/security/credentials/fake/fake_credentials.c17
-rw-r--r--src/core/lib/security/credentials/google_default/google_default_credentials.c41
-rw-r--r--src/core/lib/security/credentials/iam/iam_credentials.c5
-rw-r--r--src/core/lib/security/credentials/jwt/jwt_credentials.c28
-rw-r--r--src/core/lib/security/credentials/jwt/jwt_credentials.h3
-rw-r--r--src/core/lib/security/credentials/jwt/jwt_verifier.c104
-rw-r--r--src/core/lib/security/credentials/jwt/jwt_verifier.h8
-rw-r--r--src/core/lib/security/credentials/oauth2/oauth2_credentials.c33
-rw-r--r--src/core/lib/security/credentials/oauth2/oauth2_credentials.h2
-rw-r--r--src/core/lib/security/credentials/plugin/plugin_credentials.c29
-rw-r--r--src/core/lib/security/credentials/ssl/ssl_credentials.c20
-rw-r--r--src/core/lib/security/transport/client_auth_filter.c64
-rw-r--r--src/core/lib/security/transport/handshake.c21
-rw-r--r--src/core/lib/security/transport/secure_endpoint.c25
-rw-r--r--src/core/lib/security/transport/security_connector.c39
-rw-r--r--src/core/lib/security/transport/security_connector.h20
-rw-r--r--src/core/lib/security/transport/server_auth_filter.c45
-rw-r--r--src/core/lib/security/util/b64.c15
-rw-r--r--src/core/lib/security/util/b64.h7
-rw-r--r--src/core/lib/slice/percent_encoding.c8
-rw-r--r--src/core/lib/slice/slice.c121
-rw-r--r--src/core/lib/slice/slice_buffer.c24
-rw-r--r--src/core/lib/slice/slice_hash_table.c (renamed from src/core/lib/transport/mdstr_hash_table.c)70
-rw-r--r--src/core/lib/slice/slice_hash_table.h (renamed from src/core/lib/transport/mdstr_hash_table.h)36
-rw-r--r--src/core/lib/slice/slice_intern.c325
-rw-r--r--src/core/lib/slice/slice_internal.h60
-rw-r--r--src/core/lib/slice/slice_string_helpers.c8
-rw-r--r--src/core/lib/slice/slice_string_helpers.h5
-rw-r--r--src/core/lib/slice/slice_traits.h44
-rw-r--r--src/core/lib/support/string.c26
-rw-r--r--src/core/lib/support/string.h3
-rw-r--r--src/core/lib/surface/byte_buffer.c8
-rw-r--r--src/core/lib/surface/byte_buffer_reader.c16
-rw-r--r--src/core/lib/surface/call.c260
-rw-r--r--src/core/lib/surface/call.h5
-rw-r--r--src/core/lib/surface/call_details.c6
-rw-r--r--src/core/lib/surface/call_log_batch.c19
-rw-r--r--src/core/lib/surface/channel.c135
-rw-r--r--src/core/lib/surface/channel.h9
-rw-r--r--src/core/lib/surface/channel_init.c2
-rw-r--r--src/core/lib/surface/channel_init.h3
-rw-r--r--src/core/lib/surface/init.c20
-rw-r--r--src/core/lib/surface/init_secure.c4
-rw-r--r--src/core/lib/surface/lame_client.c16
-rw-r--r--src/core/lib/surface/server.c120
-rw-r--r--src/core/lib/surface/validate_metadata.c26
-rw-r--r--src/core/lib/transport/byte_stream.c5
-rw-r--r--src/core/lib/transport/metadata.c737
-rw-r--r--src/core/lib/transport/metadata.h130
-rw-r--r--src/core/lib/transport/metadata_batch.c49
-rw-r--r--src/core/lib/transport/metadata_batch.h20
-rw-r--r--src/core/lib/transport/method_config.c321
-rw-r--r--src/core/lib/transport/method_config.h139
-rw-r--r--src/core/lib/transport/pid_controller.h2
-rw-r--r--src/core/lib/transport/service_config.c53
-rw-r--r--src/core/lib/transport/service_config.h13
-rw-r--r--src/core/lib/transport/static_metadata.c848
-rw-r--r--src/core/lib/transport/static_metadata.h452
-rw-r--r--src/core/lib/transport/timeout_encoding.c20
-rw-r--r--src/core/lib/transport/timeout_encoding.h2
-rw-r--r--src/core/lib/transport/transport.c16
-rw-r--r--src/core/lib/transport/transport.h7
-rw-r--r--src/core/lib/transport/transport_op_string.c6
-rw-r--r--src/cpp/common/channel_arguments.cc7
-rw-r--r--src/cpp/common/channel_filter.cc8
-rw-r--r--src/cpp/common/channel_filter.h5
-rw-r--r--src/cpp/util/slice_cc.cc2
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py3
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.c24
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.h46
-rw-r--r--test/core/bad_client/bad_client.c11
-rw-r--r--test/core/bad_client/tests/large_metadata.c18
-rw-r--r--test/core/bad_client/tests/simple_request.c4
-rw-r--r--test/core/bad_ssl/bad_ssl_test.c11
-rw-r--r--test/core/channel/channel_args_test.c27
-rw-r--r--test/core/channel/channel_stack_test.c5
-rw-r--r--test/core/client_channel/lb_policies_test.c37
-rw-r--r--test/core/client_channel/resolvers/dns_resolver_connectivity_test.c6
-rw-r--r--test/core/client_channel/resolvers/dns_resolver_test.c4
-rw-r--r--test/core/client_channel/resolvers/sockaddr_resolver_test.c6
-rw-r--r--test/core/client_channel/set_initial_connect_string_test.c8
-rw-r--r--test/core/compression/algorithm_test.c50
-rw-r--r--test/core/compression/compression_test.c4
-rw-r--r--test/core/compression/message_compress_test.c59
-rw-r--r--test/core/end2end/bad_server_response_test.c25
-rw-r--r--test/core/end2end/connection_refused_test.c20
-rw-r--r--test/core/end2end/cq_verifier.c21
-rw-r--r--test/core/end2end/cq_verifier.h2
-rw-r--r--test/core/end2end/dualstack_socket_test.c20
-rw-r--r--test/core/end2end/end2end_test_utils.c22
-rw-r--r--test/core/end2end/end2end_tests.h6
-rw-r--r--test/core/end2end/fake_resolver.c12
-rw-r--r--test/core/end2end/fixtures/h2_census.c12
-rw-r--r--test/core/end2end/fixtures/h2_compress.c14
-rw-r--r--test/core/end2end/fixtures/h2_load_reporting.c6
-rw-r--r--test/core/end2end/fixtures/h2_oauth2.c10
-rw-r--r--test/core/end2end/fixtures/h2_ssl.c6
-rw-r--r--test/core/end2end/fixtures/h2_ssl_cert.c9
-rw-r--r--test/core/end2end/fixtures/h2_ssl_proxy.c12
-rw-r--r--test/core/end2end/fixtures/http_proxy.c17
-rw-r--r--test/core/end2end/fixtures/proxy.c10
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer.c129
-rw-r--r--test/core/end2end/fuzzers/client_fuzzer.c18
-rw-r--r--test/core/end2end/fuzzers/hpack.dictionary5
-rw-r--r--test/core/end2end/fuzzers/server_fuzzer.c5
-rw-r--r--test/core/end2end/goaway_server_test.c27
-rw-r--r--test/core/end2end/invalid_call_argument_test.c36
-rw-r--r--test/core/end2end/no_server_test.c10
-rw-r--r--test/core/end2end/tests/authority_not_supported.c21
-rw-r--r--test/core/end2end/tests/bad_hostname.c10
-rw-r--r--test/core/end2end/tests/binary_metadata.c77
-rw-r--r--test/core/end2end/tests/call_creds.c29
-rw-r--r--test/core/end2end/tests/cancel_after_accept.c18
-rw-r--r--test/core/end2end/tests/cancel_after_client_done.c11
-rw-r--r--test/core/end2end/tests/cancel_after_invoke.c11
-rw-r--r--test/core/end2end/tests/cancel_before_invoke.c11
-rw-r--r--test/core/end2end/tests/cancel_in_a_vacuum.c5
-rw-r--r--test/core/end2end/tests/cancel_with_status.c13
-rw-r--r--test/core/end2end/tests/compressed_payload.c71
-rw-r--r--test/core/end2end/tests/default_host.c18
-rw-r--r--test/core/end2end/tests/disappearing_server.c18
-rw-r--r--test/core/end2end/tests/empty_batch.c5
-rw-r--r--test/core/end2end/tests/filter_call_init_fails.c16
-rw-r--r--test/core/end2end/tests/filter_causes_close.c21
-rw-r--r--test/core/end2end/tests/filter_latency.c20
-rw-r--r--test/core/end2end/tests/graceful_server_shutdown.c16
-rw-r--r--test/core/end2end/tests/high_initial_seqno.c18
-rw-r--r--test/core/end2end/tests/hpack_size.c36
-rw-r--r--test/core/end2end/tests/idempotent_request.c18
-rw-r--r--test/core/end2end/tests/invoke_large_request.c18
-rw-r--r--test/core/end2end/tests/large_metadata.c32
-rw-r--r--test/core/end2end/tests/load_reporting_hook.c30
-rw-r--r--test/core/end2end/tests/max_concurrent_streams.c45
-rw-r--r--test/core/end2end/tests/max_message_length.c71
-rw-r--r--test/core/end2end/tests/negative_deadline.c11
-rw-r--r--test/core/end2end/tests/network_status_change.c16
-rw-r--r--test/core/end2end/tests/no_logging.c18
-rw-r--r--test/core/end2end/tests/payload.c18
-rw-r--r--test/core/end2end/tests/ping_pong_streaming.c14
-rw-r--r--test/core/end2end/tests/registered_call.c13
-rw-r--r--test/core/end2end/tests/request_with_flags.c11
-rw-r--r--test/core/end2end/tests/request_with_payload.c18
-rw-r--r--test/core/end2end/tests/resource_quota_server.c19
-rw-r--r--test/core/end2end/tests/server_finishes_request.c18
-rw-r--r--test/core/end2end/tests/shutdown_finishes_calls.c13
-rw-r--r--test/core/end2end/tests/simple_cacheable_request.c40
-rw-r--r--test/core/end2end/tests/simple_delayed_request.c18
-rw-r--r--test/core/end2end/tests/simple_metadata.c40
-rw-r--r--test/core/end2end/tests/simple_request.c18
-rw-r--r--test/core/end2end/tests/streaming_error_response.c19
-rw-r--r--test/core/end2end/tests/trailing_metadata.c51
-rw-r--r--test/core/fling/client.c20
-rw-r--r--test/core/fling/server.c8
-rw-r--r--test/core/http/httpcli_test.c4
-rw-r--r--test/core/http/httpscli_test.c4
-rw-r--r--test/core/internal_api_canaries/iomgr.c4
-rw-r--r--test/core/iomgr/endpoint_tests.c8
-rw-r--r--test/core/iomgr/ev_epoll_linux_test.c7
-rw-r--r--test/core/iomgr/fd_conservation_posix_test.c6
-rw-r--r--test/core/iomgr/fd_posix_test.c5
-rw-r--r--test/core/iomgr/resolve_address_test.c8
-rw-r--r--test/core/iomgr/resource_quota_test.c13
-rw-r--r--test/core/iomgr/tcp_posix_test.c20
-rw-r--r--test/core/iomgr/udp_server_test.c2
-rw-r--r--test/core/security/b64_test.c44
-rw-r--r--test/core/security/credentials_test.c134
-rw-r--r--test/core/security/json_token_test.c13
-rw-r--r--test/core/security/jwt_verifier_test.c40
-rw-r--r--test/core/security/secure_endpoint_test.c7
-rw-r--r--test/core/security/ssl_server_fuzzer.c6
-rw-r--r--test/core/security/verify_jwt.c4
-rw-r--r--test/core/slice/slice_test.c62
-rw-r--r--test/core/surface/byte_buffer_reader_test.c10
-rw-r--r--test/core/surface/lame_client_test.c9
-rw-r--r--test/core/surface/public_headers_must_be_c89.c1
-rw-r--r--test/core/surface/secure_channel_create_test.c4
-rw-r--r--test/core/surface/sequential_connectivity_test.c7
-rw-r--r--test/core/transport/chttp2/bin_decoder_test.c103
-rw-r--r--test/core/transport/chttp2/bin_encoder_test.c4
-rw-r--r--test/core/transport/chttp2/hpack_encoder_test.c87
-rw-r--r--test/core/transport/chttp2/hpack_parser_fuzzer_test.c13
-rw-r--r--test/core/transport/chttp2/hpack_parser_test.c39
-rw-r--r--test/core/transport/chttp2/hpack_table_test.c79
-rw-r--r--test/core/transport/metadata_test.c353
-rw-r--r--test/core/transport/timeout_encoding_test.c28
-rw-r--r--test/core/util/passthru_endpoint.c6
-rw-r--r--test/core/util/port_server_client.c6
-rwxr-xr-xtools/codegen/core/gen_static_metadata.py164
-rw-r--r--tools/codegen/core/perfect/.gitignore7
-rwxr-xr-xtools/codegen/core/perfect/build.sh4
-rw-r--r--tools/codegen/core/perfect/lookupa.c240
-rw-r--r--tools/codegen/core/perfect/lookupa.h24
-rw-r--r--tools/codegen/core/perfect/perfect.c1367
-rw-r--r--tools/codegen/core/perfect/perfect.h132
-rw-r--r--tools/codegen/core/perfect/perfhex.c1308
-rw-r--r--tools/codegen/core/perfect/recycle.c87
-rw-r--r--tools/codegen/core/perfect/recycle.h65
-rwxr-xr-xtools/codegen/core/perfect/run.sh6
-rw-r--r--tools/codegen/core/perfect/standard.h57
-rw-r--r--tools/doxygen/Doxyfile.c++1
-rw-r--r--tools/doxygen/Doxyfile.c++.internal1
-rw-r--r--tools/doxygen/Doxyfile.core2
-rw-r--r--tools/doxygen/Doxyfile.core.internal7
-rwxr-xr-xtools/run_tests/sanity/core_banned_functions.py31
-rw-r--r--tools/run_tests/sanity/sanity_tests.yaml2
-rw-r--r--tools/run_tests/sources_and_headers.json9
-rw-r--r--vsprojects/vcxproj/gpr/gpr.vcxproj1
-rw-r--r--vsprojects/vcxproj/gpr/gpr.vcxproj.filters3
-rw-r--r--vsprojects/vcxproj/grpc++/grpc++.vcxproj1
-rw-r--r--vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters3
-rw-r--r--vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj1
-rw-r--r--vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters3
-rw-r--r--vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj1
-rw-r--r--vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters3
-rw-r--r--vsprojects/vcxproj/grpc/grpc.vcxproj9
-rw-r--r--vsprojects/vcxproj/grpc/grpc.vcxproj.filters18
-rw-r--r--vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj9
-rw-r--r--vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters18
-rw-r--r--vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj9
-rw-r--r--vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters18
-rw-r--r--vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj1
-rw-r--r--vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters3
-rw-r--r--vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj1
-rw-r--r--vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters3
-rw-r--r--vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj1
-rw-r--r--vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters3
329 files changed, 9678 insertions, 3630 deletions
diff --git a/BUILD b/BUILD
index f80e5f0664..79b71c6726 100644
--- a/BUILD
+++ b/BUILD
@@ -135,6 +135,7 @@ cc_library(
"include/grpc/impl/codegen/atm_gcc_atomic.h",
"include/grpc/impl/codegen/atm_gcc_sync.h",
"include/grpc/impl/codegen/atm_windows.h",
+ "include/grpc/impl/codegen/exec_ctx_fwd.h",
"include/grpc/impl/codegen/gpr_types.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/slice.h",
@@ -230,6 +231,7 @@ cc_library(
"src/core/lib/json/json_reader.h",
"src/core/lib/json/json_writer.h",
"src/core/lib/slice/percent_encoding.h",
+ "src/core/lib/slice/slice_hash_table.h",
"src/core/lib/slice/slice_string_helpers.h",
"src/core/lib/surface/api_trace.h",
"src/core/lib/surface/call.h",
@@ -244,7 +246,6 @@ cc_library(
"src/core/lib/surface/server.h",
"src/core/lib/transport/byte_stream.h",
"src/core/lib/transport/connectivity_state.h",
- "src/core/lib/transport/mdstr_hash_table.h",
"src/core/lib/transport/metadata.h",
"src/core/lib/transport/metadata_batch.h",
"src/core/lib/transport/pid_controller.h",
@@ -412,6 +413,8 @@ cc_library(
"src/core/lib/slice/percent_encoding.c",
"src/core/lib/slice/slice.c",
"src/core/lib/slice/slice_buffer.c",
+ "src/core/lib/slice/slice_hash_table.c",
+ "src/core/lib/slice/slice_intern.c",
"src/core/lib/slice/slice_string_helpers.c",
"src/core/lib/surface/alarm.c",
"src/core/lib/surface/api_trace.c",
@@ -433,7 +436,6 @@ cc_library(
"src/core/lib/surface/version.c",
"src/core/lib/transport/byte_stream.c",
"src/core/lib/transport/connectivity_state.c",
- "src/core/lib/transport/mdstr_hash_table.c",
"src/core/lib/transport/metadata.c",
"src/core/lib/transport/metadata_batch.c",
"src/core/lib/transport/pid_controller.c",
@@ -560,6 +562,7 @@ cc_library(
"include/grpc/impl/codegen/atm_gcc_atomic.h",
"include/grpc/impl/codegen/atm_gcc_sync.h",
"include/grpc/impl/codegen/atm_windows.h",
+ "include/grpc/impl/codegen/exec_ctx_fwd.h",
"include/grpc/impl/codegen/gpr_types.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/slice.h",
@@ -664,6 +667,7 @@ cc_library(
"src/core/lib/json/json_reader.h",
"src/core/lib/json/json_writer.h",
"src/core/lib/slice/percent_encoding.h",
+ "src/core/lib/slice/slice_hash_table.h",
"src/core/lib/slice/slice_string_helpers.h",
"src/core/lib/surface/api_trace.h",
"src/core/lib/surface/call.h",
@@ -678,7 +682,6 @@ cc_library(
"src/core/lib/surface/server.h",
"src/core/lib/transport/byte_stream.h",
"src/core/lib/transport/connectivity_state.h",
- "src/core/lib/transport/mdstr_hash_table.h",
"src/core/lib/transport/metadata.h",
"src/core/lib/transport/metadata_batch.h",
"src/core/lib/transport/pid_controller.h",
@@ -831,6 +834,8 @@ cc_library(
"src/core/lib/slice/percent_encoding.c",
"src/core/lib/slice/slice.c",
"src/core/lib/slice/slice_buffer.c",
+ "src/core/lib/slice/slice_hash_table.c",
+ "src/core/lib/slice/slice_intern.c",
"src/core/lib/slice/slice_string_helpers.c",
"src/core/lib/surface/alarm.c",
"src/core/lib/surface/api_trace.c",
@@ -852,7 +857,6 @@ cc_library(
"src/core/lib/surface/version.c",
"src/core/lib/transport/byte_stream.c",
"src/core/lib/transport/connectivity_state.c",
- "src/core/lib/transport/mdstr_hash_table.c",
"src/core/lib/transport/metadata.c",
"src/core/lib/transport/metadata_batch.c",
"src/core/lib/transport/pid_controller.c",
@@ -954,6 +958,7 @@ cc_library(
"include/grpc/impl/codegen/atm_gcc_atomic.h",
"include/grpc/impl/codegen/atm_gcc_sync.h",
"include/grpc/impl/codegen/atm_windows.h",
+ "include/grpc/impl/codegen/exec_ctx_fwd.h",
"include/grpc/impl/codegen/gpr_types.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/slice.h",
@@ -1053,6 +1058,7 @@ cc_library(
"src/core/lib/json/json_reader.h",
"src/core/lib/json/json_writer.h",
"src/core/lib/slice/percent_encoding.h",
+ "src/core/lib/slice/slice_hash_table.h",
"src/core/lib/slice/slice_string_helpers.h",
"src/core/lib/surface/api_trace.h",
"src/core/lib/surface/call.h",
@@ -1067,7 +1073,6 @@ cc_library(
"src/core/lib/surface/server.h",
"src/core/lib/transport/byte_stream.h",
"src/core/lib/transport/connectivity_state.h",
- "src/core/lib/transport/mdstr_hash_table.h",
"src/core/lib/transport/metadata.h",
"src/core/lib/transport/metadata_batch.h",
"src/core/lib/transport/pid_controller.h",
@@ -1212,6 +1217,8 @@ cc_library(
"src/core/lib/slice/percent_encoding.c",
"src/core/lib/slice/slice.c",
"src/core/lib/slice/slice_buffer.c",
+ "src/core/lib/slice/slice_hash_table.c",
+ "src/core/lib/slice/slice_intern.c",
"src/core/lib/slice/slice_string_helpers.c",
"src/core/lib/surface/alarm.c",
"src/core/lib/surface/api_trace.c",
@@ -1233,7 +1240,6 @@ cc_library(
"src/core/lib/surface/version.c",
"src/core/lib/transport/byte_stream.c",
"src/core/lib/transport/connectivity_state.c",
- "src/core/lib/transport/mdstr_hash_table.c",
"src/core/lib/transport/metadata.c",
"src/core/lib/transport/metadata_batch.c",
"src/core/lib/transport/pid_controller.c",
@@ -1331,6 +1337,7 @@ cc_library(
"include/grpc/impl/codegen/atm_gcc_atomic.h",
"include/grpc/impl/codegen/atm_gcc_sync.h",
"include/grpc/impl/codegen/atm_windows.h",
+ "include/grpc/impl/codegen/exec_ctx_fwd.h",
"include/grpc/impl/codegen/gpr_types.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/slice.h",
@@ -1486,6 +1493,7 @@ cc_library(
"include/grpc/impl/codegen/atm_gcc_atomic.h",
"include/grpc/impl/codegen/atm_gcc_sync.h",
"include/grpc/impl/codegen/atm_windows.h",
+ "include/grpc/impl/codegen/exec_ctx_fwd.h",
"include/grpc/impl/codegen/gpr_types.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/slice.h",
@@ -1630,6 +1638,7 @@ cc_library(
"include/grpc/impl/codegen/atm_gcc_atomic.h",
"include/grpc/impl/codegen/atm_gcc_sync.h",
"include/grpc/impl/codegen/atm_windows.h",
+ "include/grpc/impl/codegen/exec_ctx_fwd.h",
"include/grpc/impl/codegen/gpr_types.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/slice.h",
@@ -1795,6 +1804,7 @@ cc_library(
"include/grpc/impl/codegen/atm_gcc_atomic.h",
"include/grpc/impl/codegen/atm_gcc_sync.h",
"include/grpc/impl/codegen/atm_windows.h",
+ "include/grpc/impl/codegen/exec_ctx_fwd.h",
"include/grpc/impl/codegen/gpr_types.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/slice.h",
@@ -1957,6 +1967,7 @@ objc_library(
"include/grpc/impl/codegen/atm_gcc_atomic.h",
"include/grpc/impl/codegen/atm_gcc_sync.h",
"include/grpc/impl/codegen/atm_windows.h",
+ "include/grpc/impl/codegen/exec_ctx_fwd.h",
"include/grpc/impl/codegen/gpr_types.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/slice.h",
@@ -2073,6 +2084,8 @@ objc_library(
"src/core/lib/slice/percent_encoding.c",
"src/core/lib/slice/slice.c",
"src/core/lib/slice/slice_buffer.c",
+ "src/core/lib/slice/slice_hash_table.c",
+ "src/core/lib/slice/slice_intern.c",
"src/core/lib/slice/slice_string_helpers.c",
"src/core/lib/surface/alarm.c",
"src/core/lib/surface/api_trace.c",
@@ -2094,7 +2107,6 @@ objc_library(
"src/core/lib/surface/version.c",
"src/core/lib/transport/byte_stream.c",
"src/core/lib/transport/connectivity_state.c",
- "src/core/lib/transport/mdstr_hash_table.c",
"src/core/lib/transport/metadata.c",
"src/core/lib/transport/metadata_batch.c",
"src/core/lib/transport/pid_controller.c",
@@ -2221,6 +2233,7 @@ objc_library(
"include/grpc/impl/codegen/atm_gcc_atomic.h",
"include/grpc/impl/codegen/atm_gcc_sync.h",
"include/grpc/impl/codegen/atm_windows.h",
+ "include/grpc/impl/codegen/exec_ctx_fwd.h",
"include/grpc/impl/codegen/gpr_types.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/slice.h",
@@ -2304,6 +2317,7 @@ objc_library(
"src/core/lib/json/json_reader.h",
"src/core/lib/json/json_writer.h",
"src/core/lib/slice/percent_encoding.h",
+ "src/core/lib/slice/slice_hash_table.h",
"src/core/lib/slice/slice_string_helpers.h",
"src/core/lib/surface/api_trace.h",
"src/core/lib/surface/call.h",
@@ -2318,7 +2332,6 @@ objc_library(
"src/core/lib/surface/server.h",
"src/core/lib/transport/byte_stream.h",
"src/core/lib/transport/connectivity_state.h",
- "src/core/lib/transport/mdstr_hash_table.h",
"src/core/lib/transport/metadata.h",
"src/core/lib/transport/metadata_batch.h",
"src/core/lib/transport/pid_controller.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cc9170038e..bbce41bee6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -258,6 +258,7 @@ foreach(_hdr
include/grpc/impl/codegen/atm_gcc_atomic.h
include/grpc/impl/codegen/atm_gcc_sync.h
include/grpc/impl/codegen/atm_windows.h
+ include/grpc/impl/codegen/exec_ctx_fwd.h
include/grpc/impl/codegen/gpr_types.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/slice.h
@@ -367,6 +368,8 @@ add_library(grpc
src/core/lib/slice/percent_encoding.c
src/core/lib/slice/slice.c
src/core/lib/slice/slice_buffer.c
+ src/core/lib/slice/slice_hash_table.c
+ src/core/lib/slice/slice_intern.c
src/core/lib/slice/slice_string_helpers.c
src/core/lib/surface/alarm.c
src/core/lib/surface/api_trace.c
@@ -388,7 +391,6 @@ add_library(grpc
src/core/lib/surface/version.c
src/core/lib/transport/byte_stream.c
src/core/lib/transport/connectivity_state.c
- src/core/lib/transport/mdstr_hash_table.c
src/core/lib/transport/metadata.c
src/core/lib/transport/metadata_batch.c
src/core/lib/transport/pid_controller.c
@@ -535,6 +537,7 @@ foreach(_hdr
include/grpc/impl/codegen/atm_gcc_atomic.h
include/grpc/impl/codegen/atm_gcc_sync.h
include/grpc/impl/codegen/atm_windows.h
+ include/grpc/impl/codegen/exec_ctx_fwd.h
include/grpc/impl/codegen/gpr_types.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/slice.h
@@ -646,6 +649,8 @@ add_library(grpc_cronet
src/core/lib/slice/percent_encoding.c
src/core/lib/slice/slice.c
src/core/lib/slice/slice_buffer.c
+ src/core/lib/slice/slice_hash_table.c
+ src/core/lib/slice/slice_intern.c
src/core/lib/slice/slice_string_helpers.c
src/core/lib/surface/alarm.c
src/core/lib/surface/api_trace.c
@@ -667,7 +672,6 @@ add_library(grpc_cronet
src/core/lib/surface/version.c
src/core/lib/transport/byte_stream.c
src/core/lib/transport/connectivity_state.c
- src/core/lib/transport/mdstr_hash_table.c
src/core/lib/transport/metadata.c
src/core/lib/transport/metadata_batch.c
src/core/lib/transport/pid_controller.c
@@ -785,6 +789,7 @@ foreach(_hdr
include/grpc/impl/codegen/atm_gcc_atomic.h
include/grpc/impl/codegen/atm_gcc_sync.h
include/grpc/impl/codegen/atm_windows.h
+ include/grpc/impl/codegen/exec_ctx_fwd.h
include/grpc/impl/codegen/gpr_types.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/slice.h
@@ -897,6 +902,8 @@ add_library(grpc_unsecure
src/core/lib/slice/percent_encoding.c
src/core/lib/slice/slice.c
src/core/lib/slice/slice_buffer.c
+ src/core/lib/slice/slice_hash_table.c
+ src/core/lib/slice/slice_intern.c
src/core/lib/slice/slice_string_helpers.c
src/core/lib/surface/alarm.c
src/core/lib/surface/api_trace.c
@@ -918,7 +925,6 @@ add_library(grpc_unsecure
src/core/lib/surface/version.c
src/core/lib/transport/byte_stream.c
src/core/lib/transport/connectivity_state.c
- src/core/lib/transport/mdstr_hash_table.c
src/core/lib/transport/metadata.c
src/core/lib/transport/metadata_batch.c
src/core/lib/transport/pid_controller.c
@@ -1034,6 +1040,7 @@ foreach(_hdr
include/grpc/impl/codegen/atm_gcc_atomic.h
include/grpc/impl/codegen/atm_gcc_sync.h
include/grpc/impl/codegen/atm_windows.h
+ include/grpc/impl/codegen/exec_ctx_fwd.h
include/grpc/impl/codegen/gpr_types.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/slice.h
@@ -1197,6 +1204,7 @@ foreach(_hdr
include/grpc/impl/codegen/atm_gcc_atomic.h
include/grpc/impl/codegen/atm_gcc_sync.h
include/grpc/impl/codegen/atm_windows.h
+ include/grpc/impl/codegen/exec_ctx_fwd.h
include/grpc/impl/codegen/gpr_types.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/slice.h
@@ -1355,6 +1363,7 @@ foreach(_hdr
include/grpc/impl/codegen/atm_gcc_atomic.h
include/grpc/impl/codegen/atm_gcc_sync.h
include/grpc/impl/codegen/atm_windows.h
+ include/grpc/impl/codegen/exec_ctx_fwd.h
include/grpc/impl/codegen/gpr_types.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/slice.h
@@ -1551,6 +1560,7 @@ foreach(_hdr
include/grpc/impl/codegen/atm_gcc_atomic.h
include/grpc/impl/codegen/atm_gcc_sync.h
include/grpc/impl/codegen/atm_windows.h
+ include/grpc/impl/codegen/exec_ctx_fwd.h
include/grpc/impl/codegen/gpr_types.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/slice.h
diff --git a/Makefile b/Makefile
index 1609d6951b..0e0217e499 100644
--- a/Makefile
+++ b/Makefile
@@ -2552,6 +2552,7 @@ PUBLIC_HEADERS_C += \
include/grpc/impl/codegen/atm_gcc_atomic.h \
include/grpc/impl/codegen/atm_gcc_sync.h \
include/grpc/impl/codegen/atm_windows.h \
+ include/grpc/impl/codegen/exec_ctx_fwd.h \
include/grpc/impl/codegen/gpr_types.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/slice.h \
@@ -2706,6 +2707,8 @@ LIBGRPC_SRC = \
src/core/lib/slice/percent_encoding.c \
src/core/lib/slice/slice.c \
src/core/lib/slice/slice_buffer.c \
+ src/core/lib/slice/slice_hash_table.c \
+ src/core/lib/slice/slice_intern.c \
src/core/lib/slice/slice_string_helpers.c \
src/core/lib/surface/alarm.c \
src/core/lib/surface/api_trace.c \
@@ -2727,7 +2730,6 @@ LIBGRPC_SRC = \
src/core/lib/surface/version.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
- src/core/lib/transport/mdstr_hash_table.c \
src/core/lib/transport/metadata.c \
src/core/lib/transport/metadata_batch.c \
src/core/lib/transport/pid_controller.c \
@@ -2857,6 +2859,7 @@ PUBLIC_HEADERS_C += \
include/grpc/impl/codegen/atm_gcc_atomic.h \
include/grpc/impl/codegen/atm_gcc_sync.h \
include/grpc/impl/codegen/atm_windows.h \
+ include/grpc/impl/codegen/exec_ctx_fwd.h \
include/grpc/impl/codegen/gpr_types.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/slice.h \
@@ -3003,6 +3006,8 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/slice/percent_encoding.c \
src/core/lib/slice/slice.c \
src/core/lib/slice/slice_buffer.c \
+ src/core/lib/slice/slice_hash_table.c \
+ src/core/lib/slice/slice_intern.c \
src/core/lib/slice/slice_string_helpers.c \
src/core/lib/surface/alarm.c \
src/core/lib/surface/api_trace.c \
@@ -3024,7 +3029,6 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/surface/version.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
- src/core/lib/transport/mdstr_hash_table.c \
src/core/lib/transport/metadata.c \
src/core/lib/transport/metadata_batch.c \
src/core/lib/transport/pid_controller.c \
@@ -3126,6 +3130,7 @@ PUBLIC_HEADERS_C += \
include/grpc/impl/codegen/atm_gcc_atomic.h \
include/grpc/impl/codegen/atm_gcc_sync.h \
include/grpc/impl/codegen/atm_windows.h \
+ include/grpc/impl/codegen/exec_ctx_fwd.h \
include/grpc/impl/codegen/gpr_types.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/slice.h \
@@ -3291,6 +3296,8 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/slice/percent_encoding.c \
src/core/lib/slice/slice.c \
src/core/lib/slice/slice_buffer.c \
+ src/core/lib/slice/slice_hash_table.c \
+ src/core/lib/slice/slice_intern.c \
src/core/lib/slice/slice_string_helpers.c \
src/core/lib/surface/alarm.c \
src/core/lib/surface/api_trace.c \
@@ -3312,7 +3319,6 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/surface/version.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
- src/core/lib/transport/mdstr_hash_table.c \
src/core/lib/transport/metadata.c \
src/core/lib/transport/metadata_batch.c \
src/core/lib/transport/pid_controller.c \
@@ -3342,6 +3348,7 @@ PUBLIC_HEADERS_C += \
include/grpc/impl/codegen/atm_gcc_atomic.h \
include/grpc/impl/codegen/atm_gcc_sync.h \
include/grpc/impl/codegen/atm_windows.h \
+ include/grpc/impl/codegen/exec_ctx_fwd.h \
include/grpc/impl/codegen/gpr_types.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/slice.h \
@@ -3508,6 +3515,8 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/slice/percent_encoding.c \
src/core/lib/slice/slice.c \
src/core/lib/slice/slice_buffer.c \
+ src/core/lib/slice/slice_hash_table.c \
+ src/core/lib/slice/slice_intern.c \
src/core/lib/slice/slice_string_helpers.c \
src/core/lib/surface/alarm.c \
src/core/lib/surface/api_trace.c \
@@ -3529,7 +3538,6 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/surface/version.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
- src/core/lib/transport/mdstr_hash_table.c \
src/core/lib/transport/metadata.c \
src/core/lib/transport/metadata_batch.c \
src/core/lib/transport/pid_controller.c \
@@ -3630,6 +3638,7 @@ PUBLIC_HEADERS_C += \
include/grpc/impl/codegen/atm_gcc_atomic.h \
include/grpc/impl/codegen/atm_gcc_sync.h \
include/grpc/impl/codegen/atm_windows.h \
+ include/grpc/impl/codegen/exec_ctx_fwd.h \
include/grpc/impl/codegen/gpr_types.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/slice.h \
@@ -3874,6 +3883,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/impl/codegen/atm_gcc_atomic.h \
include/grpc/impl/codegen/atm_gcc_sync.h \
include/grpc/impl/codegen/atm_windows.h \
+ include/grpc/impl/codegen/exec_ctx_fwd.h \
include/grpc/impl/codegen/gpr_types.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/slice.h \
@@ -4061,6 +4071,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/impl/codegen/atm_gcc_atomic.h \
include/grpc/impl/codegen/atm_gcc_sync.h \
include/grpc/impl/codegen/atm_windows.h \
+ include/grpc/impl/codegen/exec_ctx_fwd.h \
include/grpc/impl/codegen/gpr_types.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/slice.h \
@@ -4406,6 +4417,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/impl/codegen/atm_gcc_atomic.h \
include/grpc/impl/codegen/atm_gcc_sync.h \
include/grpc/impl/codegen/atm_windows.h \
+ include/grpc/impl/codegen/exec_ctx_fwd.h \
include/grpc/impl/codegen/gpr_types.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/slice.h \
@@ -4584,6 +4596,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/impl/codegen/atm_gcc_atomic.h \
include/grpc/impl/codegen/atm_gcc_sync.h \
include/grpc/impl/codegen/atm_windows.h \
+ include/grpc/impl/codegen/exec_ctx_fwd.h \
include/grpc/impl/codegen/gpr_types.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/slice.h \
diff --git a/binding.gyp b/binding.gyp
index 28d7c6b9a5..4e17d68588 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -647,6 +647,8 @@
'src/core/lib/slice/percent_encoding.c',
'src/core/lib/slice/slice.c',
'src/core/lib/slice/slice_buffer.c',
+ 'src/core/lib/slice/slice_hash_table.c',
+ 'src/core/lib/slice/slice_intern.c',
'src/core/lib/slice/slice_string_helpers.c',
'src/core/lib/surface/alarm.c',
'src/core/lib/surface/api_trace.c',
@@ -668,7 +670,6 @@
'src/core/lib/surface/version.c',
'src/core/lib/transport/byte_stream.c',
'src/core/lib/transport/connectivity_state.c',
- 'src/core/lib/transport/mdstr_hash_table.c',
'src/core/lib/transport/metadata.c',
'src/core/lib/transport/metadata_batch.c',
'src/core/lib/transport/pid_controller.c',
diff --git a/build.yaml b/build.yaml
index 407b50ca7b..cca5003d27 100644
--- a/build.yaml
+++ b/build.yaml
@@ -144,6 +144,7 @@ filegroups:
- include/grpc/impl/codegen/atm_gcc_atomic.h
- include/grpc/impl/codegen/atm_gcc_sync.h
- include/grpc/impl/codegen/atm_windows.h
+ - include/grpc/impl/codegen/exec_ctx_fwd.h
- include/grpc/impl/codegen/gpr_types.h
- include/grpc/impl/codegen/port_platform.h
- include/grpc/impl/codegen/slice.h
@@ -237,6 +238,7 @@ filegroups:
- src/core/lib/json/json_reader.h
- src/core/lib/json/json_writer.h
- src/core/lib/slice/percent_encoding.h
+ - src/core/lib/slice/slice_hash_table.h
- src/core/lib/slice/slice_string_helpers.h
- src/core/lib/surface/api_trace.h
- src/core/lib/surface/call.h
@@ -251,7 +253,6 @@ filegroups:
- src/core/lib/surface/server.h
- src/core/lib/transport/byte_stream.h
- src/core/lib/transport/connectivity_state.h
- - src/core/lib/transport/mdstr_hash_table.h
- src/core/lib/transport/metadata.h
- src/core/lib/transport/metadata_batch.h
- src/core/lib/transport/pid_controller.h
@@ -343,6 +344,8 @@ filegroups:
- src/core/lib/slice/percent_encoding.c
- src/core/lib/slice/slice.c
- src/core/lib/slice/slice_buffer.c
+ - src/core/lib/slice/slice_hash_table.c
+ - src/core/lib/slice/slice_intern.c
- src/core/lib/slice/slice_string_helpers.c
- src/core/lib/surface/alarm.c
- src/core/lib/surface/api_trace.c
@@ -364,7 +367,6 @@ filegroups:
- src/core/lib/surface/version.c
- src/core/lib/transport/byte_stream.c
- src/core/lib/transport/connectivity_state.c
- - src/core/lib/transport/mdstr_hash_table.c
- src/core/lib/transport/metadata.c
- src/core/lib/transport/metadata_batch.c
- src/core/lib/transport/pid_controller.c
diff --git a/config.m4 b/config.m4
index 7f65b7c0d8..4c39e6397a 100644
--- a/config.m4
+++ b/config.m4
@@ -163,6 +163,8 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/slice/percent_encoding.c \
src/core/lib/slice/slice.c \
src/core/lib/slice/slice_buffer.c \
+ src/core/lib/slice/slice_hash_table.c \
+ src/core/lib/slice/slice_intern.c \
src/core/lib/slice/slice_string_helpers.c \
src/core/lib/surface/alarm.c \
src/core/lib/surface/api_trace.c \
@@ -184,7 +186,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/surface/version.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
- src/core/lib/transport/mdstr_hash_table.c \
src/core/lib/transport/metadata.c \
src/core/lib/transport/metadata_batch.c \
src/core/lib/transport/pid_controller.c \
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index c4ec01da93..f865dc4657 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -146,6 +146,7 @@ Pod::Spec.new do |s|
'include/grpc/impl/codegen/atm_gcc_atomic.h',
'include/grpc/impl/codegen/atm_gcc_sync.h',
'include/grpc/impl/codegen/atm_windows.h',
+ 'include/grpc/impl/codegen/exec_ctx_fwd.h',
'include/grpc/impl/codegen/gpr_types.h',
'include/grpc/impl/codegen/port_platform.h',
'include/grpc/impl/codegen/slice.h',
@@ -172,6 +173,7 @@ Pod::Spec.new do |s|
'include/grpc/impl/codegen/atm_gcc_atomic.h',
'include/grpc/impl/codegen/atm_gcc_sync.h',
'include/grpc/impl/codegen/atm_windows.h',
+ 'include/grpc/impl/codegen/exec_ctx_fwd.h',
'include/grpc/impl/codegen/gpr_types.h',
'include/grpc/impl/codegen/port_platform.h',
'include/grpc/impl/codegen/slice.h',
@@ -319,6 +321,7 @@ Pod::Spec.new do |s|
'src/core/lib/json/json_reader.h',
'src/core/lib/json/json_writer.h',
'src/core/lib/slice/percent_encoding.h',
+ 'src/core/lib/slice/slice_hash_table.h',
'src/core/lib/slice/slice_string_helpers.h',
'src/core/lib/surface/api_trace.h',
'src/core/lib/surface/call.h',
@@ -333,7 +336,6 @@ Pod::Spec.new do |s|
'src/core/lib/surface/server.h',
'src/core/lib/transport/byte_stream.h',
'src/core/lib/transport/connectivity_state.h',
- 'src/core/lib/transport/mdstr_hash_table.h',
'src/core/lib/transport/metadata.h',
'src/core/lib/transport/metadata_batch.h',
'src/core/lib/transport/pid_controller.h',
@@ -505,6 +507,8 @@ Pod::Spec.new do |s|
'src/core/lib/slice/percent_encoding.c',
'src/core/lib/slice/slice.c',
'src/core/lib/slice/slice_buffer.c',
+ 'src/core/lib/slice/slice_hash_table.c',
+ 'src/core/lib/slice/slice_intern.c',
'src/core/lib/slice/slice_string_helpers.c',
'src/core/lib/surface/alarm.c',
'src/core/lib/surface/api_trace.c',
@@ -526,7 +530,6 @@ Pod::Spec.new do |s|
'src/core/lib/surface/version.c',
'src/core/lib/transport/byte_stream.c',
'src/core/lib/transport/connectivity_state.c',
- 'src/core/lib/transport/mdstr_hash_table.c',
'src/core/lib/transport/metadata.c',
'src/core/lib/transport/metadata_batch.c',
'src/core/lib/transport/pid_controller.c',
@@ -722,6 +725,7 @@ Pod::Spec.new do |s|
'src/core/lib/json/json_reader.h',
'src/core/lib/json/json_writer.h',
'src/core/lib/slice/percent_encoding.h',
+ 'src/core/lib/slice/slice_hash_table.h',
'src/core/lib/slice/slice_string_helpers.h',
'src/core/lib/surface/api_trace.h',
'src/core/lib/surface/call.h',
@@ -736,7 +740,6 @@ Pod::Spec.new do |s|
'src/core/lib/surface/server.h',
'src/core/lib/transport/byte_stream.h',
'src/core/lib/transport/connectivity_state.h',
- 'src/core/lib/transport/mdstr_hash_table.h',
'src/core/lib/transport/metadata.h',
'src/core/lib/transport/metadata_batch.h',
'src/core/lib/transport/pid_controller.h',
diff --git a/grpc.def b/grpc.def
index 01628638ef..c5877f89c8 100644
--- a/grpc.def
+++ b/grpc.def
@@ -141,17 +141,27 @@ EXPORTS
grpc_slice_new_with_user_data
grpc_slice_new_with_len
grpc_slice_malloc
+ grpc_slice_intern
grpc_slice_from_copied_string
grpc_slice_from_copied_buffer
grpc_slice_from_static_string
+ grpc_slice_from_static_buffer
grpc_slice_sub
grpc_slice_sub_no_ref
grpc_slice_split_tail
grpc_slice_split_head
- gpr_empty_slice
+ grpc_empty_slice
+ grpc_slice_default_hash_impl
grpc_slice_cmp
grpc_slice_str_cmp
+ grpc_slice_buf_cmp
+ grpc_slice_buf_start_eq
+ grpc_slice_rchr
+ grpc_slice_chr
+ grpc_slice_slice
+ grpc_slice_hash
grpc_slice_is_equivalent
+ grpc_slice_dup
grpc_slice_buffer_init
grpc_slice_buffer_destroy
grpc_slice_buffer_add
diff --git a/grpc.gemspec b/grpc.gemspec
index e2a2ffc21a..385a9f4caa 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -74,6 +74,7 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/impl/codegen/atm_gcc_atomic.h )
s.files += %w( include/grpc/impl/codegen/atm_gcc_sync.h )
s.files += %w( include/grpc/impl/codegen/atm_windows.h )
+ s.files += %w( include/grpc/impl/codegen/exec_ctx_fwd.h )
s.files += %w( include/grpc/impl/codegen/gpr_types.h )
s.files += %w( include/grpc/impl/codegen/port_platform.h )
s.files += %w( include/grpc/impl/codegen/slice.h )
@@ -156,6 +157,7 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/impl/codegen/atm_gcc_atomic.h )
s.files += %w( include/grpc/impl/codegen/atm_gcc_sync.h )
s.files += %w( include/grpc/impl/codegen/atm_windows.h )
+ s.files += %w( include/grpc/impl/codegen/exec_ctx_fwd.h )
s.files += %w( include/grpc/impl/codegen/gpr_types.h )
s.files += %w( include/grpc/impl/codegen/port_platform.h )
s.files += %w( include/grpc/impl/codegen/slice.h )
@@ -239,6 +241,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/json/json_reader.h )
s.files += %w( src/core/lib/json/json_writer.h )
s.files += %w( src/core/lib/slice/percent_encoding.h )
+ s.files += %w( src/core/lib/slice/slice_hash_table.h )
s.files += %w( src/core/lib/slice/slice_string_helpers.h )
s.files += %w( src/core/lib/surface/api_trace.h )
s.files += %w( src/core/lib/surface/call.h )
@@ -253,7 +256,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/surface/server.h )
s.files += %w( src/core/lib/transport/byte_stream.h )
s.files += %w( src/core/lib/transport/connectivity_state.h )
- s.files += %w( src/core/lib/transport/mdstr_hash_table.h )
s.files += %w( src/core/lib/transport/metadata.h )
s.files += %w( src/core/lib/transport/metadata_batch.h )
s.files += %w( src/core/lib/transport/pid_controller.h )
@@ -425,6 +427,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/slice/percent_encoding.c )
s.files += %w( src/core/lib/slice/slice.c )
s.files += %w( src/core/lib/slice/slice_buffer.c )
+ s.files += %w( src/core/lib/slice/slice_hash_table.c )
+ s.files += %w( src/core/lib/slice/slice_intern.c )
s.files += %w( src/core/lib/slice/slice_string_helpers.c )
s.files += %w( src/core/lib/surface/alarm.c )
s.files += %w( src/core/lib/surface/api_trace.c )
@@ -446,7 +450,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/surface/version.c )
s.files += %w( src/core/lib/transport/byte_stream.c )
s.files += %w( src/core/lib/transport/connectivity_state.c )
- s.files += %w( src/core/lib/transport/mdstr_hash_table.c )
s.files += %w( src/core/lib/transport/metadata.c )
s.files += %w( src/core/lib/transport/metadata_batch.c )
s.files += %w( src/core/lib/transport/pid_controller.c )
diff --git a/include/grpc++/support/channel_arguments.h b/include/grpc++/support/channel_arguments.h
index 571ab5d530..d43f7c61bd 100644
--- a/include/grpc++/support/channel_arguments.h
+++ b/include/grpc++/support/channel_arguments.h
@@ -127,7 +127,7 @@ class ChannelArguments {
/// Default pointer argument operations.
struct PointerVtableMembers {
static void* Copy(void* in) { return in; }
- static void Destroy(void* in) {}
+ static void Destroy(grpc_exec_ctx* exec_ctx, void* in) {}
static int Compare(void* a, void* b) {
if (a < b) return -1;
if (a > b) return 1;
diff --git a/include/grpc/compression.h b/include/grpc/compression.h
index 5f285cdcdf..659d6fe758 100644
--- a/include/grpc/compression.h
+++ b/include/grpc/compression.h
@@ -34,11 +34,12 @@
#ifndef GRPC_COMPRESSION_H
#define GRPC_COMPRESSION_H
-#include <stdlib.h>
-
#include <grpc/impl/codegen/port_platform.h>
+#include <stdlib.h>
+
#include <grpc/impl/codegen/compression_types.h>
+#include <grpc/slice.h>
#ifdef __cplusplus
extern "C" {
@@ -48,8 +49,7 @@ extern "C" {
* grpc_compression_algorithm instance, updating \a algorithm. Returns 1 upon
* success, 0 otherwise. */
GRPCAPI int grpc_compression_algorithm_parse(
- const char *name, size_t name_length,
- grpc_compression_algorithm *algorithm);
+ grpc_slice value, grpc_compression_algorithm *algorithm);
/** Updates \a name with the encoding name corresponding to a valid \a
* algorithm. Note that \a name is statically allocated and must *not* be freed.
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index 5e486215e0..2f3b37ad80 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -178,8 +178,8 @@ GRPCAPI void grpc_channel_watch_connectivity_state(
possible values). */
GRPCAPI grpc_call *grpc_channel_create_call(
grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
- grpc_completion_queue *completion_queue, const char *method,
- const char *host, gpr_timespec deadline, void *reserved);
+ grpc_completion_queue *completion_queue, grpc_slice method,
+ const grpc_slice *host, gpr_timespec deadline, void *reserved);
/** Ping the channels peer (load balanced channels will select one sub-channel
to ping); if the channel is not connected, posts a failed. */
@@ -396,14 +396,14 @@ GRPCAPI void grpc_server_destroy(grpc_server *server);
GRPCAPI int grpc_tracer_set_enabled(const char *name, int enabled);
/** Check whether a metadata key is legal (will be accepted by core) */
-GRPCAPI int grpc_header_key_is_legal(const char *key, size_t length);
+GRPCAPI int grpc_header_key_is_legal(grpc_slice slice);
/** Check whether a non-binary metadata value is legal (will be accepted by
core) */
-GRPCAPI int grpc_header_nonbin_value_is_legal(const char *value, size_t length);
+GRPCAPI int grpc_header_nonbin_value_is_legal(grpc_slice slice);
/** Check whether a metadata key corresponds to a binary value */
-GRPCAPI int grpc_is_binary_header(const char *key, size_t length);
+GRPCAPI int grpc_is_binary_header(grpc_slice slice);
/** Convert grpc_call_error values to a string */
GRPCAPI const char *grpc_call_error_to_string(grpc_call_error error);
diff --git a/include/grpc/impl/codegen/compression_types.h b/include/grpc/impl/codegen/compression_types.h
index 170d99f431..8810943137 100644
--- a/include/grpc/impl/codegen/compression_types.h
+++ b/include/grpc/impl/codegen/compression_types.h
@@ -41,11 +41,6 @@
extern "C" {
#endif
-/** To be used as initial metadata key for the request of a concrete compression
- * algorithm */
-#define GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY \
- "grpc-internal-encoding-request"
-
/** To be used in channel arguments.
*
* \addtogroup grpc_arg_keys
diff --git a/include/grpc/impl/codegen/exec_ctx_fwd.h b/include/grpc/impl/codegen/exec_ctx_fwd.h
new file mode 100644
index 0000000000..32edcedbb3
--- /dev/null
+++ b/include/grpc/impl/codegen/exec_ctx_fwd.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_EXEC_CTX_FWD_H
+#define GRPC_IMPL_CODEGEN_EXEC_CTX_FWD_H
+
+/* forward declaration for exec_ctx.h */
+struct grpc_exec_ctx;
+typedef struct grpc_exec_ctx grpc_exec_ctx;
+
+#endif /* GRPC_IMPL_CODEGEN_EXEC_CTX_FWD_H */
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index da1bd9dcbf..04d01eaffd 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -34,10 +34,10 @@
#ifndef GRPC_IMPL_CODEGEN_GRPC_TYPES_H
#define GRPC_IMPL_CODEGEN_GRPC_TYPES_H
+#include <grpc/impl/codegen/compression_types.h>
+#include <grpc/impl/codegen/exec_ctx_fwd.h>
#include <grpc/impl/codegen/gpr_types.h>
#include <grpc/impl/codegen/slice.h>
-
-#include <grpc/impl/codegen/compression_types.h>
#include <grpc/impl/codegen/status.h>
#include <stddef.h>
@@ -96,7 +96,7 @@ typedef enum {
typedef struct grpc_arg_pointer_vtable {
void *(*copy)(void *p);
- void (*destroy)(void *p);
+ void (*destroy)(grpc_exec_ctx *exec_ctx, void *p);
int (*cmp)(void *p, void *q);
} grpc_arg_pointer_vtable;
@@ -297,9 +297,11 @@ typedef enum grpc_call_error {
/** A single metadata element */
typedef struct grpc_metadata {
- const char *key;
- const char *value;
- size_t value_length;
+ /* the key, value values are expected to line up with grpc_mdelem: if changing
+ them, update metadata.h at the same time. */
+ grpc_slice key;
+ grpc_slice value;
+
uint32_t flags;
/** The following fields are reserved for grpc internal use.
@@ -341,10 +343,8 @@ typedef struct {
} grpc_metadata_array;
typedef struct {
- char *method;
- size_t method_capacity;
- char *host;
- size_t host_capacity;
+ grpc_slice method;
+ grpc_slice host;
gpr_timespec deadline;
uint32_t flags;
void *reserved;
@@ -426,7 +426,10 @@ typedef struct grpc_op {
size_t trailing_metadata_count;
grpc_metadata *trailing_metadata;
grpc_status_code status;
- const char *status_details;
+ /* optional: set to NULL if no details need sending, non-NULL if they do
+ * pointer will not be retained past the start_batch call
+ */
+ grpc_slice *status_details;
} send_status_from_server;
/** ownership of the array is with the caller, but ownership of the elements
stays with the call object (ie key, value members are owned by the call
@@ -447,28 +450,7 @@ typedef struct grpc_op {
value, or reuse it in a future op. */
grpc_metadata_array *trailing_metadata;
grpc_status_code *status;
- /** status_details is a buffer owned by the application before the op
- completes and after the op has completed. During the operation
- status_details may be reallocated to a size larger than
- *status_details_capacity, in which case *status_details_capacity will
- be updated with the new array capacity.
-
- Pre-allocating space:
- size_t my_capacity = 8;
- char *my_details = gpr_malloc(my_capacity);
- x.status_details = &my_details;
- x.status_details_capacity = &my_capacity;
-
- Not pre-allocating space:
- size_t my_capacity = 0;
- char *my_details = NULL;
- x.status_details = &my_details;
- x.status_details_capacity = &my_capacity;
-
- After the call:
- gpr_free(my_details); */
- char **status_details;
- size_t *status_details_capacity;
+ grpc_slice *status_details;
} recv_status_on_client;
struct {
/** out argument, set to 1 if the call failed in any way (seen as a
diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h
index 774ba0e95d..ecce1ca089 100644
--- a/include/grpc/impl/codegen/slice.h
+++ b/include/grpc/impl/codegen/slice.h
@@ -37,6 +37,10 @@
#include <stddef.h>
#include <stdint.h>
+#include <grpc/impl/codegen/exec_ctx_fwd.h>
+
+typedef struct grpc_slice grpc_slice;
+
/* Slice API
A slice represents a contiguous reference counted array of bytes.
@@ -50,14 +54,19 @@
reference ownership semantics (who should call unref?) and mutability
constraints (is the callee allowed to modify the slice?) */
+typedef struct grpc_slice_refcount_vtable {
+ void (*ref)(void *);
+ void (*unref)(grpc_exec_ctx *exec_ctx, void *);
+ uint32_t (*hash)(void *, grpc_slice slice);
+} grpc_slice_refcount_vtable;
+
/* Reference count container for grpc_slice. Contains function pointers to
increment and decrement reference counts. Implementations should cleanup
when the reference count drops to zero.
Typically client code should not touch this, and use grpc_slice_malloc,
grpc_slice_new, or grpc_slice_new_with_len instead. */
typedef struct grpc_slice_refcount {
- void (*ref)(void *);
- void (*unref)(void *);
+ const grpc_slice_refcount_vtable *vtable;
} grpc_slice_refcount;
#define GRPC_SLICE_INLINED_SIZE (sizeof(size_t) + sizeof(uint8_t *) - 1)
@@ -71,7 +80,7 @@ typedef struct grpc_slice_refcount {
If the slice does not have a refcount, it represents an inlined small piece
of data that is copied by value. */
-typedef struct grpc_slice {
+struct grpc_slice {
struct grpc_slice_refcount *refcount;
union {
struct {
@@ -83,7 +92,7 @@ typedef struct grpc_slice {
uint8_t bytes[GRPC_SLICE_INLINED_SIZE];
} inlined;
} data;
-} grpc_slice;
+};
#define GRPC_SLICE_BUFFER_INLINE_ELEMENTS 8
diff --git a/include/grpc/slice.h b/include/grpc/slice.h
index 1f181aae16..dc0a7a344e 100644
--- a/include/grpc/slice.h
+++ b/include/grpc/slice.h
@@ -76,6 +76,12 @@ GPRAPI grpc_slice grpc_slice_new_with_len(void *p, size_t len,
Aborts if malloc() fails. */
GPRAPI grpc_slice grpc_slice_malloc(size_t length);
+/* Intern a slice:
+
+ The return value for two invocations of this function with the same sequence
+ of bytes is a slice which points to the same memory. */
+GPRAPI grpc_slice grpc_slice_intern(grpc_slice slice);
+
/* Create a slice by copying a string.
Does not preserve null terminators.
Equivalent to:
@@ -93,6 +99,9 @@ GPRAPI grpc_slice grpc_slice_from_copied_buffer(const char *source, size_t len);
/* Create a slice pointing to constant memory */
GPRAPI grpc_slice grpc_slice_from_static_string(const char *source);
+/* Create a slice pointing to constant memory */
+GPRAPI grpc_slice grpc_slice_from_static_buffer(const void *source, size_t len);
+
/* Return a result slice derived from s, which shares a ref count with s, where
result.data==s.data+begin, and result.length==end-begin.
The ref count of s is increased by one.
@@ -113,18 +122,38 @@ GPRAPI grpc_slice grpc_slice_split_tail(grpc_slice *s, size_t split);
Requires s intialized, split <= s.length */
GPRAPI grpc_slice grpc_slice_split_head(grpc_slice *s, size_t split);
-GPRAPI grpc_slice gpr_empty_slice(void);
+GPRAPI grpc_slice grpc_empty_slice(void);
+
+GPRAPI uint32_t grpc_slice_default_hash_impl(void *, grpc_slice s);
/* Returns <0 if a < b, ==0 if a == b, >0 if a > b
The order is arbitrary, and is not guaranteed to be stable across different
versions of the API. */
GPRAPI int grpc_slice_cmp(grpc_slice a, grpc_slice b);
GPRAPI int grpc_slice_str_cmp(grpc_slice a, const char *b);
+GPRAPI int grpc_slice_buf_cmp(grpc_slice a, const void *b, size_t blen);
+
+/* return non-zero if the first blen bytes of a are equal to b */
+GPRAPI int grpc_slice_buf_start_eq(grpc_slice a, const void *b, size_t blen);
+
+/* return the index of the last instance of \a c in \a s, or -1 if not found */
+GPRAPI int grpc_slice_rchr(grpc_slice s, char c);
+GPRAPI int grpc_slice_chr(grpc_slice s, char c);
+
+/* return the index of the first occurance of \a needle in \a haystack, or -1 if
+ * it's not found */
+GPRAPI int grpc_slice_slice(grpc_slice haystack, grpc_slice needle);
+
+GPRAPI uint32_t grpc_slice_hash(grpc_slice s);
/* Do two slices point at the same memory, with the same length
If a or b is inlined, actually compares data */
GPRAPI int grpc_slice_is_equivalent(grpc_slice a, grpc_slice b);
+/* Return a slice pointing to newly allocated memory that has the same contents
+ * as \a s */
+GPRAPI grpc_slice grpc_slice_dup(grpc_slice a);
+
#ifdef __cplusplus
}
#endif
diff --git a/package.xml b/package.xml
index 2822ac624d..ff84a0e45b 100644
--- a/package.xml
+++ b/package.xml
@@ -81,6 +81,7 @@
<file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_atomic.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_sync.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/atm_windows.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/exec_ctx_fwd.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_types.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/port_platform.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/slice.h" role="src" />
@@ -163,6 +164,7 @@
<file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_atomic.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_sync.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/atm_windows.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/exec_ctx_fwd.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_types.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/port_platform.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/slice.h" role="src" />
@@ -246,6 +248,7 @@
<file baseinstalldir="/" name="src/core/lib/json/json_reader.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json_writer.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/percent_encoding.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/slice/slice_hash_table.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_string_helpers.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/api_trace.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/call.h" role="src" />
@@ -260,7 +263,6 @@
<file baseinstalldir="/" name="src/core/lib/surface/server.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/byte_stream.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/connectivity_state.h" role="src" />
- <file baseinstalldir="/" name="src/core/lib/transport/mdstr_hash_table.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/metadata.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/metadata_batch.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/pid_controller.h" role="src" />
@@ -432,6 +434,8 @@
<file baseinstalldir="/" name="src/core/lib/slice/percent_encoding.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_buffer.c" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/slice/slice_hash_table.c" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/slice/slice_intern.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_string_helpers.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/alarm.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/api_trace.c" role="src" />
@@ -453,7 +457,6 @@
<file baseinstalldir="/" name="src/core/lib/surface/version.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/byte_stream.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/connectivity_state.c" role="src" />
- <file baseinstalldir="/" name="src/core/lib/transport/mdstr_hash_table.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/metadata.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/metadata_batch.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/pid_controller.c" role="src" />
diff --git a/src/core/ext/census/grpc_filter.c b/src/core/ext/census/grpc_filter.c
index 397dbc40a8..c1a883b6f8 100644
--- a/src/core/ext/census/grpc_filter.c
+++ b/src/core/ext/census/grpc_filter.c
@@ -67,9 +67,7 @@ static void extract_and_annotate_method_tag(grpc_metadata_batch *md,
channel_data *chand) {
grpc_linked_mdelem *m;
for (m = md->list.head; m != NULL; m = m->next) {
- if (m->md->key == GRPC_MDSTR_PATH) {
- gpr_log(GPR_DEBUG, "%s",
- (const char *)GRPC_SLICE_START_PTR(m->md->value->slice));
+ if (grpc_slice_cmp(GRPC_MDKEY(m->md), GRPC_MDSTR_PATH) == 0) {
/* Add method tag here */
}
}
diff --git a/src/core/ext/census/grpc_plugin.c b/src/core/ext/census/grpc_plugin.c
index e43ceafd0c..c9fe453af8 100644
--- a/src/core/ext/census/grpc_plugin.c
+++ b/src/core/ext/census/grpc_plugin.c
@@ -51,7 +51,8 @@ static bool is_census_enabled(const grpc_channel_args *a) {
return census_enabled();
}
-static bool maybe_add_census_filter(grpc_channel_stack_builder *builder,
+static bool maybe_add_census_filter(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder,
void *arg) {
const grpc_channel_args *args =
grpc_channel_stack_builder_get_channel_arguments(builder);
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index 1fcff4388a..8929e8c48a 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -51,6 +51,7 @@
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/transport/connectivity_state.h"
@@ -82,8 +83,12 @@ static void *method_parameters_copy(void *value) {
return new_value;
}
-static const grpc_mdstr_hash_table_vtable method_parameters_vtable = {
- gpr_free, method_parameters_copy};
+static void method_parameters_free(grpc_exec_ctx *exec_ctx, void *p) {
+ gpr_free(p);
+}
+
+static const grpc_slice_hash_table_vtable method_parameters_vtable = {
+ method_parameters_free, method_parameters_copy};
static void *method_parameters_create_from_json(const grpc_json *json) {
wait_for_ready_value wait_for_ready = WAIT_FOR_READY_UNSET;
@@ -160,7 +165,7 @@ typedef struct client_channel_channel_data {
/** service config in JSON form */
char *service_config_json;
/** maps method names to method_parameters structs */
- grpc_mdstr_hash_table *method_params_table;
+ grpc_slice_hash_table *method_params_table;
/** incoming resolver result - set by resolver.next() */
grpc_channel_args *resolver_result;
/** a list of closures that are all waiting for config to come in */
@@ -261,7 +266,7 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
char *lb_policy_name = NULL;
grpc_lb_policy *lb_policy = NULL;
grpc_lb_policy *old_lb_policy;
- grpc_mdstr_hash_table *method_params_table = NULL;
+ grpc_slice_hash_table *method_params_table = NULL;
grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE;
bool exit_idle = false;
grpc_error *state_error = GRPC_ERROR_CREATE("No load balancing policy");
@@ -326,7 +331,7 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
grpc_service_config_create(service_config_json);
if (service_config != NULL) {
method_params_table = grpc_service_config_create_method_config_table(
- service_config, method_parameters_create_from_json,
+ exec_ctx, service_config, method_parameters_create_from_json,
&method_parameters_vtable);
grpc_service_config_destroy(service_config);
}
@@ -335,7 +340,7 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
// be pointing to data inside chand->resolver_result.
// The copy will be saved in chand->lb_policy_name below.
lb_policy_name = gpr_strdup(lb_policy_name);
- grpc_channel_args_destroy(chand->resolver_result);
+ grpc_channel_args_destroy(exec_ctx, chand->resolver_result);
chand->resolver_result = NULL;
}
@@ -356,7 +361,7 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
chand->service_config_json = service_config_json;
}
if (chand->method_params_table != NULL) {
- grpc_mdstr_hash_table_unref(chand->method_params_table);
+ grpc_slice_hash_table_unref(exec_ctx, chand->method_params_table);
}
chand->method_params_table = method_params_table;
if (lb_policy != NULL) {
@@ -540,7 +545,7 @@ static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx,
gpr_free(chand->lb_policy_name);
gpr_free(chand->service_config_json);
if (chand->method_params_table != NULL) {
- grpc_mdstr_hash_table_unref(chand->method_params_table);
+ grpc_slice_hash_table_unref(exec_ctx, chand->method_params_table);
}
grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker);
grpc_pollset_set_destroy(chand->interested_parties);
@@ -575,7 +580,7 @@ typedef struct client_channel_call_data {
// to avoid this without breaking the grpc_deadline_state abstraction.
grpc_deadline_state deadline_state;
- grpc_mdstr *path; // Request path.
+ grpc_slice path; // Request path.
gpr_timespec call_start_time;
gpr_timespec deadline;
wait_for_ready_value wait_for_ready_from_service_config;
@@ -972,16 +977,16 @@ static void read_service_config(grpc_exec_ctx *exec_ctx, void *arg,
if (error == GRPC_ERROR_NONE) {
// Get the method config table from channel data.
gpr_mu_lock(&chand->mu);
- grpc_mdstr_hash_table *method_params_table = NULL;
+ grpc_slice_hash_table *method_params_table = NULL;
if (chand->method_params_table != NULL) {
method_params_table =
- grpc_mdstr_hash_table_ref(chand->method_params_table);
+ grpc_slice_hash_table_ref(chand->method_params_table);
}
gpr_mu_unlock(&chand->mu);
// If the method config table was present, use it.
if (method_params_table != NULL) {
- const method_parameters *method_params =
- grpc_method_config_table_get(method_params_table, calld->path);
+ const method_parameters *method_params = grpc_method_config_table_get(
+ exec_ctx, method_params_table, calld->path);
if (method_params != NULL) {
const bool have_method_timeout =
gpr_time_cmp(method_params->timeout, gpr_time_0(GPR_TIMESPAN)) != 0;
@@ -1004,7 +1009,7 @@ static void read_service_config(grpc_exec_ctx *exec_ctx, void *arg,
gpr_mu_unlock(&calld->mu);
}
}
- grpc_mdstr_hash_table_unref(method_params_table);
+ grpc_slice_hash_table_unref(exec_ctx, method_params_table);
}
}
GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "read_service_config");
@@ -1018,7 +1023,7 @@ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
call_data *calld = elem->call_data;
// Initialize data members.
grpc_deadline_state_init(exec_ctx, elem, args->call_stack);
- calld->path = GRPC_MDSTR_REF(args->path);
+ calld->path = grpc_slice_ref_internal(args->path);
calld->call_start_time = args->start_time;
calld->deadline = gpr_convert_clock_type(args->deadline, GPR_CLOCK_MONOTONIC);
calld->wait_for_ready_from_service_config = WAIT_FOR_READY_UNSET;
@@ -1042,11 +1047,11 @@ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
if (chand->lb_policy != NULL) {
// We already have a resolver result, so check for service config.
if (chand->method_params_table != NULL) {
- grpc_mdstr_hash_table *method_params_table =
- grpc_mdstr_hash_table_ref(chand->method_params_table);
+ grpc_slice_hash_table *method_params_table =
+ grpc_slice_hash_table_ref(chand->method_params_table);
gpr_mu_unlock(&chand->mu);
- method_parameters *method_params =
- grpc_method_config_table_get(method_params_table, args->path);
+ method_parameters *method_params = grpc_method_config_table_get(
+ exec_ctx, method_params_table, args->path);
if (method_params != NULL) {
if (gpr_time_cmp(method_params->timeout,
gpr_time_0(GPR_CLOCK_MONOTONIC)) != 0) {
@@ -1059,7 +1064,7 @@ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
method_params->wait_for_ready;
}
}
- grpc_mdstr_hash_table_unref(method_params_table);
+ grpc_slice_hash_table_unref(exec_ctx, method_params_table);
} else {
gpr_mu_unlock(&chand->mu);
}
@@ -1087,7 +1092,7 @@ static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
void *and_free_memory) {
call_data *calld = elem->call_data;
grpc_deadline_state_destroy(exec_ctx, elem);
- GRPC_MDSTR_UNREF(calld->path);
+ grpc_slice_unref_internal(exec_ctx, calld->path);
GRPC_ERROR_UNREF(calld->cancel_error);
grpc_subchannel_call *call = GET_CALL(calld);
if (call != NULL && call != CANCELLED_CALL) {
diff --git a/src/core/ext/client_channel/client_channel_plugin.c b/src/core/ext/client_channel/client_channel_plugin.c
index a3e5079843..988b7a1d5c 100644
--- a/src/core/ext/client_channel/client_channel_plugin.c
+++ b/src/core/ext/client_channel/client_channel_plugin.c
@@ -43,12 +43,14 @@
#include "src/core/ext/client_channel/subchannel_index.h"
#include "src/core/lib/surface/channel_init.h"
-static bool append_filter(grpc_channel_stack_builder *builder, void *arg) {
+static bool append_filter(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder, void *arg) {
return grpc_channel_stack_builder_append_filter(
builder, (const grpc_channel_filter *)arg, NULL, NULL);
}
-static bool set_default_host_if_unset(grpc_channel_stack_builder *builder,
+static bool set_default_host_if_unset(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder,
void *unused) {
const grpc_channel_args *args =
grpc_channel_stack_builder_get_channel_arguments(builder);
@@ -66,9 +68,10 @@ static bool set_default_host_if_unset(grpc_channel_stack_builder *builder,
arg.key = GRPC_ARG_DEFAULT_AUTHORITY;
arg.value.string = default_authority;
grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
- grpc_channel_stack_builder_set_channel_arguments(builder, new_args);
+ grpc_channel_stack_builder_set_channel_arguments(exec_ctx, builder,
+ new_args);
gpr_free(default_authority);
- grpc_channel_args_destroy(new_args);
+ grpc_channel_args_destroy(exec_ctx, new_args);
}
return true;
}
diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c
index 82042897b2..b1d3eb56a5 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ b/src/core/ext/client_channel/http_connect_handshaker.c
@@ -44,6 +44,7 @@
#include "src/core/lib/http/format_request.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/timer.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/support/env.h"
typedef struct http_connect_handshaker {
@@ -72,11 +73,12 @@ typedef struct http_connect_handshaker {
} http_connect_handshaker;
// Unref and clean up handshaker.
-static void http_connect_handshaker_unref(http_connect_handshaker* handshaker) {
+static void http_connect_handshaker_unref(grpc_exec_ctx* exec_ctx,
+ http_connect_handshaker* handshaker) {
if (gpr_unref(&handshaker->refcount)) {
gpr_free(handshaker->proxy_server);
gpr_free(handshaker->server_name);
- grpc_slice_buffer_destroy(&handshaker->write_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &handshaker->write_buffer);
grpc_http_parser_destroy(&handshaker->http_parser);
grpc_http_response_destroy(&handshaker->http_response);
gpr_free(handshaker);
@@ -89,7 +91,7 @@ static void on_timeout(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
if (error == GRPC_ERROR_NONE) { // Timer fired, rather than being cancelled.
grpc_endpoint_shutdown(exec_ctx, handshaker->endpoint);
}
- http_connect_handshaker_unref(handshaker);
+ http_connect_handshaker_unref(exec_ctx, handshaker);
}
// Callback invoked when finished writing HTTP CONNECT request.
@@ -142,7 +144,7 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
&handshaker->read_buffer->slices[i + 1],
handshaker->read_buffer->count - i - 1);
grpc_slice_buffer_swap(handshaker->read_buffer, &tmp_buffer);
- grpc_slice_buffer_destroy(&tmp_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &tmp_buffer);
break;
}
}
@@ -159,7 +161,8 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
// complete (e.g., handling chunked transfer encoding or looking
// at the Content-Length: header).
if (handshaker->http_parser.state != GRPC_HTTP_BODY) {
- grpc_slice_buffer_reset_and_unref(handshaker->read_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
+ handshaker->read_buffer);
grpc_endpoint_read(exec_ctx, handshaker->endpoint, handshaker->read_buffer,
&handshaker->response_read_closure);
return;
@@ -186,7 +189,7 @@ done:
static void http_connect_handshaker_destroy(grpc_exec_ctx* exec_ctx,
grpc_handshaker* handshaker_in) {
http_connect_handshaker* handshaker = (http_connect_handshaker*)handshaker_in;
- http_connect_handshaker_unref(handshaker);
+ http_connect_handshaker_unref(exec_ctx, handshaker);
}
static void http_connect_handshaker_shutdown(grpc_exec_ctx* exec_ctx,
diff --git a/src/core/ext/client_channel/lb_policy_factory.c b/src/core/ext/client_channel/lb_policy_factory.c
index 8a474c8818..7af9bb0411 100644
--- a/src/core/ext/client_channel/lb_policy_factory.c
+++ b/src/core/ext/client_channel/lb_policy_factory.c
@@ -112,11 +112,13 @@ int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1,
return 0;
}
-void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses) {
+void grpc_lb_addresses_destroy(grpc_exec_ctx* exec_ctx,
+ grpc_lb_addresses* addresses) {
for (size_t i = 0; i < addresses->num_addresses; ++i) {
gpr_free(addresses->addresses[i].balancer_name);
if (addresses->addresses[i].user_data != NULL) {
- addresses->user_data_vtable->destroy(addresses->addresses[i].user_data);
+ addresses->user_data_vtable->destroy(exec_ctx,
+ addresses->addresses[i].user_data);
}
}
gpr_free(addresses->addresses);
@@ -126,8 +128,8 @@ void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses) {
static void* lb_addresses_copy(void* addresses) {
return grpc_lb_addresses_copy(addresses);
}
-static void lb_addresses_destroy(void* addresses) {
- grpc_lb_addresses_destroy(addresses);
+static void lb_addresses_destroy(grpc_exec_ctx* exec_ctx, void* addresses) {
+ grpc_lb_addresses_destroy(exec_ctx, addresses);
}
static int lb_addresses_cmp(void* addresses1, void* addresses2) {
return grpc_lb_addresses_cmp(addresses1, addresses2);
diff --git a/src/core/ext/client_channel/lb_policy_factory.h b/src/core/ext/client_channel/lb_policy_factory.h
index e2b8080a32..ceee3efbc2 100644
--- a/src/core/ext/client_channel/lb_policy_factory.h
+++ b/src/core/ext/client_channel/lb_policy_factory.h
@@ -61,7 +61,7 @@ typedef struct grpc_lb_address {
typedef struct grpc_lb_user_data_vtable {
void *(*copy)(void *);
- void (*destroy)(void *);
+ void (*destroy)(grpc_exec_ctx *exec_ctx, void *);
int (*cmp)(void *, void *);
} grpc_lb_user_data_vtable;
@@ -93,7 +93,8 @@ int grpc_lb_addresses_cmp(const grpc_lb_addresses *addresses1,
const grpc_lb_addresses *addresses2);
/** Destroys \a addresses. */
-void grpc_lb_addresses_destroy(grpc_lb_addresses *addresses);
+void grpc_lb_addresses_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_lb_addresses *addresses);
/** Returns a channel arg containing \a addresses. */
grpc_arg grpc_lb_addresses_create_channel_arg(
diff --git a/src/core/ext/client_channel/resolver_factory.c b/src/core/ext/client_channel/resolver_factory.c
index 7c3d644257..00bbb92dd0 100644
--- a/src/core/ext/client_channel/resolver_factory.c
+++ b/src/core/ext/client_channel/resolver_factory.c
@@ -43,9 +43,10 @@ void grpc_resolver_factory_unref(grpc_resolver_factory* factory) {
/** Create a resolver instance for a name */
grpc_resolver* grpc_resolver_factory_create_resolver(
- grpc_resolver_factory* factory, grpc_resolver_args* args) {
+ grpc_exec_ctx* exec_ctx, grpc_resolver_factory* factory,
+ grpc_resolver_args* args) {
if (factory == NULL) return NULL;
- return factory->vtable->create_resolver(factory, args);
+ return factory->vtable->create_resolver(exec_ctx, factory, args);
}
char* grpc_resolver_factory_get_default_authority(
diff --git a/src/core/ext/client_channel/resolver_factory.h b/src/core/ext/client_channel/resolver_factory.h
index 4da42e84d2..76b1f45d80 100644
--- a/src/core/ext/client_channel/resolver_factory.h
+++ b/src/core/ext/client_channel/resolver_factory.h
@@ -55,7 +55,8 @@ struct grpc_resolver_factory_vtable {
void (*unref)(grpc_resolver_factory *factory);
/** Implementation of grpc_resolver_factory_create_resolver */
- grpc_resolver *(*create_resolver)(grpc_resolver_factory *factory,
+ grpc_resolver *(*create_resolver)(grpc_exec_ctx *exec_ctx,
+ grpc_resolver_factory *factory,
grpc_resolver_args *args);
/** Implementation of grpc_resolver_factory_get_default_authority */
@@ -70,7 +71,8 @@ void grpc_resolver_factory_unref(grpc_resolver_factory *resolver);
/** Create a resolver instance for a name */
grpc_resolver *grpc_resolver_factory_create_resolver(
- grpc_resolver_factory *factory, grpc_resolver_args *args);
+ grpc_exec_ctx *exec_ctx, grpc_resolver_factory *factory,
+ grpc_resolver_args *args);
/** Return a (freshly allocated with gpr_malloc) string representing
the default authority to use for this scheme. */
diff --git a/src/core/ext/client_channel/resolver_registry.c b/src/core/ext/client_channel/resolver_registry.c
index d0f0fc3f33..9feba14e58 100644
--- a/src/core/ext/client_channel/resolver_registry.c
+++ b/src/core/ext/client_channel/resolver_registry.c
@@ -131,7 +131,7 @@ static grpc_resolver_factory *resolve_factory(const char *target,
return factory;
}
-grpc_resolver *grpc_resolver_create(const char *target,
+grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target,
const grpc_channel_args *args) {
grpc_uri *uri = NULL;
grpc_resolver_factory *factory = resolve_factory(target, &uri);
@@ -140,7 +140,8 @@ grpc_resolver *grpc_resolver_create(const char *target,
memset(&resolver_args, 0, sizeof(resolver_args));
resolver_args.uri = uri;
resolver_args.args = args;
- resolver = grpc_resolver_factory_create_resolver(factory, &resolver_args);
+ resolver =
+ grpc_resolver_factory_create_resolver(exec_ctx, factory, &resolver_args);
grpc_uri_destroy(uri);
return resolver;
}
diff --git a/src/core/ext/client_channel/resolver_registry.h b/src/core/ext/client_channel/resolver_registry.h
index 2a95a669f0..4f6aba0ba5 100644
--- a/src/core/ext/client_channel/resolver_registry.h
+++ b/src/core/ext/client_channel/resolver_registry.h
@@ -60,7 +60,7 @@ void grpc_register_resolver_type(grpc_resolver_factory *factory);
If a resolver factory was not found, return NULL.
\a args is a set of channel arguments to be included in the result
(typically the set of arguments passed in from the client API). */
-grpc_resolver *grpc_resolver_create(const char *target,
+grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target,
const grpc_channel_args *args);
/** Find a resolver factory given a name and return an (owned-by-the-caller)
diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
index a148b2a0e1..063b79cece 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/client_channel/subchannel.c
@@ -46,6 +46,7 @@
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/support/backoff.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/channel_init.h"
@@ -204,9 +205,9 @@ static void subchannel_destroy(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
grpc_subchannel *c = arg;
gpr_free((void *)c->filters);
- grpc_channel_args_destroy(c->args);
+ grpc_channel_args_destroy(exec_ctx, c->args);
gpr_free(c->addr);
- grpc_slice_unref(c->initial_connect_string);
+ grpc_slice_unref_internal(exec_ctx, c->initial_connect_string);
grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker);
grpc_connector_unref(exec_ctx, c->connector);
grpc_pollset_set_destroy(c->pollset_set);
@@ -538,7 +539,7 @@ static void publish_transport_locked(grpc_exec_ctx *exec_ctx,
/* construct channel stack */
grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create();
grpc_channel_stack_builder_set_channel_arguments(
- builder, c->connecting_result.channel_args);
+ exec_ctx, builder, c->connecting_result.channel_args);
grpc_channel_stack_builder_set_transport(builder,
c->connecting_result.transport);
@@ -547,7 +548,7 @@ static void publish_transport_locked(grpc_exec_ctx *exec_ctx,
con = grpc_channel_stack_builder_finish(exec_ctx, builder, 0, 1,
connection_destroy, NULL);
} else {
- grpc_channel_stack_builder_destroy(builder);
+ grpc_channel_stack_builder_destroy(exec_ctx, builder);
abort(); /* TODO(ctiller): what to do here (previously we just crashed) */
}
stk = CHANNEL_STACK_FROM_CONNECTION(con);
@@ -650,7 +651,7 @@ static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *arg,
}
gpr_mu_unlock(&c->mu);
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
- grpc_channel_args_destroy(delete_channel_args);
+ grpc_channel_args_destroy(exec_ctx, delete_channel_args);
}
/*
@@ -702,7 +703,7 @@ grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel(
grpc_error *grpc_connected_subchannel_create_call(
grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con,
- grpc_polling_entity *pollent, grpc_mdstr *path, gpr_timespec start_time,
+ grpc_polling_entity *pollent, grpc_slice path, gpr_timespec start_time,
gpr_timespec deadline, grpc_subchannel_call **call) {
grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con);
*call = gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size);
diff --git a/src/core/ext/client_channel/subchannel.h b/src/core/ext/client_channel/subchannel.h
index 10bae620df..e7a5bb4bbd 100644
--- a/src/core/ext/client_channel/subchannel.h
+++ b/src/core/ext/client_channel/subchannel.h
@@ -111,7 +111,7 @@ void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx,
/** construct a subchannel call */
grpc_error *grpc_connected_subchannel_create_call(
grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel,
- grpc_polling_entity *pollent, grpc_mdstr *path, gpr_timespec start_time,
+ grpc_polling_entity *pollent, grpc_slice path, gpr_timespec start_time,
gpr_timespec deadline, grpc_subchannel_call **subchannel_call);
/** process a transport level op */
diff --git a/src/core/ext/client_channel/subchannel_index.c b/src/core/ext/client_channel/subchannel_index.c
index 227013a7d7..25fdfcf3d4 100644
--- a/src/core/ext/client_channel/subchannel_index.c
+++ b/src/core/ext/client_channel/subchannel_index.c
@@ -131,7 +131,7 @@ void grpc_subchannel_key_destroy(grpc_exec_ctx *exec_ctx,
grpc_subchannel_key *k) {
grpc_connector_unref(exec_ctx, k->connector);
gpr_free((grpc_channel_args *)k->args.filters);
- grpc_channel_args_destroy((grpc_channel_args *)k->args.args);
+ grpc_channel_args_destroy(exec_ctx, (grpc_channel_args *)k->args.args);
gpr_free((void *)k->args.server_name);
gpr_free(k->args.addr);
gpr_free(k);
diff --git a/src/core/ext/client_channel/uri_parser.c b/src/core/ext/client_channel/uri_parser.c
index 0fbc542ef8..f8c946b275 100644
--- a/src/core/ext/client_channel/uri_parser.c
+++ b/src/core/ext/client_channel/uri_parser.c
@@ -42,7 +42,6 @@
#include <grpc/support/port_platform.h>
#include <grpc/support/string_util.h>
-#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
/** a size_t default value... maps to all 1's */
@@ -138,7 +137,6 @@ static int parse_fragment_or_query(const char *uri_text, size_t *i) {
return 1;
}
-static void do_nothing(void *ignored) {}
static void parse_query_parts(grpc_uri *uri) {
static const char *QUERY_PARTS_SEPARATOR = "&";
static const char *QUERY_PARTS_VALUE_SEPARATOR = "=";
@@ -149,38 +147,32 @@ static void parse_query_parts(grpc_uri *uri) {
uri->num_query_parts = 0;
return;
}
- grpc_slice query_slice =
- grpc_slice_new(uri->query, strlen(uri->query), do_nothing);
- grpc_slice_buffer query_parts; /* the &-separated elements of the query */
- grpc_slice_buffer query_param_parts; /* the =-separated subelements */
- grpc_slice_buffer_init(&query_parts);
- grpc_slice_buffer_init(&query_param_parts);
-
- grpc_slice_split(query_slice, QUERY_PARTS_SEPARATOR, &query_parts);
- uri->query_parts = gpr_malloc(query_parts.count * sizeof(char *));
- uri->query_parts_values = gpr_malloc(query_parts.count * sizeof(char *));
- uri->num_query_parts = query_parts.count;
- for (size_t i = 0; i < query_parts.count; i++) {
- grpc_slice_split(query_parts.slices[i], QUERY_PARTS_VALUE_SEPARATOR,
- &query_param_parts);
- GPR_ASSERT(query_param_parts.count > 0);
- uri->query_parts[i] =
- grpc_dump_slice(query_param_parts.slices[0], GPR_DUMP_ASCII);
- if (query_param_parts.count > 1) {
+ gpr_string_split(uri->query, QUERY_PARTS_SEPARATOR, &uri->query_parts,
+ &uri->num_query_parts);
+ uri->query_parts_values = gpr_malloc(uri->num_query_parts * sizeof(char **));
+ for (size_t i = 0; i < uri->num_query_parts; i++) {
+ char **query_param_parts;
+ size_t num_query_param_parts;
+ char *full = uri->query_parts[i];
+ gpr_string_split(full, QUERY_PARTS_VALUE_SEPARATOR, &query_param_parts,
+ &num_query_param_parts);
+ GPR_ASSERT(num_query_param_parts > 0);
+ uri->query_parts[i] = query_param_parts[0];
+ if (num_query_param_parts > 1) {
/* TODO(dgq): only the first value after the separator is considered.
* Perhaps all chars after the first separator for the query part should
* be included, even if they include the separator. */
- uri->query_parts_values[i] =
- grpc_dump_slice(query_param_parts.slices[1], GPR_DUMP_ASCII);
+ uri->query_parts_values[i] = query_param_parts[1];
} else {
uri->query_parts_values[i] = NULL;
}
- grpc_slice_buffer_reset_and_unref(&query_param_parts);
+ for (size_t j = 2; j < num_query_param_parts; j++) {
+ gpr_free(query_param_parts[j]);
+ }
+ gpr_free(query_param_parts);
+ gpr_free(full);
}
- grpc_slice_buffer_destroy(&query_parts);
- grpc_slice_buffer_destroy(&query_param_parts);
- grpc_slice_unref(query_slice);
}
grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) {
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index 0829e05b43..ebb3f8044b 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -116,6 +116,7 @@
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/timer.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/backoff.h"
#include "src/core/lib/support/string.h"
@@ -134,9 +135,9 @@ int grpc_lb_glb_trace = 0;
* metadata */
static void initial_metadata_add_lb_token(
grpc_metadata_batch *initial_metadata,
- grpc_linked_mdelem *lb_token_mdelem_storage, grpc_mdelem *lb_token) {
+ grpc_linked_mdelem *lb_token_mdelem_storage, grpc_mdelem lb_token) {
GPR_ASSERT(lb_token_mdelem_storage != NULL);
- GPR_ASSERT(lb_token != NULL);
+ GPR_ASSERT(!GRPC_MDISNULL(lb_token));
grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage,
lb_token);
}
@@ -158,7 +159,7 @@ typedef struct wrapped_rr_closure_arg {
grpc_connected_subchannel **target;
/* the LB token associated with the pick */
- grpc_mdelem *lb_token;
+ grpc_mdelem lb_token;
/* storage for the lb token initial metadata mdelem */
grpc_linked_mdelem *lb_token_mdelem_storage;
@@ -186,7 +187,7 @@ static void wrapped_rr_closure(grpc_exec_ctx *exec_ctx, void *arg,
* addresses failed to connect). There won't be any user_data/token
* available */
if (wc_arg->target != NULL) {
- if (wc_arg->lb_token != NULL) {
+ if (!GRPC_MDISNULL(wc_arg->lb_token)) {
initial_metadata_add_lb_token(wc_arg->initial_metadata,
wc_arg->lb_token_mdelem_storage,
GRPC_MDELEM_REF(wc_arg->lb_token));
@@ -338,8 +339,7 @@ typedef struct glb_lb_policy {
/* call status code and details, set in lb_on_server_status_received() */
grpc_status_code lb_call_status;
- char *lb_call_status_details;
- size_t lb_call_status_details_capacity;
+ grpc_slice lb_call_status_details;
/** LB call retry backoff state */
gpr_backoff lb_call_backoff_state;
@@ -381,10 +381,14 @@ static bool is_server_valid(const grpc_grpclb_server *server, size_t idx,
/* vtable for LB tokens in grpc_lb_addresses. */
static void *lb_token_copy(void *token) {
- return token == NULL ? NULL : GRPC_MDELEM_REF(token);
+ return token == NULL
+ ? NULL
+ : (void *)GRPC_MDELEM_REF((grpc_mdelem){(uintptr_t)token}).payload;
}
-static void lb_token_destroy(void *token) {
- if (token != NULL) GRPC_MDELEM_UNREF(token);
+static void lb_token_destroy(grpc_exec_ctx *exec_ctx, void *token) {
+ if (token != NULL) {
+ GRPC_MDELEM_UNREF(exec_ctx, (grpc_mdelem){(uintptr_t)token});
+ }
}
static int lb_token_cmp(void *token1, void *token2) {
if (token1 > token2) return 1;
@@ -418,7 +422,7 @@ static void parse_server(const grpc_grpclb_server *server,
/* Returns addresses extracted from \a serverlist. */
static grpc_lb_addresses *process_serverlist_locked(
- const grpc_grpclb_serverlist *serverlist) {
+ grpc_exec_ctx *exec_ctx, const grpc_grpclb_serverlist *serverlist) {
size_t num_valid = 0;
/* first pass: count how many are valid in order to allocate the necessary
* memory in a single block */
@@ -452,10 +456,11 @@ static grpc_lb_addresses *process_serverlist_locked(
GPR_ARRAY_SIZE(server->load_balance_token);
const size_t lb_token_length =
strnlen(server->load_balance_token, lb_token_max_length);
- grpc_mdstr *lb_token_mdstr = grpc_mdstr_from_buffer(
- (uint8_t *)server->load_balance_token, lb_token_length);
- user_data = grpc_mdelem_from_metadata_strings(GRPC_MDSTR_LB_TOKEN,
- lb_token_mdstr);
+ grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer(
+ server->load_balance_token, lb_token_length);
+ user_data = (void *)grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_LB_TOKEN,
+ lb_token_mdstr)
+ .payload;
} else {
char *uri = grpc_sockaddr_to_uri(&addr);
gpr_log(GPR_INFO,
@@ -463,7 +468,7 @@ static grpc_lb_addresses *process_serverlist_locked(
"be used instead",
uri);
gpr_free(uri);
- user_data = GRPC_MDELEM_LB_TOKEN_EMPTY;
+ user_data = (void *)GRPC_MDELEM_LB_TOKEN_EMPTY.payload;
}
grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len,
@@ -578,7 +583,8 @@ static grpc_lb_policy *create_rr_locked(
grpc_lb_policy_args args;
memset(&args, 0, sizeof(args));
args.client_channel_factory = glb_policy->cc_factory;
- grpc_lb_addresses *addresses = process_serverlist_locked(serverlist);
+ grpc_lb_addresses *addresses =
+ process_serverlist_locked(exec_ctx, serverlist);
// Replace the LB addresses in the channel args that we pass down to
// the subchannel.
@@ -590,8 +596,8 @@ static grpc_lb_policy *create_rr_locked(
grpc_lb_policy *rr = grpc_lb_policy_create(exec_ctx, "round_robin", &args);
GPR_ASSERT(rr != NULL);
- grpc_lb_addresses_destroy(addresses);
- grpc_channel_args_destroy(args.args);
+ grpc_lb_addresses_destroy(exec_ctx, addresses);
+ grpc_channel_args_destroy(exec_ctx, args.args);
return rr;
}
@@ -825,7 +831,7 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
glb_policy->lb_channel = grpc_client_channel_factory_create_channel(
exec_ctx, glb_policy->cc_factory, target_uri_str,
GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, new_args);
- grpc_channel_args_destroy(new_args);
+ grpc_channel_args_destroy(exec_ctx, new_args);
gpr_free(target_uri_str);
for (size_t i = 0; i < num_grpclb_addrs; i++) {
@@ -851,7 +857,7 @@ static void glb_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
GPR_ASSERT(glb_policy->pending_picks == NULL);
GPR_ASSERT(glb_policy->pending_pings == NULL);
gpr_free((void *)glb_policy->server_name);
- grpc_channel_args_destroy(glb_policy->args);
+ grpc_channel_args_destroy(exec_ctx, glb_policy->args);
grpc_channel_destroy(glb_policy->lb_channel);
glb_policy->lb_channel = NULL;
grpc_connectivity_state_destroy(exec_ctx, &glb_policy->state_tracker);
@@ -1074,7 +1080,8 @@ static void lb_on_server_status_received(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error);
static void lb_on_response_received(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error);
-static void lb_call_init_locked(glb_lb_policy *glb_policy) {
+static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
+ glb_lb_policy *glb_policy) {
GPR_ASSERT(glb_policy->server_name != NULL);
GPR_ASSERT(glb_policy->server_name[0] != '\0');
GPR_ASSERT(!glb_policy->shutting_down);
@@ -1082,11 +1089,12 @@ static void lb_call_init_locked(glb_lb_policy *glb_policy) {
/* Note the following LB call progresses every time there's activity in \a
* glb_policy->base.interested_parties, which is comprised of the polling
* entities from \a client_channel. */
+ grpc_slice host = grpc_slice_from_copied_string(glb_policy->server_name);
glb_policy->lb_call = grpc_channel_create_pollset_set_call(
- glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
+ exec_ctx, glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
glb_policy->base.interested_parties,
- "/grpc.lb.v1.LoadBalancer/BalanceLoad", glb_policy->server_name,
- glb_policy->deadline, NULL);
+ GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD,
+ &host, glb_policy->deadline, NULL);
grpc_metadata_array_init(&glb_policy->lb_initial_metadata_recv);
grpc_metadata_array_init(&glb_policy->lb_trailing_metadata_recv);
@@ -1096,12 +1104,9 @@ static void lb_call_init_locked(glb_lb_policy *glb_policy) {
grpc_slice request_payload_slice = grpc_grpclb_request_encode(request);
glb_policy->lb_request_payload =
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
- grpc_slice_unref(request_payload_slice);
+ grpc_slice_unref_internal(exec_ctx, request_payload_slice);
grpc_grpclb_request_destroy(request);
- glb_policy->lb_call_status_details = NULL;
- glb_policy->lb_call_status_details_capacity = 0;
-
grpc_closure_init(&glb_policy->lb_on_server_status_received,
lb_on_server_status_received, glb_policy);
grpc_closure_init(&glb_policy->lb_on_response_received,
@@ -1112,7 +1117,8 @@ static void lb_call_init_locked(glb_lb_policy *glb_policy) {
BACKOFF_MAX_SECONDS * 1000);
}
-static void lb_call_destroy_locked(glb_lb_policy *glb_policy) {
+static void lb_call_destroy_locked(grpc_exec_ctx *exec_ctx,
+ glb_lb_policy *glb_policy) {
GPR_ASSERT(glb_policy->lb_call != NULL);
grpc_call_destroy(glb_policy->lb_call);
glb_policy->lb_call = NULL;
@@ -1121,7 +1127,7 @@ static void lb_call_destroy_locked(glb_lb_policy *glb_policy) {
grpc_metadata_array_destroy(&glb_policy->lb_trailing_metadata_recv);
grpc_byte_buffer_destroy(glb_policy->lb_request_payload);
- gpr_free(glb_policy->lb_call_status_details);
+ grpc_slice_unref_internal(exec_ctx, glb_policy->lb_call_status_details);
}
/*
@@ -1132,7 +1138,7 @@ static void query_for_backends_locked(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(glb_policy->lb_channel != NULL);
if (glb_policy->shutting_down) return;
- lb_call_init_locked(glb_policy);
+ lb_call_init_locked(exec_ctx, glb_policy);
if (grpc_lb_glb_trace) {
gpr_log(GPR_INFO, "Query for backends (grpclb: %p, lb_call: %p)",
@@ -1170,8 +1176,6 @@ static void query_for_backends_locked(grpc_exec_ctx *exec_ctx,
op->data.recv_status_on_client.status = &glb_policy->lb_call_status;
op->data.recv_status_on_client.status_details =
&glb_policy->lb_call_status_details;
- op->data.recv_status_on_client.status_details_capacity =
- &glb_policy->lb_call_status_details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -1217,7 +1221,7 @@ static void lb_on_response_received(grpc_exec_ctx *exec_ctx, void *arg,
grpc_grpclb_response_parse_serverlist(response_slice);
if (serverlist != NULL) {
GPR_ASSERT(glb_policy->lb_call != NULL);
- grpc_slice_unref(response_slice);
+ grpc_slice_unref_internal(exec_ctx, response_slice);
if (grpc_lb_glb_trace) {
gpr_log(GPR_INFO, "Serverlist with %lu servers received",
(unsigned long)serverlist->num_servers);
@@ -1258,7 +1262,7 @@ static void lb_on_response_received(grpc_exec_ctx *exec_ctx, void *arg,
} else { /* serverlist == NULL */
gpr_log(GPR_ERROR, "Invalid LB response received: '%s'. Ignoring.",
grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX));
- grpc_slice_unref(response_slice);
+ grpc_slice_unref_internal(exec_ctx, response_slice);
}
if (!glb_policy->shutting_down) {
@@ -1311,15 +1315,18 @@ static void lb_on_server_status_received(grpc_exec_ctx *exec_ctx, void *arg,
GPR_ASSERT(glb_policy->lb_call != NULL);
if (grpc_lb_glb_trace) {
+ char *status_details =
+ grpc_dump_slice(glb_policy->lb_call_status_details, GPR_DUMP_ASCII);
gpr_log(GPR_DEBUG,
"Status from LB server received. Status = %d, Details = '%s', "
"(call: %p)",
- glb_policy->lb_call_status, glb_policy->lb_call_status_details,
+ glb_policy->lb_call_status, status_details,
(void *)glb_policy->lb_call);
+ gpr_free(status_details);
}
- /* We need to performe cleanups no matter what. */
- lb_call_destroy_locked(glb_policy);
+ /* We need to perform cleanups no matter what. */
+ lb_call_destroy_locked(exec_ctx, glb_policy);
if (!glb_policy->shutting_down) {
/* if we aren't shutting down, restart the LB client call after some time */
diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/lb_policy/round_robin/round_robin.c
index 59f84054c4..f93dd078ce 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/lb_policy/round_robin/round_robin.c
@@ -284,7 +284,7 @@ static void rr_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, "rr_destroy");
if (sd->user_data != NULL) {
GPR_ASSERT(sd->user_data_vtable != NULL);
- sd->user_data_vtable->destroy(sd->user_data);
+ sd->user_data_vtable->destroy(exec_ctx, sd->user_data);
}
gpr_free(sd);
}
diff --git a/src/core/ext/load_reporting/load_reporting.c b/src/core/ext/load_reporting/load_reporting.c
index df1ea0ec9a..37b06a737f 100644
--- a/src/core/ext/load_reporting/load_reporting.c
+++ b/src/core/ext/load_reporting/load_reporting.c
@@ -53,7 +53,8 @@ static bool is_load_reporting_enabled(const grpc_channel_args *a) {
return false;
}
-static bool maybe_add_load_reporting_filter(grpc_channel_stack_builder *builder,
+static bool maybe_add_load_reporting_filter(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder,
void *arg) {
const grpc_channel_args *args =
grpc_channel_stack_builder_get_channel_arguments(builder);
diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c
index b810e20bb9..5d3b4c4207 100644
--- a/src/core/ext/load_reporting/load_reporting_filter.c
+++ b/src/core/ext/load_reporting/load_reporting_filter.c
@@ -41,13 +41,17 @@
#include "src/core/ext/load_reporting/load_reporting_filter.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/static_metadata.h"
typedef struct call_data {
intptr_t id; /**< an id unique to the call */
- char *trailing_md_string;
- char *initial_md_string;
- const char *service_method;
+ bool have_trailing_md_string;
+ grpc_slice trailing_md_string;
+ bool have_initial_md_string;
+ grpc_slice initial_md_string;
+ bool have_service_method;
+ grpc_slice service_method;
/* stores the recv_initial_metadata op's ready closure, which we wrap with our
* own (on_initial_md_ready) in order to capture the incoming initial metadata
@@ -68,16 +72,19 @@ typedef struct {
grpc_exec_ctx *exec_ctx;
} recv_md_filter_args;
-static grpc_mdelem *recv_md_filter(void *user_data, grpc_mdelem *md) {
+static grpc_mdelem recv_md_filter(grpc_exec_ctx *exec_ctx, void *user_data,
+ grpc_mdelem md) {
recv_md_filter_args *a = user_data;
grpc_call_element *elem = a->elem;
call_data *calld = elem->call_data;
- if (md->key == GRPC_MDSTR_PATH) {
- calld->service_method = grpc_mdstr_as_c_string(md->value);
- } else if (md->key == GRPC_MDSTR_LB_TOKEN) {
- calld->initial_md_string = gpr_strdup(grpc_mdstr_as_c_string(md->value));
- return NULL;
+ if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_PATH) == 0) {
+ calld->service_method = grpc_slice_ref_internal(GRPC_MDVALUE(md));
+ calld->have_service_method = true;
+ } else if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_LB_TOKEN) == 0) {
+ calld->initial_md_string = grpc_slice_ref_internal(GRPC_MDVALUE(md));
+ calld->have_initial_md_string = true;
+ return GRPC_MDNULL;
}
return md;
@@ -92,9 +99,9 @@ static void on_initial_md_ready(grpc_exec_ctx *exec_ctx, void *user_data,
recv_md_filter_args a;
a.elem = elem;
a.exec_ctx = exec_ctx;
- grpc_metadata_batch_filter(calld->recv_initial_metadata, recv_md_filter,
- &a);
- if (calld->service_method == NULL) {
+ grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata,
+ recv_md_filter, &a);
+ if (!calld->have_service_method) {
err =
grpc_error_add_child(err, GRPC_ERROR_CREATE("Missing :path header"));
}
@@ -147,8 +154,8 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
calld->service_method};
*/
- gpr_free(calld->initial_md_string);
- gpr_free(calld->trailing_md_string);
+ grpc_slice_unref_internal(exec_ctx, calld->initial_md_string);
+ grpc_slice_unref_internal(exec_ctx, calld->trailing_md_string);
}
/* Constructor for channel_data */
@@ -189,13 +196,15 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
*/
}
-static grpc_mdelem *lr_trailing_md_filter(void *user_data, grpc_mdelem *md) {
+static grpc_mdelem lr_trailing_md_filter(grpc_exec_ctx *exec_ctx,
+ void *user_data, grpc_mdelem md) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
- if (md->key == GRPC_MDSTR_LB_COST_BIN) {
- calld->trailing_md_string = gpr_strdup(grpc_mdstr_as_c_string(md->value));
- return NULL;
+ if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_LB_COST_BIN) == 0) {
+ calld->trailing_md_string = grpc_slice_ref_internal(GRPC_MDVALUE(md));
+ calld->have_trailing_md_string = true;
+ return GRPC_MDNULL;
}
return md;
@@ -213,7 +222,7 @@ static void lr_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
calld->ops_recv_initial_metadata_ready = op->recv_initial_metadata_ready;
op->recv_initial_metadata_ready = &calld->on_initial_md_ready;
} else if (op->send_trailing_metadata) {
- grpc_metadata_batch_filter(op->send_trailing_metadata,
+ grpc_metadata_batch_filter(exec_ctx, op->send_trailing_metadata,
lr_trailing_md_filter, elem);
}
grpc_call_next_op(exec_ctx, elem, op);
diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c
index 665439f360..052bfd4bcc 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/resolver/dns/native/dns_resolver.c
@@ -179,7 +179,7 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses);
result = grpc_channel_args_copy_and_add(r->channel_args, &new_arg, 1);
grpc_resolved_addresses_destroy(r->addresses);
- grpc_lb_addresses_destroy(addresses);
+ grpc_lb_addresses_destroy(exec_ctx, addresses);
} else {
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
gpr_timespec next_try = gpr_backoff_step(&r->backoff_state, now);
@@ -200,7 +200,7 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
now);
}
if (r->resolved_result != NULL) {
- grpc_channel_args_destroy(r->resolved_result);
+ grpc_channel_args_destroy(exec_ctx, r->resolved_result);
}
r->resolved_result = result;
r->resolved_version++;
@@ -237,11 +237,11 @@ static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
dns_resolver *r = (dns_resolver *)gr;
gpr_mu_destroy(&r->mu);
if (r->resolved_result != NULL) {
- grpc_channel_args_destroy(r->resolved_result);
+ grpc_channel_args_destroy(exec_ctx, r->resolved_result);
}
gpr_free(r->name_to_resolve);
gpr_free(r->default_port);
- grpc_channel_args_destroy(r->channel_args);
+ grpc_channel_args_destroy(exec_ctx, r->channel_args);
gpr_free(r);
}
@@ -283,7 +283,8 @@ static void dns_factory_ref(grpc_resolver_factory *factory) {}
static void dns_factory_unref(grpc_resolver_factory *factory) {}
static grpc_resolver *dns_factory_create_resolver(
- grpc_resolver_factory *factory, grpc_resolver_args *args) {
+ grpc_exec_ctx *exec_ctx, grpc_resolver_factory *factory,
+ grpc_resolver_args *args) {
return dns_create(args, "https");
}
diff --git a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
index 26a650aadd..55f8c071f2 100644
--- a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
+++ b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
@@ -47,6 +47,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
@@ -131,8 +132,8 @@ static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
sockaddr_resolver *r = (sockaddr_resolver *)gr;
gpr_mu_destroy(&r->mu);
- grpc_lb_addresses_destroy(r->addresses);
- grpc_channel_args_destroy(r->channel_args);
+ grpc_lb_addresses_destroy(exec_ctx, r->addresses);
+ grpc_channel_args_destroy(exec_ctx, r->channel_args);
gpr_free(r);
}
@@ -161,7 +162,8 @@ char *unix_get_default_authority(grpc_resolver_factory *factory,
static void do_nothing(void *ignored) {}
-static grpc_resolver *sockaddr_create(grpc_resolver_args *args,
+static grpc_resolver *sockaddr_create(grpc_exec_ctx *exec_ctx,
+ grpc_resolver_args *args,
int parse(grpc_uri *uri,
grpc_resolved_address *dst)) {
if (0 != strcmp(args->uri->authority, "")) {
@@ -188,10 +190,10 @@ static grpc_resolver *sockaddr_create(grpc_resolver_args *args,
gpr_free(part_str);
if (errors_found) break;
}
- grpc_slice_buffer_destroy(&path_parts);
- grpc_slice_unref(path_slice);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &path_parts);
+ grpc_slice_unref_internal(exec_ctx, path_slice);
if (errors_found) {
- grpc_lb_addresses_destroy(addresses);
+ grpc_lb_addresses_destroy(exec_ctx, addresses);
return NULL;
}
/* Instantiate resolver. */
@@ -219,8 +221,9 @@ static void sockaddr_factory_unref(grpc_resolver_factory *factory) {}
#define DECL_FACTORY(name) \
static grpc_resolver *name##_factory_create_resolver( \
- grpc_resolver_factory *factory, grpc_resolver_args *args) { \
- return sockaddr_create(args, parse_##name); \
+ grpc_exec_ctx *exec_ctx, grpc_resolver_factory *factory, \
+ grpc_resolver_args *args) { \
+ return sockaddr_create(exec_ctx, args, parse_##name); \
} \
static const grpc_resolver_factory_vtable name##_factory_vtable = { \
sockaddr_factory_ref, sockaddr_factory_unref, \
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
index 8e03fd82c1..ad1dd29241 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -98,7 +98,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
grpc_error *error) {
connector *c = user_data;
if (error != GRPC_ERROR_NONE) {
- grpc_channel_args_destroy(args);
+ grpc_channel_args_destroy(exec_ctx, args);
gpr_free(read_buffer);
} else {
c->result->transport =
@@ -197,7 +197,7 @@ static grpc_channel *client_channel_factory_create_channel(
const grpc_channel_args *args) {
grpc_channel *channel =
grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
- grpc_resolver *resolver = grpc_resolver_create(target, args);
+ grpc_resolver *resolver = grpc_resolver_create(exec_ctx, target, args);
if (!resolver) {
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
"client_channel_factory_create_channel");
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
index 1e5b1c22e3..f1069e2c57 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
@@ -74,7 +74,7 @@ grpc_channel *grpc_insecure_channel_create_from_fd(
GPR_ASSERT(transport);
grpc_channel *channel = grpc_channel_create(
&exec_ctx, target, final_args, GRPC_CLIENT_DIRECT_CHANNEL, transport);
- grpc_channel_args_destroy(final_args);
+ grpc_channel_args_destroy(&exec_ctx, final_args);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL);
grpc_exec_ctx_finish(&exec_ctx);
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
index 04c88a2d36..92e7fb17f9 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
@@ -91,7 +91,7 @@ static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) {
connector *c = (connector *)con;
if (gpr_unref(&c->refs)) {
/* c->initial_string_buffer does not need to be destroyed */
- grpc_channel_args_destroy(c->tmp_args);
+ grpc_channel_args_destroy(exec_ctx, c->tmp_args);
grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr);
gpr_free(c);
}
@@ -240,7 +240,7 @@ static void client_channel_factory_unref(
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) {
client_channel_factory *f = (client_channel_factory *)cc_factory;
if (gpr_unref(&f->refs)) {
- GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
+ GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &f->security_connector->base,
"client_channel_factory");
gpr_free(f);
}
@@ -276,7 +276,7 @@ static grpc_channel *client_channel_factory_create_channel(
client_channel_factory *f = (client_channel_factory *)cc_factory;
grpc_channel *channel =
grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
- grpc_resolver *resolver = grpc_resolver_create(target, args);
+ grpc_resolver *resolver = grpc_resolver_create(exec_ctx, target, args);
if (resolver != NULL) {
grpc_client_channel_finish_initialization(
exec_ctx, grpc_channel_get_channel_stack(channel), resolver, &f->base);
@@ -320,8 +320,8 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
grpc_channel_security_connector *security_connector;
grpc_channel_args *new_args_from_connector;
if (grpc_channel_credentials_create_security_connector(
- creds, target, args, &security_connector, &new_args_from_connector) !=
- GRPC_SECURITY_OK) {
+ &exec_ctx, creds, target, args, &security_connector,
+ &new_args_from_connector) != GRPC_SECURITY_OK) {
grpc_exec_ctx_finish(&exec_ctx);
return grpc_lame_client_channel_create(
target, GRPC_STATUS_INTERNAL, "Failed to create security connector.");
@@ -332,7 +332,7 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
new_args_from_connector != NULL ? new_args_from_connector : args,
&connector_arg, 1);
if (new_args_from_connector != NULL) {
- grpc_channel_args_destroy(new_args_from_connector);
+ grpc_channel_args_destroy(&exec_ctx, new_args_from_connector);
}
// Create client channel factory.
client_channel_factory *f = gpr_malloc(sizeof(*f));
@@ -346,9 +346,9 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
grpc_channel *channel = client_channel_factory_create_channel(
&exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args);
// Clean up.
- GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
+ GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &f->security_connector->base,
"secure_client_channel_factory_create_channel");
- grpc_channel_args_destroy(new_args);
+ grpc_channel_args_destroy(&exec_ctx, new_args);
grpc_client_channel_factory_unref(&exec_ctx, &f->base);
grpc_exec_ctx_finish(&exec_ctx);
return channel; /* may be NULL */
diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
index c18d618f96..ce7cd7586b 100644
--- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
+++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
@@ -80,7 +80,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
grpc_chttp2_transport_start_reading(exec_ctx, transport, read_buffer);
}
// Clean up.
- grpc_channel_args_destroy(args);
+ grpc_channel_args_destroy(exec_ctx, args);
grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr);
gpr_free(state);
}
diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
index aa2ecf5743..f46e849932 100644
--- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
+++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
@@ -62,7 +62,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server *server,
grpc_endpoint *server_endpoint =
grpc_tcp_create(grpc_fd_create(fd, name), resource_quota,
GRPC_TCP_DEFAULT_READ_SLICE_SIZE, name);
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
gpr_free(name);
diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
index 942638ad7f..6293e06b69 100644
--- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
+++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
@@ -98,7 +98,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
grpc_server_setup_transport(
exec_ctx, connection_state->server_state->server, transport,
connection_state->accepting_pollset, args_copy);
- grpc_channel_args_destroy(args_copy);
+ grpc_channel_args_destroy(exec_ctx, args_copy);
grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL);
} else {
/* We need to consume this here, because the server may already have
@@ -110,7 +110,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
} else {
gpr_log(GPR_ERROR, "Secure transport failed with error %d", status);
}
- grpc_channel_args_destroy(connection_state->args);
+ grpc_channel_args_destroy(exec_ctx, connection_state->args);
grpc_tcp_server_unref(exec_ctx, connection_state->server_state->tcp);
gpr_free(connection_state);
}
@@ -125,7 +125,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str);
grpc_error_free_string(error_str);
GRPC_ERROR_UNREF(error);
- grpc_channel_args_destroy(args);
+ grpc_channel_args_destroy(exec_ctx, args);
gpr_free(read_buffer);
grpc_handshake_manager_shutdown(exec_ctx, connection_state->handshake_mgr);
grpc_handshake_manager_destroy(exec_ctx, connection_state->handshake_mgr);
@@ -199,8 +199,8 @@ static void tcp_server_shutdown_complete(grpc_exec_ctx *exec_ctx, void *statep,
/* Flush queued work before a synchronous unref. */
grpc_exec_ctx_flush(exec_ctx);
- GRPC_SECURITY_CONNECTOR_UNREF(&server_state->sc->base, "server");
- grpc_server_credentials_unref(server_state->creds);
+ GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &server_state->sc->base, "server");
+ grpc_server_credentials_unref(exec_ctx, server_state->creds);
if (destroy_done != NULL) {
destroy_done->cb(exec_ctx, destroy_done->cb_arg, GRPC_ERROR_REF(error));
@@ -249,7 +249,8 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
"No credentials specified for secure server port (creds==NULL)");
goto error;
}
- status = grpc_server_credentials_create_security_connector(creds, &sc);
+ status =
+ grpc_server_credentials_create_security_connector(&exec_ctx, creds, &sc);
if (status != GRPC_SECURITY_OK) {
char *msg;
gpr_asprintf(&msg,
@@ -349,7 +350,7 @@ error:
} else {
if (sc) {
grpc_exec_ctx_flush(&exec_ctx);
- GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "server");
+ GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &sc->base, "server");
}
if (server_state) {
gpr_free(server_state);
diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.c b/src/core/ext/transport/chttp2/transport/bin_decoder.c
index 3eef80b557..1a3637a1e3 100644
--- a/src/core/ext/transport/chttp2/transport/bin_decoder.c
+++ b/src/core/ext/transport/chttp2/transport/bin_decoder.c
@@ -34,6 +34,7 @@
#include "src/core/ext/transport/chttp2/transport/bin_decoder.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
@@ -143,7 +144,8 @@ bool grpc_base64_decode_partial(struct grpc_base64_decode_context *ctx) {
return true;
}
-grpc_slice grpc_chttp2_base64_decode(grpc_slice input) {
+grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx *exec_ctx,
+ grpc_slice input) {
size_t input_length = GRPC_SLICE_LENGTH(input);
size_t output_length = input_length / 4 * 3;
struct grpc_base64_decode_context ctx;
@@ -155,7 +157,7 @@ grpc_slice grpc_chttp2_base64_decode(grpc_slice input) {
"grpc_chttp2_base64_decode has a length of %d, which is not a "
"multiple of 4.\n",
(int)input_length);
- return gpr_empty_slice();
+ return grpc_empty_slice();
}
if (input_length > 0) {
@@ -179,15 +181,16 @@ grpc_slice grpc_chttp2_base64_decode(grpc_slice input) {
char *s = grpc_dump_slice(input, GPR_DUMP_ASCII);
gpr_log(GPR_ERROR, "Base64 decoding failed, input string:\n%s\n", s);
gpr_free(s);
- grpc_slice_unref(output);
- return gpr_empty_slice();
+ grpc_slice_unref_internal(exec_ctx, output);
+ return grpc_empty_slice();
}
GPR_ASSERT(ctx.output_cur == GRPC_SLICE_END_PTR(output));
GPR_ASSERT(ctx.input_cur == GRPC_SLICE_END_PTR(input));
return output;
}
-grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input,
+grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx,
+ grpc_slice input,
size_t output_length) {
size_t input_length = GRPC_SLICE_LENGTH(input);
grpc_slice output = grpc_slice_malloc(output_length);
@@ -200,8 +203,8 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input,
"grpc_chttp2_base64_decode_with_length has a length of %d, which "
"has a tail of 1 byte.\n",
(int)input_length);
- grpc_slice_unref(output);
- return gpr_empty_slice();
+ grpc_slice_unref_internal(exec_ctx, output);
+ return grpc_empty_slice();
}
if (output_length > input_length / 4 * 3 + tail_xtra[input_length % 4]) {
@@ -210,8 +213,8 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input,
"than the max possible output length %d.\n",
(int)output_length,
(int)(input_length / 4 * 3 + tail_xtra[input_length % 4]));
- grpc_slice_unref(output);
- return gpr_empty_slice();
+ grpc_slice_unref_internal(exec_ctx, output);
+ return grpc_empty_slice();
}
ctx.input_cur = GRPC_SLICE_START_PTR(input);
@@ -224,8 +227,8 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input,
char *s = grpc_dump_slice(input, GPR_DUMP_ASCII);
gpr_log(GPR_ERROR, "Base64 decoding failed, input string:\n%s\n", s);
gpr_free(s);
- grpc_slice_unref(output);
- return gpr_empty_slice();
+ grpc_slice_unref_internal(exec_ctx, output);
+ return grpc_empty_slice();
}
GPR_ASSERT(ctx.output_cur == GRPC_SLICE_END_PTR(output));
GPR_ASSERT(ctx.input_cur <= GRPC_SLICE_END_PTR(input));
diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.h b/src/core/ext/transport/chttp2/transport/bin_decoder.h
index 83a90be519..48ffb2ae3b 100644
--- a/src/core/ext/transport/chttp2/transport/bin_decoder.h
+++ b/src/core/ext/transport/chttp2/transport/bin_decoder.h
@@ -55,12 +55,13 @@ bool grpc_base64_decode_partial(struct grpc_base64_decode_context *ctx);
/* base64 decode a slice with pad chars. Returns a new slice, does not take
ownership of the input. Returns an empty slice if decoding is failed. */
-grpc_slice grpc_chttp2_base64_decode(grpc_slice input);
+grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx *exec_ctx, grpc_slice input);
/* base64 decode a slice without pad chars, data length is needed. Returns a new
slice, does not take ownership of the input. Returns an empty slice if
decoding is failed. */
-grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input,
+grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx,
+ grpc_slice input,
size_t output_length);
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_DECODER_H */
diff --git a/src/core/ext/transport/chttp2/transport/bin_encoder.c b/src/core/ext/transport/chttp2/transport/bin_encoder.c
index af25a4352a..e301c073f3 100644
--- a/src/core/ext/transport/chttp2/transport/bin_encoder.c
+++ b/src/core/ext/transport/chttp2/transport/bin_encoder.c
@@ -177,8 +177,7 @@ static void enc_add1(huff_out *out, uint8_t a) {
enc_flush_some(out);
}
-grpc_slice grpc_chttp2_base64_encode_and_huffman_compress_impl(
- grpc_slice input) {
+grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input) {
size_t input_length = GRPC_SLICE_LENGTH(input);
size_t input_triplets = input_length / 3;
size_t tail_case = input_length % 3;
diff --git a/src/core/ext/transport/chttp2/transport/bin_encoder.h b/src/core/ext/transport/chttp2/transport/bin_encoder.h
index 9e143b46e2..0f899c8e34 100644
--- a/src/core/ext/transport/chttp2/transport/bin_encoder.h
+++ b/src/core/ext/transport/chttp2/transport/bin_encoder.h
@@ -47,9 +47,8 @@ grpc_slice grpc_chttp2_huffman_compress(grpc_slice input);
/* equivalent to:
grpc_slice x = grpc_chttp2_base64_encode(input);
grpc_slice y = grpc_chttp2_huffman_compress(x);
- grpc_slice_unref(x);
+ grpc_slice_unref_internal(exec_ctx, x);
return y; */
-grpc_slice grpc_chttp2_base64_encode_and_huffman_compress_impl(
- grpc_slice input);
+grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input);
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_ENCODER_H */
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_plugin.c b/src/core/ext/transport/chttp2/transport/chttp2_plugin.c
index bd87253ed3..59b21e3330 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_plugin.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_plugin.c
@@ -31,14 +31,11 @@
*
*/
-#include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/transport/metadata.h"
void grpc_chttp2_plugin_init(void) {
- grpc_chttp2_base64_encode_and_huffman_compress =
- grpc_chttp2_base64_encode_and_huffman_compress_impl;
grpc_register_tracer("http", &grpc_http_trace);
grpc_register_tracer("flowctl", &grpc_flowctl_trace);
}
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 127e1cdc13..91861829e3 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -51,6 +51,7 @@
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/workqueue.h"
#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/transport/static_metadata.h"
@@ -144,13 +145,13 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
grpc_endpoint_destroy(exec_ctx, t->ep);
- grpc_slice_buffer_destroy(&t->qbuf);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &t->qbuf);
- grpc_slice_buffer_destroy(&t->outbuf);
- grpc_chttp2_hpack_compressor_destroy(&t->hpack_compressor);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &t->outbuf);
+ grpc_chttp2_hpack_compressor_destroy(exec_ctx, &t->hpack_compressor);
- grpc_slice_buffer_destroy(&t->read_buffer);
- grpc_chttp2_hpack_parser_destroy(&t->hpack_parser);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &t->read_buffer);
+ grpc_chttp2_hpack_parser_destroy(exec_ctx, &t->hpack_parser);
grpc_chttp2_goaway_parser_destroy(&t->goaway_parser);
for (i = 0; i < STREAM_LIST_COUNT; i++) {
@@ -263,7 +264,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
destructive_reclaimer_locked, t);
grpc_chttp2_goaway_parser_init(&t->goaway_parser);
- grpc_chttp2_hpack_parser_init(&t->hpack_parser);
+ grpc_chttp2_hpack_parser_init(exec_ctx, &t->hpack_parser);
grpc_slice_buffer_init(&t->read_buffer);
@@ -530,9 +531,11 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
GPR_ASSERT(s->recv_message_ready == NULL);
GPR_ASSERT(s->recv_trailing_metadata_finished == NULL);
grpc_chttp2_data_parser_destroy(exec_ctx, &s->data_parser);
- grpc_chttp2_incoming_metadata_buffer_destroy(&s->metadata_buffer[0]);
- grpc_chttp2_incoming_metadata_buffer_destroy(&s->metadata_buffer[1]);
- grpc_slice_buffer_destroy(&s->flow_controlled_buffer);
+ grpc_chttp2_incoming_metadata_buffer_destroy(exec_ctx,
+ &s->metadata_buffer[0]);
+ grpc_chttp2_incoming_metadata_buffer_destroy(exec_ctx,
+ &s->metadata_buffer[1]);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &s->flow_controlled_buffer);
GRPC_ERROR_UNREF(s->read_closed_error);
GRPC_ERROR_UNREF(s->write_closed_error);
@@ -761,7 +764,7 @@ void grpc_chttp2_add_incoming_goaway(grpc_exec_ctx *exec_ctx,
char *msg = grpc_dump_slice(goaway_text, GPR_DUMP_HEX | GPR_DUMP_ASCII);
GRPC_CHTTP2_IF_TRACING(
gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg));
- grpc_slice_unref(goaway_text);
+ grpc_slice_unref_internal(exec_ctx, goaway_text);
t->seen_goaway = 1;
/* lie: use transient failure from the transport to indicate goaway has been
* received */
@@ -873,8 +876,8 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx,
static bool contains_non_ok_status(grpc_metadata_batch *batch) {
grpc_linked_mdelem *l;
for (l = batch->list.head; l; l = l->next) {
- if (l->md->key == GRPC_MDSTR_GRPC_STATUS &&
- l->md != GRPC_MDELEM_GRPC_STATUS_0) {
+ if (grpc_slice_cmp(GRPC_MDKEY(l->md), GRPC_MDSTR_GRPC_STATUS) == 0 &&
+ !grpc_mdelem_eq(l->md, GRPC_MDELEM_GRPC_STATUS_0)) {
return true;
}
}
@@ -1244,7 +1247,7 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
if (op->send_goaway) {
send_goaway(exec_ctx, t,
grpc_chttp2_grpc_status_to_http2_error(op->goaway_status),
- grpc_slice_ref(*op->goaway_message));
+ grpc_slice_ref_internal(*op->goaway_message));
}
if (op->set_accept_stream) {
@@ -1475,20 +1478,19 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
gpr_ltoa(status, status_string);
grpc_chttp2_incoming_metadata_buffer_add(
&s->metadata_buffer[1],
- grpc_mdelem_from_metadata_strings(
- GRPC_MDSTR_GRPC_STATUS, grpc_mdstr_from_string(status_string)));
+ grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_STATUS,
+ grpc_slice_from_copied_string(status_string)));
if (slice) {
grpc_chttp2_incoming_metadata_buffer_add(
&s->metadata_buffer[1],
- grpc_mdelem_from_metadata_strings(
- GRPC_MDSTR_GRPC_MESSAGE,
- grpc_mdstr_from_slice(grpc_slice_ref(*slice))));
+ grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
+ grpc_slice_ref_internal(*slice)));
}
s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE;
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
}
if (slice) {
- grpc_slice_unref(*slice);
+ grpc_slice_unref_internal(exec_ctx, *slice);
}
}
@@ -1866,7 +1868,7 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
keep_reading = true;
GRPC_CHTTP2_REF_TRANSPORT(t, "keep_reading");
}
- grpc_slice_buffer_reset_and_unref(&t->read_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &t->read_buffer);
if (keep_reading) {
grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer, &t->read_action_begin);
@@ -1920,7 +1922,7 @@ static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx,
grpc_chttp2_incoming_byte_stream *bs) {
if (gpr_unref(&bs->refs)) {
GRPC_ERROR_UNREF(bs->error);
- grpc_slice_buffer_destroy(&bs->slices);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &bs->slices);
gpr_mu_destroy(&bs->slice_mu);
gpr_free(bs);
}
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
index eb68fe3138..8e2264a602 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
@@ -48,6 +48,7 @@
#include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
#include "src/core/ext/transport/chttp2/transport/hpack_table.h"
#include "src/core/ext/transport/chttp2/transport/varint.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/static_metadata.h"
#include "src/core/lib/transport/timeout_encoding.h"
@@ -63,6 +64,10 @@
/* don't consider adding anything bigger than this to the hpack table */
#define MAX_DECODER_SPACE_USAGE 512
+static grpc_slice_refcount terminal_slice_refcount = {NULL};
+static const grpc_slice terminal_slice = {&terminal_slice_refcount,
+ .data.refcounted = {0, 0}};
+
extern int grpc_http_trace;
typedef struct {
@@ -183,9 +188,11 @@ static void evict_entry(grpc_chttp2_hpack_compressor *c) {
}
/* add an element to the decoder table */
-static void add_elem(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem) {
- uint32_t key_hash = elem->key->hash;
- uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, elem->value->hash);
+static void add_elem(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
+ grpc_mdelem elem) {
+ uint32_t key_hash = grpc_slice_hash(GRPC_MDKEY(elem));
+ uint32_t value_hash = grpc_slice_hash(GRPC_MDVALUE(elem));
+ uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, value_hash);
uint32_t new_index = c->tail_remote_index + c->table_elems + 1;
size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem);
@@ -210,53 +217,64 @@ static void add_elem(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem) {
c->table_elems++;
/* Store this element into {entries,indices}_elem */
- if (c->entries_elems[HASH_FRAGMENT_2(elem_hash)] == elem) {
+ if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_2(elem_hash)], elem)) {
/* already there: update with new index */
c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
- } else if (c->entries_elems[HASH_FRAGMENT_3(elem_hash)] == elem) {
+ } else if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_3(elem_hash)],
+ elem)) {
/* already there (cuckoo): update with new index */
c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
- } else if (c->entries_elems[HASH_FRAGMENT_2(elem_hash)] == NULL) {
+ } else if (GRPC_MDISNULL(c->entries_elems[HASH_FRAGMENT_2(elem_hash)])) {
/* not there, but a free element: add */
c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem);
c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
- } else if (c->entries_elems[HASH_FRAGMENT_3(elem_hash)] == NULL) {
+ } else if (GRPC_MDISNULL(c->entries_elems[HASH_FRAGMENT_3(elem_hash)])) {
/* not there (cuckoo), but a free element: add */
c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem);
c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
} else if (c->indices_elems[HASH_FRAGMENT_2(elem_hash)] <
c->indices_elems[HASH_FRAGMENT_3(elem_hash)]) {
/* not there: replace oldest */
- GRPC_MDELEM_UNREF(c->entries_elems[HASH_FRAGMENT_2(elem_hash)]);
+ GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[HASH_FRAGMENT_2(elem_hash)]);
c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem);
c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index;
} else {
/* not there: replace oldest */
- GRPC_MDELEM_UNREF(c->entries_elems[HASH_FRAGMENT_3(elem_hash)]);
+ GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[HASH_FRAGMENT_3(elem_hash)]);
c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem);
c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index;
}
/* do exactly the same for the key (so we can find by that again too) */
- if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == elem->key) {
+ if (grpc_slice_cmp(c->entries_keys[HASH_FRAGMENT_2(key_hash)],
+ GRPC_MDKEY(elem)) == 0) {
c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index;
- } else if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == elem->key) {
+ } else if (grpc_slice_cmp(c->entries_keys[HASH_FRAGMENT_3(key_hash)],
+ GRPC_MDKEY(elem)) == 0) {
c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index;
- } else if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == NULL) {
- c->entries_keys[HASH_FRAGMENT_2(key_hash)] = GRPC_MDSTR_REF(elem->key);
+ } else if (c->entries_keys[HASH_FRAGMENT_2(key_hash)].refcount ==
+ &terminal_slice_refcount) {
+ c->entries_keys[HASH_FRAGMENT_2(key_hash)] =
+ grpc_slice_ref_internal(GRPC_MDKEY(elem));
c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index;
- } else if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == NULL) {
- c->entries_keys[HASH_FRAGMENT_3(key_hash)] = GRPC_MDSTR_REF(elem->key);
+ } else if (c->entries_keys[HASH_FRAGMENT_3(key_hash)].refcount ==
+ &terminal_slice_refcount) {
+ c->entries_keys[HASH_FRAGMENT_3(key_hash)] =
+ grpc_slice_ref_internal(GRPC_MDKEY(elem));
c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index;
} else if (c->indices_keys[HASH_FRAGMENT_2(key_hash)] <
c->indices_keys[HASH_FRAGMENT_3(key_hash)]) {
- GRPC_MDSTR_UNREF(c->entries_keys[HASH_FRAGMENT_2(key_hash)]);
- c->entries_keys[HASH_FRAGMENT_2(key_hash)] = GRPC_MDSTR_REF(elem->key);
+ grpc_slice_unref_internal(exec_ctx,
+ c->entries_keys[HASH_FRAGMENT_2(key_hash)]);
+ c->entries_keys[HASH_FRAGMENT_2(key_hash)] =
+ grpc_slice_ref_internal(GRPC_MDKEY(elem));
c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index;
} else {
- GRPC_MDSTR_UNREF(c->entries_keys[HASH_FRAGMENT_3(key_hash)]);
- c->entries_keys[HASH_FRAGMENT_3(key_hash)] = GRPC_MDSTR_REF(elem->key);
+ grpc_slice_unref_internal(exec_ctx,
+ c->entries_keys[HASH_FRAGMENT_3(key_hash)]);
+ c->entries_keys[HASH_FRAGMENT_3(key_hash)] =
+ grpc_slice_ref_internal(GRPC_MDKEY(elem));
c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index;
}
}
@@ -268,20 +286,18 @@ static void emit_indexed(grpc_chttp2_hpack_compressor *c, uint32_t elem_index,
len);
}
-static grpc_slice get_wire_value(grpc_mdelem *elem, uint8_t *huffman_prefix) {
- if (grpc_is_binary_header(
- (const char *)GRPC_SLICE_START_PTR(elem->key->slice),
- GRPC_SLICE_LENGTH(elem->key->slice))) {
+static grpc_slice get_wire_value(grpc_mdelem elem, uint8_t *huffman_prefix) {
+ if (grpc_is_binary_header(GRPC_MDKEY(elem))) {
*huffman_prefix = 0x80;
- return grpc_mdstr_as_base64_encoded_and_huffman_compressed(elem->value);
+ return grpc_chttp2_base64_encode_and_huffman_compress(GRPC_MDVALUE(elem));
}
/* TODO(ctiller): opportunistically compress non-binary headers */
*huffman_prefix = 0x00;
- return elem->value->slice;
+ return grpc_slice_ref(GRPC_MDVALUE(elem));
}
static void emit_lithdr_incidx(grpc_chttp2_hpack_compressor *c,
- uint32_t key_index, grpc_mdelem *elem,
+ uint32_t key_index, grpc_mdelem elem,
framer_state *st) {
uint32_t len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 2);
uint8_t huffman_prefix;
@@ -294,11 +310,11 @@ static void emit_lithdr_incidx(grpc_chttp2_hpack_compressor *c,
add_tiny_header_data(st, len_pfx), len_pfx);
GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix,
add_tiny_header_data(st, len_val_len), len_val_len);
- add_header_data(st, grpc_slice_ref(value_slice));
+ add_header_data(st, value_slice);
}
static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor *c,
- uint32_t key_index, grpc_mdelem *elem,
+ uint32_t key_index, grpc_mdelem elem,
framer_state *st) {
uint32_t len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 4);
uint8_t huffman_prefix;
@@ -311,12 +327,12 @@ static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor *c,
add_tiny_header_data(st, len_pfx), len_pfx);
GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix,
add_tiny_header_data(st, len_val_len), len_val_len);
- add_header_data(st, grpc_slice_ref(value_slice));
+ add_header_data(st, value_slice);
}
static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor *c,
- grpc_mdelem *elem, framer_state *st) {
- uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(elem->key->slice);
+ grpc_mdelem elem, framer_state *st) {
+ uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
uint8_t huffman_prefix;
grpc_slice value_slice = get_wire_value(elem, &huffman_prefix);
uint32_t len_val = (uint32_t)GRPC_SLICE_LENGTH(value_slice);
@@ -327,15 +343,15 @@ static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor *c,
*add_tiny_header_data(st, 1) = 0x40;
GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00,
add_tiny_header_data(st, len_key_len), len_key_len);
- add_header_data(st, grpc_slice_ref(elem->key->slice));
+ add_header_data(st, grpc_slice_ref_internal(GRPC_MDKEY(elem)));
GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix,
add_tiny_header_data(st, len_val_len), len_val_len);
- add_header_data(st, grpc_slice_ref(value_slice));
+ add_header_data(st, value_slice);
}
static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor *c,
- grpc_mdelem *elem, framer_state *st) {
- uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(elem->key->slice);
+ grpc_mdelem elem, framer_state *st) {
+ uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
uint8_t huffman_prefix;
grpc_slice value_slice = get_wire_value(elem, &huffman_prefix);
uint32_t len_val = (uint32_t)GRPC_SLICE_LENGTH(value_slice);
@@ -346,10 +362,10 @@ static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor *c,
*add_tiny_header_data(st, 1) = 0x00;
GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00,
add_tiny_header_data(st, len_key_len), len_key_len);
- add_header_data(st, grpc_slice_ref(elem->key->slice));
+ add_header_data(st, grpc_slice_ref_internal(GRPC_MDKEY(elem)));
GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix,
add_tiny_header_data(st, len_val_len), len_val_len);
- add_header_data(st, grpc_slice_ref(value_slice));
+ add_header_data(st, value_slice);
}
static void emit_advertise_table_size_change(grpc_chttp2_hpack_compressor *c,
@@ -366,16 +382,17 @@ static uint32_t dynidx(grpc_chttp2_hpack_compressor *c, uint32_t elem_index) {
}
/* encode an mdelem */
-static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem,
- framer_state *st) {
- uint32_t key_hash = elem->key->hash;
- uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, elem->value->hash);
+static void hpack_enc(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
+ grpc_mdelem elem, framer_state *st) {
+ uint32_t key_hash = grpc_slice_hash(GRPC_MDKEY(elem));
+ uint32_t value_hash = grpc_slice_hash(GRPC_MDVALUE(elem));
+ uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, value_hash);
size_t decoder_space_usage;
uint32_t indices_key;
int should_add_elem;
- GPR_ASSERT(GRPC_SLICE_LENGTH(elem->key->slice) > 0);
- if (GRPC_SLICE_START_PTR(elem->key->slice)[0] != ':') { /* regular header */
+ GPR_ASSERT(GRPC_SLICE_LENGTH(GRPC_MDKEY(elem)) > 0);
+ if (GRPC_SLICE_START_PTR(GRPC_MDKEY(elem))[0] != ':') { /* regular header */
st->seen_regular_header = 1;
} else {
GPR_ASSERT(
@@ -387,7 +404,7 @@ static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem,
/* is this elem currently in the decoders table? */
- if (c->entries_elems[HASH_FRAGMENT_2(elem_hash)] == elem &&
+ if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_2(elem_hash)], elem) &&
c->indices_elems[HASH_FRAGMENT_2(elem_hash)] > c->tail_remote_index) {
/* HIT: complete element (first cuckoo hash) */
emit_indexed(c, dynidx(c, c->indices_elems[HASH_FRAGMENT_2(elem_hash)]),
@@ -395,7 +412,7 @@ static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem,
return;
}
- if (c->entries_elems[HASH_FRAGMENT_3(elem_hash)] == elem &&
+ if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_3(elem_hash)], elem) &&
c->indices_elems[HASH_FRAGMENT_3(elem_hash)] > c->tail_remote_index) {
/* HIT: complete element (second cuckoo hash) */
emit_indexed(c, dynidx(c, c->indices_elems[HASH_FRAGMENT_3(elem_hash)]),
@@ -412,12 +429,13 @@ static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem,
/* no hits for the elem... maybe there's a key? */
indices_key = c->indices_keys[HASH_FRAGMENT_2(key_hash)];
- if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == elem->key &&
+ if (grpc_slice_cmp(c->entries_keys[HASH_FRAGMENT_2(key_hash)],
+ GRPC_MDKEY(elem)) == 0 &&
indices_key > c->tail_remote_index) {
/* HIT: key (first cuckoo hash) */
if (should_add_elem) {
emit_lithdr_incidx(c, dynidx(c, indices_key), elem, st);
- add_elem(c, elem);
+ add_elem(exec_ctx, c, elem);
return;
} else {
emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st);
@@ -427,12 +445,13 @@ static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem,
}
indices_key = c->indices_keys[HASH_FRAGMENT_3(key_hash)];
- if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == elem->key &&
+ if (grpc_slice_cmp(c->entries_keys[HASH_FRAGMENT_3(key_hash)],
+ GRPC_MDKEY(elem)) == 0 &&
indices_key > c->tail_remote_index) {
/* HIT: key (first cuckoo hash) */
if (should_add_elem) {
emit_lithdr_incidx(c, dynidx(c, indices_key), elem, st);
- add_elem(c, elem);
+ add_elem(exec_ctx, c, elem);
return;
} else {
emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st);
@@ -445,7 +464,7 @@ static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem,
if (should_add_elem) {
emit_lithdr_incidx_v(c, elem, st);
- add_elem(c, elem);
+ add_elem(exec_ctx, c, elem);
return;
} else {
emit_lithdr_noidx_v(c, elem, st);
@@ -457,16 +476,17 @@ static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem,
#define STRLEN_LIT(x) (sizeof(x) - 1)
#define TIMEOUT_KEY "grpc-timeout"
-static void deadline_enc(grpc_chttp2_hpack_compressor *c, gpr_timespec deadline,
+static void deadline_enc(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hpack_compressor *c, gpr_timespec deadline,
framer_state *st) {
char timeout_str[GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE];
- grpc_mdelem *mdelem;
+ grpc_mdelem mdelem;
grpc_http2_encode_timeout(
gpr_time_sub(deadline, gpr_now(deadline.clock_type)), timeout_str);
- mdelem = grpc_mdelem_from_metadata_strings(
- GRPC_MDSTR_GRPC_TIMEOUT, grpc_mdstr_from_string(timeout_str));
- hpack_enc(c, mdelem, st);
- GRPC_MDELEM_UNREF(mdelem);
+ mdelem = grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_TIMEOUT,
+ grpc_slice_from_copied_string(timeout_str));
+ hpack_enc(exec_ctx, c, mdelem, st);
+ GRPC_MDELEM_UNREF(exec_ctx, mdelem);
}
static uint32_t elems_for_bytes(uint32_t bytes) { return (bytes + 31) / 32; }
@@ -481,13 +501,19 @@ void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c) {
gpr_malloc(sizeof(*c->table_elem_size) * c->cap_table_elems);
memset(c->table_elem_size, 0,
sizeof(*c->table_elem_size) * c->cap_table_elems);
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(c->entries_keys); i++) {
+ c->entries_keys[i] = terminal_slice;
+ }
}
-void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c) {
+void grpc_chttp2_hpack_compressor_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hpack_compressor *c) {
int i;
for (i = 0; i < GRPC_CHTTP2_HPACKC_NUM_VALUES; i++) {
- if (c->entries_keys[i]) GRPC_MDSTR_UNREF(c->entries_keys[i]);
- if (c->entries_elems[i]) GRPC_MDELEM_UNREF(c->entries_elems[i]);
+ if (c->entries_keys[i].refcount != &terminal_slice_refcount) {
+ grpc_slice_unref_internal(exec_ctx, c->entries_keys[i]);
+ }
+ GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[i]);
}
gpr_free(c->table_elem_size);
}
@@ -542,7 +568,8 @@ void grpc_chttp2_hpack_compressor_set_max_table_size(
}
}
-void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c,
+void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hpack_compressor *c,
uint32_t stream_id,
grpc_metadata_batch *metadata, int is_eof,
size_t max_frame_size,
@@ -571,11 +598,11 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c,
}
grpc_metadata_batch_assert_ok(metadata);
for (l = metadata->list.head; l; l = l->next) {
- hpack_enc(c, l->md, &st);
+ hpack_enc(exec_ctx, c, l->md, &st);
}
deadline = metadata->deadline;
if (gpr_time_cmp(deadline, gpr_inf_future(deadline.clock_type)) != 0) {
- deadline_enc(c, deadline, &st);
+ deadline_enc(exec_ctx, c, deadline, &st);
}
finish_frame(&st, 1, is_eof);
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
index bcbd675ca2..83ba5b1b3e 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
@@ -74,8 +74,8 @@ typedef struct {
/* entry tables for keys & elems: these tables track values that have been
seen and *may* be in the decompressor table */
- grpc_mdstr *entries_keys[GRPC_CHTTP2_HPACKC_NUM_VALUES];
- grpc_mdelem *entries_elems[GRPC_CHTTP2_HPACKC_NUM_VALUES];
+ grpc_slice entries_keys[GRPC_CHTTP2_HPACKC_NUM_VALUES];
+ grpc_mdelem entries_elems[GRPC_CHTTP2_HPACKC_NUM_VALUES];
uint32_t indices_keys[GRPC_CHTTP2_HPACKC_NUM_VALUES];
uint32_t indices_elems[GRPC_CHTTP2_HPACKC_NUM_VALUES];
@@ -83,13 +83,15 @@ typedef struct {
} grpc_chttp2_hpack_compressor;
void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c);
-void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c);
+void grpc_chttp2_hpack_compressor_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hpack_compressor *c);
void grpc_chttp2_hpack_compressor_set_max_table_size(
grpc_chttp2_hpack_compressor *c, uint32_t max_table_size);
void grpc_chttp2_hpack_compressor_set_max_usable_size(
grpc_chttp2_hpack_compressor *c, uint32_t max_table_size);
-void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c, uint32_t id,
+void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hpack_compressor *c, uint32_t id,
grpc_metadata_batch *metadata, int is_eof,
size_t max_frame_size,
grpc_transport_one_way_stats *stats,
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c
index 6a9200b8db..91bedcf7f0 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c
@@ -52,6 +52,7 @@
#include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
#include "src/core/ext/transport/chttp2/transport/http2_errors.h"
#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/support/string.h"
extern int grpc_http_trace;
@@ -668,22 +669,22 @@ static const uint8_t inverse_base64[256] = {
/* emission helpers */
static grpc_error *on_hdr(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p,
- grpc_mdelem *md, int add_to_table) {
+ grpc_mdelem md, int add_to_table) {
if (add_to_table) {
- grpc_error *err = grpc_chttp2_hptbl_add(&p->table, md);
+ grpc_error *err = grpc_chttp2_hptbl_add(exec_ctx, &p->table, md);
if (err != GRPC_ERROR_NONE) return err;
}
if (p->on_header == NULL) {
- GRPC_MDELEM_UNREF(md);
+ GRPC_MDELEM_UNREF(exec_ctx, md);
return GRPC_ERROR_CREATE("on_header callback not set");
}
p->on_header(exec_ctx, p->on_header_user_data, md);
return GRPC_ERROR_NONE;
}
-static grpc_mdstr *take_string(grpc_chttp2_hpack_parser *p,
- grpc_chttp2_hpack_parser_string *str) {
- grpc_mdstr *s = grpc_mdstr_from_buffer((uint8_t *)str->str, str->length);
+static grpc_slice take_string(grpc_chttp2_hpack_parser *p,
+ grpc_chttp2_hpack_parser_string *str) {
+ grpc_slice s = grpc_slice_from_copied_buffer(str->str, str->length);
str->length = 0;
return s;
}
@@ -771,8 +772,8 @@ static grpc_error *finish_indexed_field(grpc_exec_ctx *exec_ctx,
grpc_chttp2_hpack_parser *p,
const uint8_t *cur,
const uint8_t *end) {
- grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
- if (md == NULL) {
+ grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
+ if (GRPC_MDISNULL(md)) {
return grpc_error_set_int(
grpc_error_set_int(GRPC_ERROR_CREATE("Invalid HPACK index received"),
GRPC_ERROR_INT_INDEX, (intptr_t)p->index),
@@ -813,11 +814,12 @@ static grpc_error *finish_lithdr_incidx(grpc_exec_ctx *exec_ctx,
grpc_chttp2_hpack_parser *p,
const uint8_t *cur,
const uint8_t *end) {
- grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
- GPR_ASSERT(md != NULL); /* handled in string parsing */
+ grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
+ GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */
grpc_error *err = on_hdr(
- exec_ctx, p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
- take_string(p, &p->value)),
+ exec_ctx, p,
+ grpc_mdelem_from_slices(exec_ctx, grpc_slice_ref_internal(GRPC_MDKEY(md)),
+ take_string(p, &p->value)),
1);
if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
return parse_begin(exec_ctx, p, cur, end);
@@ -829,8 +831,8 @@ static grpc_error *finish_lithdr_incidx_v(grpc_exec_ctx *exec_ctx,
const uint8_t *cur,
const uint8_t *end) {
grpc_error *err = on_hdr(
- exec_ctx, p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
- take_string(p, &p->value)),
+ exec_ctx, p, grpc_mdelem_from_slices(exec_ctx, take_string(p, &p->key),
+ take_string(p, &p->value)),
1);
if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
return parse_begin(exec_ctx, p, cur, end);
@@ -881,11 +883,12 @@ static grpc_error *finish_lithdr_notidx(grpc_exec_ctx *exec_ctx,
grpc_chttp2_hpack_parser *p,
const uint8_t *cur,
const uint8_t *end) {
- grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
- GPR_ASSERT(md != NULL); /* handled in string parsing */
+ grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
+ GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */
grpc_error *err = on_hdr(
- exec_ctx, p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
- take_string(p, &p->value)),
+ exec_ctx, p,
+ grpc_mdelem_from_slices(exec_ctx, grpc_slice_ref_internal(GRPC_MDKEY(md)),
+ take_string(p, &p->value)),
0);
if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
return parse_begin(exec_ctx, p, cur, end);
@@ -897,8 +900,8 @@ static grpc_error *finish_lithdr_notidx_v(grpc_exec_ctx *exec_ctx,
const uint8_t *cur,
const uint8_t *end) {
grpc_error *err = on_hdr(
- exec_ctx, p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
- take_string(p, &p->value)),
+ exec_ctx, p, grpc_mdelem_from_slices(exec_ctx, take_string(p, &p->key),
+ take_string(p, &p->value)),
0);
if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
return parse_begin(exec_ctx, p, cur, end);
@@ -949,11 +952,12 @@ static grpc_error *finish_lithdr_nvridx(grpc_exec_ctx *exec_ctx,
grpc_chttp2_hpack_parser *p,
const uint8_t *cur,
const uint8_t *end) {
- grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
- GPR_ASSERT(md != NULL); /* handled in string parsing */
+ grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
+ GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */
grpc_error *err = on_hdr(
- exec_ctx, p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
- take_string(p, &p->value)),
+ exec_ctx, p,
+ grpc_mdelem_from_slices(exec_ctx, grpc_slice_ref_internal(GRPC_MDKEY(md)),
+ take_string(p, &p->value)),
0);
if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
return parse_begin(exec_ctx, p, cur, end);
@@ -965,8 +969,8 @@ static grpc_error *finish_lithdr_nvridx_v(grpc_exec_ctx *exec_ctx,
const uint8_t *cur,
const uint8_t *end) {
grpc_error *err = on_hdr(
- exec_ctx, p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
- take_string(p, &p->value)),
+ exec_ctx, p, grpc_mdelem_from_slices(exec_ctx, take_string(p, &p->key),
+ take_string(p, &p->value)),
0);
if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
return parse_begin(exec_ctx, p, cur, end);
@@ -1020,7 +1024,7 @@ static grpc_error *finish_max_tbl_size(grpc_exec_ctx *exec_ctx,
gpr_log(GPR_INFO, "MAX TABLE SIZE: %d", p->index);
}
grpc_error *err =
- grpc_chttp2_hptbl_set_current_table_size(&p->table, p->index);
+ grpc_chttp2_hptbl_set_current_table_size(exec_ctx, &p->table, p->index);
if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
return parse_begin(exec_ctx, p, cur, end);
}
@@ -1490,21 +1494,20 @@ static grpc_error *parse_key_string(grpc_exec_ctx *exec_ctx,
/* check if a key represents a binary header or not */
static bool is_binary_literal_header(grpc_chttp2_hpack_parser *p) {
- return grpc_is_binary_header(p->key.str, p->key.length);
+ return grpc_is_binary_header(
+ grpc_slice_from_static_buffer(p->key.str, p->key.length));
}
static grpc_error *is_binary_indexed_header(grpc_chttp2_hpack_parser *p,
bool *is) {
- grpc_mdelem *elem = grpc_chttp2_hptbl_lookup(&p->table, p->index);
- if (!elem) {
+ grpc_mdelem elem = grpc_chttp2_hptbl_lookup(&p->table, p->index);
+ if (GRPC_MDISNULL(elem)) {
return grpc_error_set_int(
grpc_error_set_int(GRPC_ERROR_CREATE("Invalid HPACK index received"),
GRPC_ERROR_INT_INDEX, (intptr_t)p->index),
GRPC_ERROR_INT_SIZE, (intptr_t)p->table.num_ents);
}
- *is = grpc_is_binary_header(
- (const char *)GRPC_SLICE_START_PTR(elem->key->slice),
- GRPC_SLICE_LENGTH(elem->key->slice));
+ *is = grpc_is_binary_header(GRPC_MDKEY(elem));
return GRPC_ERROR_NONE;
}
@@ -1534,7 +1537,8 @@ static grpc_error *parse_value_string_with_literal_key(
/* PUBLIC INTERFACE */
-void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p) {
+void grpc_chttp2_hpack_parser_init(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hpack_parser *p) {
p->on_header = NULL;
p->on_header_user_data = NULL;
p->state = parse_begin;
@@ -1546,7 +1550,7 @@ void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p) {
p->value.length = 0;
p->dynamic_table_update_allowed = 2;
p->last_error = GRPC_ERROR_NONE;
- grpc_chttp2_hptbl_init(&p->table);
+ grpc_chttp2_hptbl_init(exec_ctx, &p->table);
}
void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p) {
@@ -1554,8 +1558,9 @@ void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p) {
p->state = parse_stream_dep0;
}
-void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p) {
- grpc_chttp2_hptbl_destroy(&p->table);
+void grpc_chttp2_hpack_parser_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hpack_parser *p) {
+ grpc_chttp2_hptbl_destroy(exec_ctx, &p->table);
GRPC_ERROR_UNREF(p->last_error);
gpr_free(p->key.str);
gpr_free(p->value.str);
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.h b/src/core/ext/transport/chttp2/transport/hpack_parser.h
index a39bf466cd..442708e3d7 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.h
@@ -56,7 +56,7 @@ typedef struct {
struct grpc_chttp2_hpack_parser {
/* user specified callback for each header output */
- void (*on_header)(grpc_exec_ctx *exec_ctx, void *user_data, grpc_mdelem *md);
+ void (*on_header)(grpc_exec_ctx *exec_ctx, void *user_data, grpc_mdelem md);
void *on_header_user_data;
grpc_error *last_error;
@@ -99,8 +99,10 @@ struct grpc_chttp2_hpack_parser {
grpc_chttp2_hptbl table;
};
-void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p);
-void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser *p);
+void grpc_chttp2_hpack_parser_init(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hpack_parser *p);
+void grpc_chttp2_hpack_parser_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hpack_parser *p);
void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p);
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.c b/src/core/ext/transport/chttp2/transport/hpack_table.c
index 2dc793d304..2cb816fe53 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.c
@@ -179,7 +179,7 @@ static uint32_t entries_for_bytes(uint32_t bytes) {
GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD;
}
-void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl) {
+void grpc_chttp2_hptbl_init(grpc_exec_ctx *exec_ctx, grpc_chttp2_hptbl *tbl) {
size_t i;
memset(tbl, 0, sizeof(*tbl));
@@ -190,24 +190,29 @@ void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl) {
tbl->ents = gpr_malloc(sizeof(*tbl->ents) * tbl->cap_entries);
memset(tbl->ents, 0, sizeof(*tbl->ents) * tbl->cap_entries);
for (i = 1; i <= GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
- tbl->static_ents[i - 1] =
- grpc_mdelem_from_strings(static_table[i].key, static_table[i].value);
+ tbl->static_ents[i - 1] = grpc_mdelem_from_slices(
+ exec_ctx,
+ grpc_slice_intern(grpc_slice_from_static_string(static_table[i].key)),
+ grpc_slice_intern(
+ grpc_slice_from_static_string(static_table[i].value)));
}
}
-void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl *tbl) {
+void grpc_chttp2_hptbl_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hptbl *tbl) {
size_t i;
for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
- GRPC_MDELEM_UNREF(tbl->static_ents[i]);
+ GRPC_MDELEM_UNREF(exec_ctx, tbl->static_ents[i]);
}
for (i = 0; i < tbl->num_ents; i++) {
- GRPC_MDELEM_UNREF(tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]);
+ GRPC_MDELEM_UNREF(exec_ctx,
+ tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]);
}
gpr_free(tbl->ents);
}
-grpc_mdelem *grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl,
- uint32_t tbl_index) {
+grpc_mdelem grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl,
+ uint32_t tbl_index) {
/* Static table comes first, just return an entry from it */
if (tbl_index <= GRPC_CHTTP2_LAST_STATIC_ENTRY) {
return tbl->static_ents[tbl_index - 1];
@@ -220,24 +225,24 @@ grpc_mdelem *grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl,
return tbl->ents[offset];
}
/* Invalid entry: return error */
- return NULL;
+ return GRPC_MDNULL;
}
/* Evict one element from the table */
-static void evict1(grpc_chttp2_hptbl *tbl) {
- grpc_mdelem *first_ent = tbl->ents[tbl->first_ent];
- size_t elem_bytes = GRPC_SLICE_LENGTH(first_ent->key->slice) +
- GRPC_SLICE_LENGTH(first_ent->value->slice) +
+static void evict1(grpc_exec_ctx *exec_ctx, grpc_chttp2_hptbl *tbl) {
+ grpc_mdelem first_ent = tbl->ents[tbl->first_ent];
+ size_t elem_bytes = GRPC_SLICE_LENGTH(GRPC_MDKEY(first_ent)) +
+ GRPC_SLICE_LENGTH(GRPC_MDVALUE(first_ent)) +
GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD;
GPR_ASSERT(elem_bytes <= tbl->mem_used);
tbl->mem_used -= (uint32_t)elem_bytes;
tbl->first_ent = ((tbl->first_ent + 1) % tbl->cap_entries);
tbl->num_ents--;
- GRPC_MDELEM_UNREF(first_ent);
+ GRPC_MDELEM_UNREF(exec_ctx, first_ent);
}
static void rebuild_ents(grpc_chttp2_hptbl *tbl, uint32_t new_cap) {
- grpc_mdelem **ents = gpr_malloc(sizeof(*ents) * new_cap);
+ grpc_mdelem *ents = gpr_malloc(sizeof(*ents) * new_cap);
uint32_t i;
for (i = 0; i < tbl->num_ents; i++) {
@@ -249,7 +254,8 @@ static void rebuild_ents(grpc_chttp2_hptbl *tbl, uint32_t new_cap) {
tbl->first_ent = 0;
}
-void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl *tbl,
+void grpc_chttp2_hptbl_set_max_bytes(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hptbl *tbl,
uint32_t max_bytes) {
if (tbl->max_bytes == max_bytes) {
return;
@@ -258,12 +264,13 @@ void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl *tbl,
gpr_log(GPR_DEBUG, "Update hpack parser max size to %d", max_bytes);
}
while (tbl->mem_used > max_bytes) {
- evict1(tbl);
+ evict1(exec_ctx, tbl);
}
tbl->max_bytes = max_bytes;
}
-grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl,
+grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hptbl *tbl,
uint32_t bytes) {
if (tbl->current_table_bytes == bytes) {
return GRPC_ERROR_NONE;
@@ -281,7 +288,7 @@ grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl,
gpr_log(GPR_DEBUG, "Update hpack parser table size to %d", bytes);
}
while (tbl->mem_used > bytes) {
- evict1(tbl);
+ evict1(exec_ctx, tbl);
}
tbl->current_table_bytes = bytes;
tbl->max_entries = entries_for_bytes(bytes);
@@ -296,10 +303,11 @@ grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl,
return GRPC_ERROR_NONE;
}
-grpc_error *grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl, grpc_mdelem *md) {
+grpc_error *grpc_chttp2_hptbl_add(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hptbl *tbl, grpc_mdelem md) {
/* determine how many bytes of buffer this entry represents */
- size_t elem_bytes = GRPC_SLICE_LENGTH(md->key->slice) +
- GRPC_SLICE_LENGTH(md->value->slice) +
+ size_t elem_bytes = GRPC_SLICE_LENGTH(GRPC_MDKEY(md)) +
+ GRPC_SLICE_LENGTH(GRPC_MDVALUE(md)) +
GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD;
if (tbl->current_table_bytes > tbl->max_bytes) {
@@ -326,14 +334,14 @@ grpc_error *grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl, grpc_mdelem *md) {
* empty table.
*/
while (tbl->num_ents) {
- evict1(tbl);
+ evict1(exec_ctx, tbl);
}
return GRPC_ERROR_NONE;
}
/* evict entries to ensure no overflow */
while (elem_bytes > (size_t)tbl->current_table_bytes - tbl->mem_used) {
- evict1(tbl);
+ evict1(exec_ctx, tbl);
}
/* copy the finalized entry in */
@@ -347,16 +355,16 @@ grpc_error *grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl, grpc_mdelem *md) {
}
grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find(
- const grpc_chttp2_hptbl *tbl, grpc_mdelem *md) {
+ const grpc_chttp2_hptbl *tbl, grpc_mdelem md) {
grpc_chttp2_hptbl_find_result r = {0, 0};
uint32_t i;
/* See if the string is in the static table */
for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
- grpc_mdelem *ent = tbl->static_ents[i];
- if (md->key != ent->key) continue;
+ grpc_mdelem ent = tbl->static_ents[i];
+ if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDKEY(ent)) != 0) continue;
r.index = i + 1u;
- r.has_value = md->value == ent->value;
+ r.has_value = grpc_slice_cmp(GRPC_MDVALUE(md), GRPC_MDVALUE(ent)) == 0;
if (r.has_value) return r;
}
@@ -364,10 +372,10 @@ grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find(
for (i = 0; i < tbl->num_ents; i++) {
uint32_t idx =
(uint32_t)(tbl->num_ents - i + GRPC_CHTTP2_LAST_STATIC_ENTRY);
- grpc_mdelem *ent = tbl->ents[(tbl->first_ent + i) % tbl->cap_entries];
- if (md->key != ent->key) continue;
+ grpc_mdelem ent = tbl->ents[(tbl->first_ent + i) % tbl->cap_entries];
+ if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDKEY(ent)) != 0) continue;
r.index = idx;
- r.has_value = md->value == ent->value;
+ r.has_value = grpc_slice_cmp(GRPC_MDVALUE(md), GRPC_MDVALUE(ent)) == 0;
if (r.has_value) return r;
}
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.h b/src/core/ext/transport/chttp2/transport/hpack_table.h
index 2ca130e64b..0e6655289f 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.h
@@ -79,24 +79,27 @@ typedef struct {
/* a circular buffer of headers - this is stored in the opposite order to
what hpack specifies, in order to simplify table management a little...
meaning lookups need to SUBTRACT from the end position */
- grpc_mdelem **ents;
- grpc_mdelem *static_ents[GRPC_CHTTP2_LAST_STATIC_ENTRY];
+ grpc_mdelem *ents;
+ grpc_mdelem static_ents[GRPC_CHTTP2_LAST_STATIC_ENTRY];
} grpc_chttp2_hptbl;
/* initialize a hpack table */
-void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl);
-void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl *tbl);
-void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl *tbl,
+void grpc_chttp2_hptbl_init(grpc_exec_ctx *exec_ctx, grpc_chttp2_hptbl *tbl);
+void grpc_chttp2_hptbl_destroy(grpc_exec_ctx *exec_ctx, grpc_chttp2_hptbl *tbl);
+void grpc_chttp2_hptbl_set_max_bytes(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hptbl *tbl,
uint32_t max_bytes);
-grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl,
+grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hptbl *tbl,
uint32_t bytes);
/* lookup a table entry based on its hpack index */
-grpc_mdelem *grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl,
+grpc_mdelem grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl,
uint32_t index);
/* add a table entry to the index */
-grpc_error *grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl,
- grpc_mdelem *md) GRPC_MUST_USE_RESULT;
+grpc_error *grpc_chttp2_hptbl_add(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_hptbl *tbl,
+ grpc_mdelem md) GRPC_MUST_USE_RESULT;
/* Find a key/value pair in the table... returns the index in the table of the
most similar entry, or 0 if the value was not found */
typedef struct {
@@ -104,6 +107,6 @@ typedef struct {
int has_value;
} grpc_chttp2_hptbl_find_result;
grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find(
- const grpc_chttp2_hptbl *tbl, grpc_mdelem *md);
+ const grpc_chttp2_hptbl *tbl, grpc_mdelem md);
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_TABLE_H */
diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.c b/src/core/ext/transport/chttp2/transport/incoming_metadata.c
index 3e463a7995..9922dd87e1 100644
--- a/src/core/ext/transport/chttp2/transport/incoming_metadata.c
+++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.c
@@ -46,18 +46,18 @@ void grpc_chttp2_incoming_metadata_buffer_init(
}
void grpc_chttp2_incoming_metadata_buffer_destroy(
- grpc_chttp2_incoming_metadata_buffer *buffer) {
+ grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer) {
size_t i;
if (!buffer->published) {
for (i = 0; i < buffer->count; i++) {
- GRPC_MDELEM_UNREF(buffer->elems[i].md);
+ GRPC_MDELEM_UNREF(exec_ctx, buffer->elems[i].md);
}
}
gpr_free(buffer->elems);
}
void grpc_chttp2_incoming_metadata_buffer_add(
- grpc_chttp2_incoming_metadata_buffer *buffer, grpc_mdelem *elem) {
+ grpc_chttp2_incoming_metadata_buffer *buffer, grpc_mdelem elem) {
GPR_ASSERT(!buffer->published);
if (buffer->capacity == buffer->count) {
buffer->capacity = GPR_MAX(8, 2 * buffer->capacity);
diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.h b/src/core/ext/transport/chttp2/transport/incoming_metadata.h
index df4343b93e..e9d07724b6 100644
--- a/src/core/ext/transport/chttp2/transport/incoming_metadata.h
+++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.h
@@ -49,12 +49,12 @@ typedef struct {
void grpc_chttp2_incoming_metadata_buffer_init(
grpc_chttp2_incoming_metadata_buffer *buffer);
void grpc_chttp2_incoming_metadata_buffer_destroy(
- grpc_chttp2_incoming_metadata_buffer *buffer);
+ grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer);
void grpc_chttp2_incoming_metadata_buffer_publish(
grpc_chttp2_incoming_metadata_buffer *buffer, grpc_metadata_batch *batch);
void grpc_chttp2_incoming_metadata_buffer_add(
- grpc_chttp2_incoming_metadata_buffer *buffer, grpc_mdelem *elem);
+ grpc_chttp2_incoming_metadata_buffer *buffer, grpc_mdelem elem);
void grpc_chttp2_incoming_metadata_buffer_set_deadline(
grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline);
diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c
index 5efb49751c..12f850791d 100644
--- a/src/core/ext/transport/chttp2/transport/parsing.c
+++ b/src/core/ext/transport/chttp2/transport/parsing.c
@@ -42,6 +42,7 @@
#include "src/core/ext/transport/chttp2/transport/http2_errors.h"
#include "src/core/ext/transport/chttp2/transport/status_conversion.h"
#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/transport/static_metadata.h"
#include "src/core/lib/transport/timeout_encoding.h"
@@ -200,7 +201,7 @@ grpc_error *grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx,
return err;
}
if (t->incoming_frame_size == 0) {
- err = parse_frame_slice(exec_ctx, t, gpr_empty_slice(), 1);
+ err = parse_frame_slice(exec_ctx, t, grpc_empty_slice(), 1);
if (err != GRPC_ERROR_NONE) {
return err;
}
@@ -335,8 +336,8 @@ static grpc_error *skip_parser(grpc_exec_ctx *exec_ctx, void *parser,
return GRPC_ERROR_NONE;
}
-static void skip_header(grpc_exec_ctx *exec_ctx, void *tp, grpc_mdelem *md) {
- GRPC_MDELEM_UNREF(md);
+static void skip_header(grpc_exec_ctx *exec_ctx, void *tp, grpc_mdelem md) {
+ GRPC_MDELEM_UNREF(exec_ctx, md);
}
static grpc_error *init_skip_frame_parser(grpc_exec_ctx *exec_ctx,
@@ -443,7 +444,7 @@ error_handler:
static void free_timeout(void *p) { gpr_free(p); }
static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp,
- grpc_mdelem *md) {
+ grpc_mdelem md) {
grpc_chttp2_transport *t = tp;
grpc_chttp2_stream *s = t->incoming_stream;
@@ -451,33 +452,43 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp,
GPR_ASSERT(s != NULL);
- GRPC_CHTTP2_IF_TRACING(gpr_log(
- GPR_INFO, "HTTP:%d:HDR:%s: %s: %s", s->id, t->is_client ? "CLI" : "SVR",
- grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value)));
+ if (grpc_http_trace) {
+ char *key = grpc_dump_slice(GRPC_MDKEY(md), GPR_DUMP_ASCII);
+ char *value =
+ grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX | GPR_DUMP_ASCII);
+ gpr_log(GPR_INFO, "HTTP:%d:HDR:%s: %s: %s", s->id,
+ t->is_client ? "CLI" : "SVR", key, value);
+ gpr_free(key);
+ gpr_free(value);
+ }
- if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) {
+ if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) == 0 &&
+ !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
/* TODO(ctiller): check for a status like " 0" */
s->seen_error = true;
}
- if (md->key == GRPC_MDSTR_GRPC_TIMEOUT) {
+ if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT) == 0) {
gpr_timespec *cached_timeout = grpc_mdelem_get_user_data(md, free_timeout);
- if (!cached_timeout) {
+ gpr_timespec timeout;
+ if (cached_timeout == NULL) {
/* not already parsed: parse it now, and store the result away */
cached_timeout = gpr_malloc(sizeof(gpr_timespec));
- if (!grpc_http2_decode_timeout(grpc_mdstr_as_c_string(md->value),
- cached_timeout)) {
- gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'",
- grpc_mdstr_as_c_string(md->value));
+ if (!grpc_http2_decode_timeout(GRPC_MDVALUE(md), cached_timeout)) {
+ char *val = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_ASCII);
+ gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val);
+ gpr_free(val);
*cached_timeout = gpr_inf_future(GPR_TIMESPAN);
}
- cached_timeout =
- grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
+ timeout = *cached_timeout;
+ grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
+ } else {
+ timeout = *cached_timeout;
}
grpc_chttp2_incoming_metadata_buffer_set_deadline(
&s->metadata_buffer[0],
- gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), *cached_timeout));
- GRPC_MDELEM_UNREF(md);
+ gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), timeout));
+ GRPC_MDELEM_UNREF(exec_ctx, md);
} else {
const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md);
const size_t metadata_size_limit =
@@ -495,7 +506,7 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp,
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
s->seen_error = true;
- GRPC_MDELEM_UNREF(md);
+ GRPC_MDELEM_UNREF(exec_ctx, md);
} else {
grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[0], md);
}
@@ -505,7 +516,7 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp,
}
static void on_trailing_header(grpc_exec_ctx *exec_ctx, void *tp,
- grpc_mdelem *md) {
+ grpc_mdelem md) {
grpc_chttp2_transport *t = tp;
grpc_chttp2_stream *s = t->incoming_stream;
@@ -513,11 +524,18 @@ static void on_trailing_header(grpc_exec_ctx *exec_ctx, void *tp,
GPR_ASSERT(s != NULL);
- GRPC_CHTTP2_IF_TRACING(gpr_log(
- GPR_INFO, "HTTP:%d:TRL:%s: %s: %s", s->id, t->is_client ? "CLI" : "SVR",
- grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value)));
+ if (grpc_http_trace) {
+ char *key = grpc_dump_slice(GRPC_MDKEY(md), GPR_DUMP_ASCII);
+ char *value =
+ grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX | GPR_DUMP_ASCII);
+ gpr_log(GPR_INFO, "HTTP:%d:TRL:%s: %s: %s", s->id,
+ t->is_client ? "CLI" : "SVR", key, value);
+ gpr_free(key);
+ gpr_free(value);
+ }
- if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) {
+ if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) == 0 &&
+ !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
/* TODO(ctiller): check for a status like " 0" */
s->seen_error = true;
}
@@ -538,7 +556,7 @@ static void on_trailing_header(grpc_exec_ctx *exec_ctx, void *tp,
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
grpc_chttp2_parsing_become_skip_parser(exec_ctx, t);
s->seen_error = true;
- GRPC_MDELEM_UNREF(md);
+ GRPC_MDELEM_UNREF(exec_ctx, md);
} else {
grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[1], md);
}
@@ -712,7 +730,7 @@ static grpc_error *init_settings_frame_parser(grpc_exec_ctx *exec_ctx,
memcpy(t->settings[GRPC_ACKED_SETTINGS], t->settings[GRPC_SENT_SETTINGS],
GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t));
grpc_chttp2_hptbl_set_max_bytes(
- &t->hpack_parser.table,
+ exec_ctx, &t->hpack_parser.table,
t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]);
t->sent_local_settings = 0;
diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c
index 139e7387c4..ef2010af7b 100644
--- a/src/core/ext/transport/chttp2/transport/writing.c
+++ b/src/core/ext/transport/chttp2/transport/writing.c
@@ -39,6 +39,7 @@
#include "src/core/ext/transport/chttp2/transport/http2_errors.h"
#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
static void add_to_write_list(grpc_chttp2_write_cb **list,
grpc_chttp2_write_cb *cb) {
@@ -119,7 +120,7 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
/* send initial metadata if it's available */
if (!sent_initial_metadata && s->send_initial_metadata) {
grpc_chttp2_encode_header(
- &t->hpack_compressor, s->id, s->send_initial_metadata, 0,
+ exec_ctx, &t->hpack_compressor, s->id, s->send_initial_metadata, 0,
t->settings[GRPC_ACKED_SETTINGS][GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
&s->stats.outgoing, &t->outbuf);
s->send_initial_metadata = NULL;
@@ -186,9 +187,9 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
&s->stats.outgoing, &t->outbuf);
} else {
grpc_chttp2_encode_header(
- &t->hpack_compressor, s->id, s->send_trailing_metadata, true,
- t->settings[GRPC_ACKED_SETTINGS]
- [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
+ exec_ctx, &t->hpack_compressor, s->id, s->send_trailing_metadata,
+ true, t->settings[GRPC_ACKED_SETTINGS]
+ [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
&s->stats.outgoing, &t->outbuf);
}
s->send_trailing_metadata = NULL;
@@ -254,7 +255,7 @@ void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
}
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:end");
}
- grpc_slice_buffer_reset_and_unref(&t->outbuf);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &t->outbuf);
GRPC_ERROR_UNREF(error);
GPR_TIMER_END("grpc_chttp2_end_write", 0);
}
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index a4c110101e..cf9a35194a 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -567,7 +567,7 @@ static void convert_metadata_to_cronet_headers(
curr = head;
size_t num_headers = 0;
while (num_headers < num_headers_available) {
- grpc_mdelem *mdelem = curr->md;
+ grpc_mdelem mdelem = curr->md;
curr = curr->next;
const char *key = grpc_mdstr_as_c_string(mdelem->key);
const char *value = grpc_mdstr_as_c_string(mdelem->value);
diff --git a/src/core/lib/channel/channel_args.c b/src/core/lib/channel/channel_args.c
index 401a2ad4fe..1a099ac437 100644
--- a/src/core/lib/channel/channel_args.c
+++ b/src/core/lib/channel/channel_args.c
@@ -184,7 +184,7 @@ grpc_channel_args *grpc_channel_args_normalize(const grpc_channel_args *a) {
return b;
}
-void grpc_channel_args_destroy(grpc_channel_args *a) {
+void grpc_channel_args_destroy(grpc_exec_ctx *exec_ctx, grpc_channel_args *a) {
size_t i;
if (!a) return;
for (i = 0; i < a->num_args; i++) {
@@ -195,7 +195,8 @@ void grpc_channel_args_destroy(grpc_channel_args *a) {
case GRPC_ARG_INTEGER:
break;
case GRPC_ARG_POINTER:
- a->args[i].value.pointer.vtable->destroy(a->args[i].value.pointer.p);
+ a->args[i].value.pointer.vtable->destroy(exec_ctx,
+ a->args[i].value.pointer.p);
break;
}
gpr_free(a->args[i].key);
@@ -249,7 +250,8 @@ static int find_compression_algorithm_states_bitset(const grpc_channel_args *a,
}
grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
- grpc_channel_args **a, grpc_compression_algorithm algorithm, int state) {
+ grpc_exec_ctx *exec_ctx, grpc_channel_args **a,
+ grpc_compression_algorithm algorithm, int state) {
int *states_arg = NULL;
grpc_channel_args *result = *a;
const int states_arg_found =
@@ -282,7 +284,7 @@ grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
GPR_BITCLEAR((unsigned *)&tmp.value.integer, algorithm);
}
result = grpc_channel_args_copy_and_add(*a, &tmp, 1);
- grpc_channel_args_destroy(*a);
+ grpc_channel_args_destroy(exec_ctx, *a);
*a = result;
}
return result;
diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h
index 88fc0e37a3..5c7d31f8bb 100644
--- a/src/core/lib/channel/channel_args.h
+++ b/src/core/lib/channel/channel_args.h
@@ -68,7 +68,7 @@ grpc_channel_args *grpc_channel_args_merge(const grpc_channel_args *a,
const grpc_channel_args *b);
/** Destroy arguments created by \a grpc_channel_args_copy */
-void grpc_channel_args_destroy(grpc_channel_args *a);
+void grpc_channel_args_destroy(grpc_exec_ctx *exec_ctx, grpc_channel_args *a);
/** Returns the compression algorithm set in \a a. */
grpc_compression_algorithm grpc_channel_args_get_compression_algorithm(
@@ -88,7 +88,8 @@ grpc_channel_args *grpc_channel_args_set_compression_algorithm(
* modified to point to the returned instance (which may be different from the
* input value of \a a). */
grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
- grpc_channel_args **a, grpc_compression_algorithm algorithm, int enabled);
+ grpc_exec_ctx *exec_ctx, grpc_channel_args **a,
+ grpc_compression_algorithm algorithm, int enabled);
/** Returns the bitset representing the support state (true for enabled, false
* for disabled) for compression algorithms.
diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c
index 999ad5f507..0f3957d5ac 100644
--- a/src/core/lib/channel/channel_stack.c
+++ b/src/core/lib/channel/channel_stack.c
@@ -162,7 +162,7 @@ grpc_error *grpc_call_stack_init(
grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack,
int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg,
grpc_call_context_element *context, const void *transport_server_data,
- grpc_mdstr *path, gpr_timespec start_time, gpr_timespec deadline,
+ grpc_slice path, gpr_timespec start_time, gpr_timespec deadline,
grpc_call_stack *call_stack) {
grpc_channel_element *channel_elems = CHANNEL_ELEMS_FROM_STACK(channel_stack);
grpc_call_element_args args;
@@ -300,7 +300,7 @@ void grpc_call_element_send_cancel_with_message(grpc_exec_ctx *exec_ctx,
grpc_transport_stream_op *op = gpr_malloc(sizeof(*op));
memset(op, 0, sizeof(*op));
op->on_complete = grpc_closure_create(destroy_op, op);
- grpc_transport_stream_op_add_cancellation_with_message(op, status,
+ grpc_transport_stream_op_add_cancellation_with_message(exec_ctx, op, status,
optional_message);
elem->filter->start_transport_stream_op(exec_ctx, elem, op);
}
@@ -312,6 +312,6 @@ void grpc_call_element_send_close_with_message(grpc_exec_ctx *exec_ctx,
grpc_transport_stream_op *op = gpr_malloc(sizeof(*op));
memset(op, 0, sizeof(*op));
op->on_complete = grpc_closure_create(destroy_op, op);
- grpc_transport_stream_op_add_close(op, status, optional_message);
+ grpc_transport_stream_op_add_close(exec_ctx, op, status, optional_message);
elem->filter->start_transport_stream_op(exec_ctx, elem, op);
}
diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h
index 004643d45f..376756533b 100644
--- a/src/core/lib/channel/channel_stack.h
+++ b/src/core/lib/channel/channel_stack.h
@@ -74,7 +74,7 @@ typedef struct {
grpc_call_stack *call_stack;
const void *server_transport_data;
grpc_call_context_element *context;
- grpc_mdstr *path;
+ grpc_slice path;
gpr_timespec start_time;
gpr_timespec deadline;
} grpc_call_element_args;
@@ -231,7 +231,7 @@ grpc_error *grpc_call_stack_init(
grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack,
int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg,
grpc_call_context_element *context, const void *transport_server_data,
- grpc_mdstr *path, gpr_timespec start_time, gpr_timespec deadline,
+ grpc_slice path, gpr_timespec start_time, gpr_timespec deadline,
grpc_call_stack *call_stack);
/* Set a pollset or a pollset_set for a call stack: must occur before the first
* op is started */
diff --git a/src/core/lib/channel/channel_stack_builder.c b/src/core/lib/channel/channel_stack_builder.c
index eda4968f48..366bd0de29 100644
--- a/src/core/lib/channel/channel_stack_builder.c
+++ b/src/core/lib/channel/channel_stack_builder.c
@@ -138,9 +138,10 @@ void grpc_channel_stack_builder_set_name(grpc_channel_stack_builder *builder,
}
void grpc_channel_stack_builder_set_channel_arguments(
- grpc_channel_stack_builder *builder, const grpc_channel_args *args) {
+ grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder,
+ const grpc_channel_args *args) {
if (builder->args != NULL) {
- grpc_channel_args_destroy(builder->args);
+ grpc_channel_args_destroy(exec_ctx, builder->args);
}
builder->args = grpc_channel_args_copy(args);
}
@@ -213,7 +214,8 @@ bool grpc_channel_stack_builder_add_filter_after(
return true;
}
-void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder) {
+void grpc_channel_stack_builder_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder) {
filter_node *p = builder->begin.next;
while (p != &builder->end) {
filter_node *next = p->next;
@@ -221,7 +223,7 @@ void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder) {
p = next;
}
if (builder->args != NULL) {
- grpc_channel_args_destroy(builder->args);
+ grpc_channel_args_destroy(exec_ctx, builder->args);
}
gpr_free(builder->target);
gpr_free(builder);
@@ -270,7 +272,7 @@ void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx,
i++;
}
- grpc_channel_stack_builder_destroy(builder);
+ grpc_channel_stack_builder_destroy(exec_ctx, builder);
gpr_free((grpc_channel_filter **)filters);
return result;
diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h
index 4a00f7bfdb..3532819a0c 100644
--- a/src/core/lib/channel/channel_stack_builder.h
+++ b/src/core/lib/channel/channel_stack_builder.h
@@ -73,7 +73,8 @@ grpc_transport *grpc_channel_stack_builder_get_transport(
/// Set channel arguments: copies args
void grpc_channel_stack_builder_set_channel_arguments(
- grpc_channel_stack_builder *builder, const grpc_channel_args *args);
+ grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder,
+ const grpc_channel_args *args);
/// Return a borrowed pointer to the channel arguments
const grpc_channel_args *grpc_channel_stack_builder_get_channel_arguments(
@@ -158,7 +159,8 @@ void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx,
void *destroy_arg);
/// Destroy the builder without creating a channel stack
-void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder);
+void grpc_channel_stack_builder_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder);
extern int grpc_trace_channel_stack_builder;
diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c
index 2874d63fc7..e04f3dc7db 100644
--- a/src/core/lib/channel/compress_filter.c
+++ b/src/core/lib/channel/compress_filter.c
@@ -44,6 +44,8 @@
#include "src/core/lib/compression/algorithm_metadata.h"
#include "src/core/lib/compression/message_compress.h"
#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/transport/static_metadata.h"
@@ -82,30 +84,34 @@ typedef struct channel_data {
/** For each \a md element from the incoming metadata, filter out the entry for
* "grpc-encoding", using its value to populate the call data's
* compression_algorithm field. */
-static grpc_mdelem *compression_md_filter(void *user_data, grpc_mdelem *md) {
+static grpc_mdelem compression_md_filter(grpc_exec_ctx *exec_ctx,
+ void *user_data, grpc_mdelem md) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
channel_data *channeld = elem->channel_data;
- if (md->key == GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST) {
- const char *md_c_str = grpc_mdstr_as_c_string(md->value);
- if (!grpc_compression_algorithm_parse(md_c_str, strlen(md_c_str),
+ if (grpc_slice_cmp(GRPC_MDKEY(md),
+ GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST) == 0) {
+ if (!grpc_compression_algorithm_parse(GRPC_MDVALUE(md),
&calld->compression_algorithm)) {
+ char *val = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_ASCII);
gpr_log(GPR_ERROR,
- "Invalid compression algorithm: '%s' (unknown). Ignoring.",
- md_c_str);
+ "Invalid compression algorithm: '%s' (unknown). Ignoring.", val);
+ gpr_free(val);
calld->compression_algorithm = GRPC_COMPRESS_NONE;
}
if (!GPR_BITGET(channeld->enabled_algorithms_bitset,
calld->compression_algorithm)) {
+ char *val = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_ASCII);
gpr_log(GPR_ERROR,
"Invalid compression algorithm: '%s' (previously disabled). "
"Ignoring.",
- md_c_str);
+ val);
+ gpr_free(val);
calld->compression_algorithm = GRPC_COMPRESS_NONE;
}
calld->has_compression_algorithm = 1;
- return NULL;
+ return GRPC_MDNULL;
}
return md;
@@ -130,12 +136,14 @@ static int skip_compression(grpc_call_element *elem, uint32_t flags) {
/** Filter initial metadata */
static void process_send_initial_metadata(
- grpc_call_element *elem, grpc_metadata_batch *initial_metadata) {
+ grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+ grpc_metadata_batch *initial_metadata) {
call_data *calld = elem->call_data;
channel_data *channeld = elem->channel_data;
/* Parse incoming request for compression. If any, it'll be available
* at calld->compression_algorithm */
- grpc_metadata_batch_filter(initial_metadata, compression_md_filter, elem);
+ grpc_metadata_batch_filter(exec_ctx, initial_metadata, compression_md_filter,
+ elem);
if (!calld->has_compression_algorithm) {
/* If no algorithm was found in the metadata and we aren't
* exceptionally skipping compression, fall back to the channel
@@ -161,7 +169,7 @@ static void continue_send_message(grpc_exec_ctx *exec_ctx,
static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
grpc_call_element *elem = elemp;
call_data *calld = elem->call_data;
- grpc_slice_buffer_reset_and_unref(&calld->slices);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &calld->slices);
calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, error);
}
@@ -171,8 +179,8 @@ static void finish_send_message(grpc_exec_ctx *exec_ctx,
int did_compress;
grpc_slice_buffer tmp;
grpc_slice_buffer_init(&tmp);
- did_compress =
- grpc_msg_compress(calld->compression_algorithm, &calld->slices, &tmp);
+ did_compress = grpc_msg_compress(exec_ctx, calld->compression_algorithm,
+ &calld->slices, &tmp);
if (did_compress) {
if (grpc_compression_trace) {
char *algo_name;
@@ -199,7 +207,7 @@ static void finish_send_message(grpc_exec_ctx *exec_ctx,
}
}
- grpc_slice_buffer_destroy(&tmp);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &tmp);
grpc_slice_buffer_stream_init(&calld->replacement_stream, &calld->slices,
calld->send_flags);
@@ -243,7 +251,7 @@ static void compress_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
GPR_TIMER_BEGIN("compress_start_transport_stream_op", 0);
if (op->send_initial_metadata) {
- process_send_initial_metadata(elem, op->send_initial_metadata);
+ process_send_initial_metadata(exec_ctx, elem, op->send_initial_metadata);
}
if (op->send_message != NULL &&
!skip_compression(elem, op->send_message->flags)) {
@@ -281,7 +289,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
void *ignored) {
/* grab pointers to our data from the call element */
call_data *calld = elem->call_data;
- grpc_slice_buffer_destroy(&calld->slices);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &calld->slices);
}
/* Constructor for channel_data */
diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c
index 038e819f72..ba2c7fcb0a 100644
--- a/src/core/lib/channel/connected_channel.c
+++ b/src/core/lib/channel/connected_channel.c
@@ -170,7 +170,8 @@ static void bind_transport(grpc_channel_stack *channel_stack,
channel_stack->call_stack_size += grpc_transport_stream_size(t);
}
-bool grpc_add_connected_filter(grpc_channel_stack_builder *builder,
+bool grpc_add_connected_filter(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder,
void *arg_must_be_null) {
GPR_ASSERT(arg_must_be_null == NULL);
grpc_transport *t = grpc_channel_stack_builder_get_transport(builder);
diff --git a/src/core/lib/channel/connected_channel.h b/src/core/lib/channel/connected_channel.h
index 3142d647b7..3585c0ecbc 100644
--- a/src/core/lib/channel/connected_channel.h
+++ b/src/core/lib/channel/connected_channel.h
@@ -36,7 +36,8 @@
#include "src/core/lib/channel/channel_stack_builder.h"
-bool grpc_add_connected_filter(grpc_channel_stack_builder *builder,
+bool grpc_add_connected_filter(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder,
void *arg_must_be_null);
#endif /* GRPC_CORE_LIB_CHANNEL_CONNECTED_CHANNEL_H */
diff --git a/src/core/lib/channel/deadline_filter.c b/src/core/lib/channel/deadline_filter.c
index 0e703d8d27..0293c34237 100644
--- a/src/core/lib/channel/deadline_filter.c
+++ b/src/core/lib/channel/deadline_filter.c
@@ -41,6 +41,7 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/timer.h"
+#include "src/core/lib/slice/slice_internal.h"
//
// grpc_deadline_state
@@ -58,7 +59,7 @@ static void timer_callback(grpc_exec_ctx* exec_ctx, void* arg,
grpc_slice msg = grpc_slice_from_static_string("Deadline Exceeded");
grpc_call_element_send_cancel_with_message(
exec_ctx, elem, GRPC_STATUS_DEADLINE_EXCEEDED, &msg);
- grpc_slice_unref(msg);
+ grpc_slice_unref_internal(exec_ctx, msg);
}
GRPC_CALL_STACK_UNREF(exec_ctx, deadline_state->call_stack, "deadline_timer");
}
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index dbe0d25211..fea6c9b345 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -37,6 +37,8 @@
#include <string.h>
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/slice/percent_encoding.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/transport/static_metadata.h"
#include "src/core/lib/transport/transport_impl.h"
@@ -87,47 +89,46 @@ typedef struct call_data {
} call_data;
typedef struct channel_data {
- grpc_mdelem *static_scheme;
- grpc_mdelem *user_agent;
+ grpc_mdelem static_scheme;
+ grpc_mdelem user_agent;
size_t max_payload_size_for_get;
} channel_data;
-typedef struct {
- grpc_call_element *elem;
- grpc_exec_ctx *exec_ctx;
-} client_recv_filter_args;
-
-static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) {
- client_recv_filter_args *a = user_data;
- if (md == GRPC_MDELEM_STATUS_200) {
- return NULL;
- } else if (md->key == GRPC_MDSTR_STATUS) {
+static grpc_mdelem client_recv_filter(grpc_exec_ctx *exec_ctx, void *user_data,
+ grpc_mdelem md) {
+ grpc_call_element *elem = user_data;
+ if (grpc_mdelem_eq(md, GRPC_MDELEM_STATUS_200)) {
+ return GRPC_MDNULL;
+ } else if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_STATUS) == 0) {
char *message_string;
- gpr_asprintf(&message_string, "Received http2 header with status: %s",
- grpc_mdstr_as_c_string(md->value));
+ char *val = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_ASCII);
+ gpr_asprintf(&message_string, "Received http2 header with status: %s", val);
grpc_slice message = grpc_slice_from_copied_string(message_string);
gpr_free(message_string);
- grpc_call_element_send_close_with_message(a->exec_ctx, a->elem,
+ gpr_free(val);
+ grpc_call_element_send_close_with_message(exec_ctx, elem,
GRPC_STATUS_CANCELLED, &message);
- return NULL;
- } else if (md->key == GRPC_MDSTR_GRPC_MESSAGE) {
+ return GRPC_MDNULL;
+ } else if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_MESSAGE) == 0) {
grpc_slice pct_decoded_msg =
- grpc_permissive_percent_decode_slice(md->value->slice);
- if (grpc_slice_is_equivalent(pct_decoded_msg, md->value->slice)) {
+ grpc_permissive_percent_decode_slice(GRPC_MDVALUE(md));
+ if (grpc_slice_is_equivalent(pct_decoded_msg, GRPC_MDVALUE(md))) {
grpc_slice_unref(pct_decoded_msg);
return md;
} else {
- return grpc_mdelem_from_metadata_strings(
- GRPC_MDSTR_GRPC_MESSAGE, grpc_mdstr_from_slice(pct_decoded_msg));
+ return grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
+ pct_decoded_msg);
}
- } else if (md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) {
- return NULL;
- } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) {
- const char *value_str = grpc_mdstr_as_c_string(md->value);
- if (strncmp(value_str, EXPECTED_CONTENT_TYPE,
- EXPECTED_CONTENT_TYPE_LENGTH) == 0 &&
- (value_str[EXPECTED_CONTENT_TYPE_LENGTH] == '+' ||
- value_str[EXPECTED_CONTENT_TYPE_LENGTH] == ';')) {
+ } else if (grpc_mdelem_eq(md,
+ GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) {
+ return GRPC_MDNULL;
+ } else if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_CONTENT_TYPE) == 0) {
+ if (grpc_slice_buf_start_eq(GRPC_MDVALUE(md), EXPECTED_CONTENT_TYPE,
+ EXPECTED_CONTENT_TYPE_LENGTH) &&
+ (GRPC_SLICE_START_PTR(GRPC_MDVALUE(md))[EXPECTED_CONTENT_TYPE_LENGTH] ==
+ '+' ||
+ GRPC_SLICE_START_PTR(GRPC_MDVALUE(md))[EXPECTED_CONTENT_TYPE_LENGTH] ==
+ ';')) {
/* Although the C implementation doesn't (currently) generate them,
any custom +-suffix is explicitly valid. */
/* TODO(klempner): We should consider preallocating common values such
@@ -136,9 +137,11 @@ static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) {
} else {
/* TODO(klempner): We're currently allowing this, but we shouldn't
see it without a proxy so log for now. */
- gpr_log(GPR_INFO, "Unexpected content-type '%s'", value_str);
+ char *val = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_ASCII);
+ gpr_log(GPR_INFO, "Unexpected content-type '%s'", val);
+ gpr_free(val);
}
- return NULL;
+ return GRPC_MDNULL;
}
return md;
}
@@ -147,11 +150,8 @@ static void hc_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx,
void *user_data, grpc_error *error) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
- client_recv_filter_args a;
- a.elem = elem;
- a.exec_ctx = exec_ctx;
- grpc_metadata_batch_filter(calld->recv_initial_metadata, client_recv_filter,
- &a);
+ grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata,
+ client_recv_filter, elem);
grpc_closure_run(exec_ctx, calld->on_done_recv_initial_metadata,
GRPC_ERROR_REF(error));
}
@@ -160,11 +160,8 @@ static void hc_on_recv_trailing_metadata(grpc_exec_ctx *exec_ctx,
void *user_data, grpc_error *error) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
- client_recv_filter_args a;
- a.elem = elem;
- a.exec_ctx = exec_ctx;
- grpc_metadata_batch_filter(calld->recv_trailing_metadata, client_recv_filter,
- &a);
+ grpc_metadata_batch_filter(exec_ctx, calld->recv_trailing_metadata,
+ client_recv_filter, elem);
grpc_closure_run(exec_ctx, calld->on_done_recv_trailing_metadata,
GRPC_ERROR_REF(error));
}
@@ -183,17 +180,22 @@ static void hc_on_complete(grpc_exec_ctx *exec_ctx, void *user_data,
static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
grpc_call_element *elem = elemp;
call_data *calld = elem->call_data;
- grpc_slice_buffer_reset_and_unref(&calld->slices);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &calld->slices);
calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, error);
}
-static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) {
+static grpc_mdelem client_strip_filter(grpc_exec_ctx *exec_ctx, void *user_data,
+ grpc_mdelem md) {
/* eat the things we'd like to set ourselves */
- if (md->key == GRPC_MDSTR_METHOD) return NULL;
- if (md->key == GRPC_MDSTR_SCHEME) return NULL;
- if (md->key == GRPC_MDSTR_TE) return NULL;
- if (md->key == GRPC_MDSTR_CONTENT_TYPE) return NULL;
- if (md->key == GRPC_MDSTR_USER_AGENT) return NULL;
+ if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_METHOD) == 0)
+ return GRPC_MDNULL;
+ if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_SCHEME) == 0)
+ return GRPC_MDNULL;
+ if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_TE) == 0) return GRPC_MDNULL;
+ if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_CONTENT_TYPE) == 0)
+ return GRPC_MDNULL;
+ if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_USER_AGENT) == 0)
+ return GRPC_MDNULL;
return md;
}
@@ -244,7 +246,7 @@ static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
cacheable, and the operation contains both initial metadata and send
message, and the payload is below the size threshold, and all the data
for this request is immediately available. */
- grpc_mdelem *method = GRPC_MDELEM_METHOD_POST;
+ grpc_mdelem method = GRPC_MDELEM_METHOD_POST;
calld->send_message_blocked = false;
if ((op->send_initial_metadata_flags &
GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) &&
@@ -258,7 +260,7 @@ static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
}
/* Attempt to read the data from send_message and create a header field. */
- if (method == GRPC_MDELEM_METHOD_GET) {
+ if (grpc_mdelem_eq(method, GRPC_MDELEM_METHOD_GET)) {
/* allocate memory to hold the entire payload */
calld->payload_bytes = gpr_malloc(op->send_message->length);
@@ -271,10 +273,10 @@ static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
if (calld->send_message_blocked == false) {
/* when all the send_message data is available, then create a MDELEM and
append to headers */
- grpc_mdelem *payload_bin = grpc_mdelem_from_metadata_strings(
- GRPC_MDSTR_GRPC_PAYLOAD_BIN,
- grpc_mdstr_from_buffer(calld->payload_bytes,
- op->send_message->length));
+ grpc_mdelem payload_bin = grpc_mdelem_from_slices(
+ exec_ctx, GRPC_MDSTR_GRPC_PAYLOAD_BIN,
+ grpc_slice_from_copied_buffer((const char *)calld->payload_bytes,
+ op->send_message->length));
grpc_metadata_batch_add_tail(op->send_initial_metadata,
&calld->payload_bin, payload_bin);
calld->on_complete = op->on_complete;
@@ -289,8 +291,8 @@ static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
}
}
- grpc_metadata_batch_filter(op->send_initial_metadata, client_strip_filter,
- elem);
+ grpc_metadata_batch_filter(exec_ctx, op->send_initial_metadata,
+ client_strip_filter, elem);
/* Send : prefixed headers, which have to be before any application
layer headers. */
grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->method,
@@ -363,21 +365,21 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info,
void *ignored) {
call_data *calld = elem->call_data;
- grpc_slice_buffer_destroy(&calld->slices);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &calld->slices);
}
-static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) {
+static grpc_mdelem scheme_from_args(const grpc_channel_args *args) {
unsigned i;
size_t j;
- grpc_mdelem *valid_schemes[] = {GRPC_MDELEM_SCHEME_HTTP,
- GRPC_MDELEM_SCHEME_HTTPS};
+ grpc_mdelem valid_schemes[] = {GRPC_MDELEM_SCHEME_HTTP,
+ GRPC_MDELEM_SCHEME_HTTPS};
if (args != NULL) {
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 == strcmp(grpc_mdstr_as_c_string(valid_schemes[j]->value),
- args->args[i].value.string)) {
+ if (0 == grpc_slice_str_cmp(GRPC_MDVALUE(valid_schemes[j]),
+ args->args[i].value.string)) {
return valid_schemes[j];
}
}
@@ -403,13 +405,13 @@ static size_t max_payload_size_from_args(const grpc_channel_args *args) {
return kMaxPayloadSizeForGet;
}
-static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args,
- const char *transport_name) {
+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_mdstr *result;
+ grpc_slice result;
gpr_strvec_init(&v);
@@ -447,7 +449,7 @@ static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args,
tmp = gpr_strvec_flatten(&v, NULL);
gpr_strvec_destroy(&v);
- result = grpc_mdstr_from_string(tmp);
+ result = grpc_slice_intern(grpc_slice_from_static_string(tmp));
gpr_free(tmp);
return result;
@@ -463,8 +465,8 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
chand->static_scheme = scheme_from_args(args->channel_args);
chand->max_payload_size_for_get =
max_payload_size_from_args(args->channel_args);
- chand->user_agent = grpc_mdelem_from_metadata_strings(
- GRPC_MDSTR_USER_AGENT,
+ chand->user_agent = grpc_mdelem_from_slices(
+ exec_ctx, GRPC_MDSTR_USER_AGENT,
user_agent_from_args(args->channel_args,
args->optional_transport->vtable->name));
}
@@ -473,7 +475,7 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
channel_data *chand = elem->channel_data;
- GRPC_MDELEM_UNREF(chand->user_agent);
+ GRPC_MDELEM_UNREF(exec_ctx, chand->user_agent);
}
const grpc_channel_filter grpc_http_client_filter = {
diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c
index b42ff06039..0d11c71d06 100644
--- a/src/core/lib/channel/http_server_filter.c
+++ b/src/core/lib/channel/http_server_filter.c
@@ -38,6 +38,8 @@
#include <string.h>
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/slice/percent_encoding.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/transport/static_metadata.h"
#define EXPECTED_CONTENT_TYPE "application/grpc"
@@ -82,63 +84,63 @@ typedef struct call_data {
typedef struct channel_data { uint8_t unused; } channel_data;
-typedef struct {
- grpc_call_element *elem;
- grpc_exec_ctx *exec_ctx;
-} server_filter_args;
-
-static grpc_mdelem *server_filter_outgoing_metadata(void *user_data,
- grpc_mdelem *md) {
- if (md->key == GRPC_MDSTR_GRPC_MESSAGE) {
+static grpc_mdelem server_filter_outgoing_metadata(grpc_exec_ctx *exec_ctx,
+ void *user_data,
+ grpc_mdelem md) {
+ if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_MESSAGE) == 0) {
grpc_slice pct_encoded_msg = grpc_percent_encode_slice(
- md->value->slice, grpc_compatible_percent_encoding_unreserved_bytes);
- if (grpc_slice_is_equivalent(pct_encoded_msg, md->value->slice)) {
- grpc_slice_unref(pct_encoded_msg);
+ GRPC_MDVALUE(md), grpc_compatible_percent_encoding_unreserved_bytes);
+ if (grpc_slice_is_equivalent(pct_encoded_msg, GRPC_MDVALUE(md))) {
+ grpc_slice_unref_internal(exec_ctx, pct_encoded_msg);
return md;
} else {
- return grpc_mdelem_from_metadata_strings(
- GRPC_MDSTR_GRPC_MESSAGE, grpc_mdstr_from_slice(pct_encoded_msg));
+ return grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
+ pct_encoded_msg);
}
} else {
return md;
}
}
-static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
- server_filter_args *a = user_data;
- grpc_call_element *elem = a->elem;
+static grpc_mdelem server_filter(grpc_exec_ctx *exec_ctx, void *user_data,
+ grpc_mdelem md) {
+ grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
/* Check if it is one of the headers we care about. */
- if (md == GRPC_MDELEM_TE_TRAILERS || md == GRPC_MDELEM_METHOD_POST ||
- md == GRPC_MDELEM_METHOD_PUT || md == GRPC_MDELEM_METHOD_GET ||
- md == GRPC_MDELEM_SCHEME_HTTP || md == GRPC_MDELEM_SCHEME_HTTPS ||
- md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) {
+ if (grpc_mdelem_eq(md, GRPC_MDELEM_TE_TRAILERS) ||
+ grpc_mdelem_eq(md, GRPC_MDELEM_METHOD_POST) ||
+ grpc_mdelem_eq(md, GRPC_MDELEM_METHOD_PUT) ||
+ grpc_mdelem_eq(md, GRPC_MDELEM_METHOD_GET) ||
+ grpc_mdelem_eq(md, GRPC_MDELEM_SCHEME_HTTP) ||
+ grpc_mdelem_eq(md, GRPC_MDELEM_SCHEME_HTTPS) ||
+ grpc_mdelem_eq(md, GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) {
/* swallow it */
- if (md == GRPC_MDELEM_METHOD_POST) {
+ if (grpc_mdelem_eq(md, GRPC_MDELEM_METHOD_POST)) {
calld->seen_method = 1;
*calld->recv_idempotent_request = false;
*calld->recv_cacheable_request = false;
- } else if (md == GRPC_MDELEM_METHOD_PUT) {
+ } else if (grpc_mdelem_eq(md, GRPC_MDELEM_METHOD_PUT)) {
calld->seen_method = 1;
*calld->recv_idempotent_request = true;
- } else if (md == GRPC_MDELEM_METHOD_GET) {
+ } else if (grpc_mdelem_eq(md, GRPC_MDELEM_METHOD_GET)) {
calld->seen_method = 1;
*calld->recv_cacheable_request = true;
- } else if (md->key == GRPC_MDSTR_SCHEME) {
+ } else if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_SCHEME) == 0) {
calld->seen_scheme = 1;
- } else if (md == GRPC_MDELEM_TE_TRAILERS) {
+ } else if (grpc_mdelem_eq(md, GRPC_MDELEM_TE_TRAILERS)) {
calld->seen_te_trailers = 1;
}
/* TODO(klempner): Track that we've seen all the headers we should
require */
- return NULL;
- } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) {
- const char *value_str = grpc_mdstr_as_c_string(md->value);
- if (strncmp(value_str, EXPECTED_CONTENT_TYPE,
- EXPECTED_CONTENT_TYPE_LENGTH) == 0 &&
- (value_str[EXPECTED_CONTENT_TYPE_LENGTH] == '+' ||
- value_str[EXPECTED_CONTENT_TYPE_LENGTH] == ';')) {
+ return GRPC_MDNULL;
+ } else if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_CONTENT_TYPE) == 0) {
+ if (grpc_slice_buf_start_eq(GRPC_MDVALUE(md), EXPECTED_CONTENT_TYPE,
+ EXPECTED_CONTENT_TYPE_LENGTH) &&
+ (GRPC_SLICE_START_PTR(GRPC_MDVALUE(md))[EXPECTED_CONTENT_TYPE_LENGTH] ==
+ '+' ||
+ GRPC_SLICE_START_PTR(GRPC_MDVALUE(md))[EXPECTED_CONTENT_TYPE_LENGTH] ==
+ ';')) {
/* Although the C implementation doesn't (currently) generate them,
any custom +-suffix is explicitly valid. */
/* TODO(klempner): We should consider preallocating common values such
@@ -147,44 +149,50 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
} else {
/* TODO(klempner): We're currently allowing this, but we shouldn't
see it without a proxy so log for now. */
- gpr_log(GPR_INFO, "Unexpected content-type '%s'", value_str);
+ char *val = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_ASCII);
+ gpr_log(GPR_INFO, "Unexpected content-type '%s'", val);
+ gpr_free(val);
}
- return NULL;
- } else if (md->key == GRPC_MDSTR_TE || md->key == GRPC_MDSTR_METHOD ||
- md->key == GRPC_MDSTR_SCHEME) {
- gpr_log(GPR_ERROR, "Invalid %s: header: '%s'",
- grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value));
+ return GRPC_MDNULL;
+ } else if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_TE) == 0 ||
+ grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_METHOD) == 0 ||
+ grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_SCHEME) == 0) {
+ char *key = grpc_dump_slice(GRPC_MDKEY(md), GPR_DUMP_ASCII);
+ char *value = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_ASCII);
+ gpr_log(GPR_ERROR, "Invalid %s: header: '%s'", key, value);
/* swallow it and error everything out. */
/* TODO(klempner): We ought to generate more descriptive error messages
on the wire here. */
- grpc_call_element_send_cancel(a->exec_ctx, elem);
- return NULL;
- } else if (md->key == GRPC_MDSTR_PATH) {
+ gpr_free(key);
+ gpr_free(value);
+ grpc_call_element_send_cancel(exec_ctx, elem);
+ return GRPC_MDNULL;
+ } else if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_PATH) == 0) {
if (calld->seen_path) {
gpr_log(GPR_ERROR, "Received :path twice");
- return NULL;
+ return GRPC_MDNULL;
}
calld->seen_path = 1;
return md;
- } else if (md->key == GRPC_MDSTR_AUTHORITY) {
+ } else if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_AUTHORITY) == 0) {
calld->seen_authority = 1;
return md;
- } else if (md->key == GRPC_MDSTR_HOST) {
+ } else if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_HOST) == 0) {
/* translate host to :authority since :authority may be
omitted */
- grpc_mdelem *authority = grpc_mdelem_from_metadata_strings(
- GRPC_MDSTR_AUTHORITY, GRPC_MDSTR_REF(md->value));
+ grpc_mdelem authority = grpc_mdelem_from_slices(
+ exec_ctx, GRPC_MDSTR_AUTHORITY, grpc_slice_ref(GRPC_MDVALUE(md)));
calld->seen_authority = 1;
return authority;
- } else if (md->key == GRPC_MDSTR_GRPC_PAYLOAD_BIN) {
+ } else if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_PAYLOAD_BIN) == 0) {
/* Retrieve the payload from the value of the 'grpc-internal-payload-bin'
header field */
calld->seen_payload_bin = 1;
grpc_slice_buffer_add(&calld->read_slice_buffer,
- grpc_slice_ref(md->value->slice));
+ grpc_slice_ref_internal(GRPC_MDVALUE(md)));
grpc_slice_buffer_stream_init(&calld->read_stream,
&calld->read_slice_buffer, 0);
- return NULL;
+ return GRPC_MDNULL;
} else {
return md;
}
@@ -195,10 +203,8 @@ static void hs_on_recv(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
if (err == GRPC_ERROR_NONE) {
- server_filter_args a;
- a.elem = elem;
- a.exec_ctx = exec_ctx;
- grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, &a);
+ grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata,
+ server_filter, elem);
/* Have we seen the required http2 transport headers?
(:method, :scheme, content-type, with :path and :authority covered
at the channel level right now) */
@@ -310,9 +316,8 @@ static void hs_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
}
if (op->send_trailing_metadata) {
- server_filter_args a = {elem, exec_ctx};
- grpc_metadata_batch_filter(op->send_trailing_metadata,
- server_filter_outgoing_metadata, &a);
+ grpc_metadata_batch_filter(exec_ctx, op->send_trailing_metadata,
+ server_filter_outgoing_metadata, elem);
}
}
@@ -346,7 +351,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info,
void *ignored) {
call_data *calld = elem->call_data;
- grpc_slice_buffer_destroy(&calld->read_slice_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &calld->read_slice_buffer);
}
/* Constructor for channel_data */
diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/lib/channel/message_size_filter.c
index 1cf68d790d..debd41cca2 100644
--- a/src/core/lib/channel/message_size_filter.c
+++ b/src/core/lib/channel/message_size_filter.c
@@ -54,8 +54,12 @@ static void* message_size_limits_copy(void* value) {
return new_value;
}
-static const grpc_mdstr_hash_table_vtable message_size_limits_vtable = {
- gpr_free, message_size_limits_copy};
+static void message_size_limits_free(grpc_exec_ctx* exec_ctx, void* value) {
+ gpr_free(value);
+}
+
+static const grpc_slice_hash_table_vtable message_size_limits_vtable = {
+ message_size_limits_free, message_size_limits_copy};
static void* message_size_limits_create_from_json(const grpc_json* json) {
int max_request_message_bytes = -1;
@@ -97,7 +101,7 @@ typedef struct channel_data {
int max_send_size;
int max_recv_size;
// Maps path names to message_size_limits structs.
- grpc_mdstr_hash_table* method_limit_table;
+ grpc_slice_hash_table* method_limit_table;
} channel_data;
// Callback invoked when we receive a message. Here we check the max
@@ -168,8 +172,8 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
calld->max_send_size = chand->max_send_size;
calld->max_recv_size = chand->max_recv_size;
if (chand->method_limit_table != NULL) {
- message_size_limits* limits =
- grpc_method_config_table_get(chand->method_limit_table, args->path);
+ message_size_limits* limits = grpc_method_config_table_get(
+ exec_ctx, chand->method_limit_table, args->path);
if (limits != NULL) {
if (limits->max_send_size >= 0 &&
(limits->max_send_size < calld->max_send_size ||
@@ -226,7 +230,7 @@ static void init_channel_elem(grpc_exec_ctx* exec_ctx,
if (service_config != NULL) {
chand->method_limit_table =
grpc_service_config_create_method_config_table(
- service_config, message_size_limits_create_from_json,
+ exec_ctx, service_config, message_size_limits_create_from_json,
&message_size_limits_vtable);
grpc_service_config_destroy(service_config);
}
@@ -237,7 +241,7 @@ static void init_channel_elem(grpc_exec_ctx* exec_ctx,
static void destroy_channel_elem(grpc_exec_ctx* exec_ctx,
grpc_channel_element* elem) {
channel_data* chand = elem->channel_data;
- grpc_mdstr_hash_table_unref(chand->method_limit_table);
+ grpc_slice_hash_table_unref(exec_ctx, chand->method_limit_table);
}
const grpc_channel_filter grpc_message_size_filter = {
diff --git a/src/core/lib/compression/algorithm_metadata.h b/src/core/lib/compression/algorithm_metadata.h
index 1f9cc15f23..58dfe628b4 100644
--- a/src/core/lib/compression/algorithm_metadata.h
+++ b/src/core/lib/compression/algorithm_metadata.h
@@ -38,16 +38,16 @@
#include "src/core/lib/transport/metadata.h"
/** Return compression algorithm based metadata value */
-grpc_mdstr *grpc_compression_algorithm_mdstr(
+grpc_slice grpc_compression_algorithm_slice(
grpc_compression_algorithm algorithm);
/** Return compression algorithm based metadata element (grpc-encoding: xxx) */
-grpc_mdelem *grpc_compression_encoding_mdelem(
+grpc_mdelem grpc_compression_encoding_mdelem(
grpc_compression_algorithm algorithm);
/** Find compression algorithm based on passed in mdstr - returns
* GRPC_COMPRESS_ALGORITHM_COUNT on failure */
-grpc_compression_algorithm grpc_compression_algorithm_from_mdstr(
- grpc_mdstr *str);
+grpc_compression_algorithm grpc_compression_algorithm_from_slice(
+ grpc_slice str);
#endif /* GRPC_CORE_LIB_COMPRESSION_ALGORITHM_METADATA_H */
diff --git a/src/core/lib/compression/compression.c b/src/core/lib/compression/compression.c
index 54efb5e855..f8777a6f6c 100644
--- a/src/core/lib/compression/compression.c
+++ b/src/core/lib/compression/compression.c
@@ -41,30 +41,24 @@
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/transport/static_metadata.h"
-int grpc_compression_algorithm_parse(const char *name, size_t name_length,
+int grpc_compression_algorithm_parse(grpc_slice name,
grpc_compression_algorithm *algorithm) {
/* we use strncmp not only because it's safer (even though in this case it
* doesn't matter, given that we are comparing against string literals, but
* because this way we needn't have "name" nil-terminated (useful for slice
* data, for example) */
- GRPC_API_TRACE(
- "grpc_compression_algorithm_parse("
- "name=%*.*s, name_length=%lu, algorithm=%p)",
- 5, ((int)name_length, (int)name_length, name, (unsigned long)name_length,
- algorithm));
- if (name_length == 0) {
- return 0;
- }
- if (strncmp(name, "identity", name_length) == 0) {
+ if (grpc_slice_cmp(name, GRPC_MDSTR_IDENTITY) == 0) {
*algorithm = GRPC_COMPRESS_NONE;
- } else if (strncmp(name, "gzip", name_length) == 0) {
+ return 1;
+ } else if (grpc_slice_cmp(name, GRPC_MDSTR_GZIP) == 0) {
*algorithm = GRPC_COMPRESS_GZIP;
- } else if (strncmp(name, "deflate", name_length) == 0) {
+ return 1;
+ } else if (grpc_slice_cmp(name, GRPC_MDSTR_DEFLATE) == 0) {
*algorithm = GRPC_COMPRESS_DEFLATE;
+ return 1;
} else {
return 0;
}
- return 1;
}
int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
@@ -87,15 +81,16 @@ int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
return 0;
}
-grpc_compression_algorithm grpc_compression_algorithm_from_mdstr(
- grpc_mdstr *str) {
- if (str == GRPC_MDSTR_IDENTITY) return GRPC_COMPRESS_NONE;
- if (str == GRPC_MDSTR_DEFLATE) return GRPC_COMPRESS_DEFLATE;
- if (str == GRPC_MDSTR_GZIP) return GRPC_COMPRESS_GZIP;
+grpc_compression_algorithm grpc_compression_algorithm_from_slice(
+ grpc_slice str) {
+ if (grpc_slice_cmp(str, GRPC_MDSTR_IDENTITY) == 0) return GRPC_COMPRESS_NONE;
+ if (grpc_slice_cmp(str, GRPC_MDSTR_DEFLATE) == 0)
+ return GRPC_COMPRESS_DEFLATE;
+ if (grpc_slice_cmp(str, GRPC_MDSTR_GZIP) == 0) return GRPC_COMPRESS_GZIP;
return GRPC_COMPRESS_ALGORITHMS_COUNT;
}
-grpc_mdstr *grpc_compression_algorithm_mdstr(
+grpc_slice grpc_compression_algorithm_slice(
grpc_compression_algorithm algorithm) {
switch (algorithm) {
case GRPC_COMPRESS_NONE:
@@ -105,12 +100,12 @@ grpc_mdstr *grpc_compression_algorithm_mdstr(
case GRPC_COMPRESS_GZIP:
return GRPC_MDSTR_GZIP;
case GRPC_COMPRESS_ALGORITHMS_COUNT:
- return NULL;
+ return grpc_empty_slice();
}
- return NULL;
+ return grpc_empty_slice();
}
-grpc_mdelem *grpc_compression_encoding_mdelem(
+grpc_mdelem grpc_compression_encoding_mdelem(
grpc_compression_algorithm algorithm) {
switch (algorithm) {
case GRPC_COMPRESS_NONE:
@@ -122,7 +117,7 @@ grpc_mdelem *grpc_compression_encoding_mdelem(
default:
break;
}
- return NULL;
+ return GRPC_MDNULL;
}
void grpc_compression_options_init(grpc_compression_options *opts) {
diff --git a/src/core/lib/compression/message_compress.c b/src/core/lib/compression/message_compress.c
index 6c245acf61..49beb953b0 100644
--- a/src/core/lib/compression/message_compress.c
+++ b/src/core/lib/compression/message_compress.c
@@ -40,10 +40,12 @@
#include <zlib.h>
+#include "src/core/lib/slice/slice_internal.h"
+
#define OUTPUT_BLOCK_SIZE 1024
-static int zlib_body(z_stream* zs, grpc_slice_buffer* input,
- grpc_slice_buffer* output,
+static int zlib_body(grpc_exec_ctx* exec_ctx, z_stream* zs,
+ grpc_slice_buffer* input, grpc_slice_buffer* output,
int (*flate)(z_stream* zs, int flush)) {
int r;
int flush;
@@ -87,7 +89,7 @@ static int zlib_body(z_stream* zs, grpc_slice_buffer* input,
return 1;
error:
- grpc_slice_unref(outbuf);
+ grpc_slice_unref_internal(exec_ctx, outbuf);
return 0;
}
@@ -97,8 +99,8 @@ static void* zalloc_gpr(void* opaque, unsigned int items, unsigned int size) {
static void zfree_gpr(void* opaque, void* address) { gpr_free(address); }
-static int zlib_compress(grpc_slice_buffer* input, grpc_slice_buffer* output,
- int gzip) {
+static int zlib_compress(grpc_exec_ctx* exec_ctx, grpc_slice_buffer* input,
+ grpc_slice_buffer* output, int gzip) {
z_stream zs;
int r;
size_t i;
@@ -110,10 +112,11 @@ static int zlib_compress(grpc_slice_buffer* input, grpc_slice_buffer* output,
r = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 | (gzip ? 16 : 0),
8, Z_DEFAULT_STRATEGY);
GPR_ASSERT(r == Z_OK);
- r = zlib_body(&zs, input, output, deflate) && output->length < input->length;
+ r = zlib_body(exec_ctx, &zs, input, output, deflate) &&
+ output->length < input->length;
if (!r) {
for (i = count_before; i < output->count; i++) {
- grpc_slice_unref(output->slices[i]);
+ grpc_slice_unref_internal(exec_ctx, output->slices[i]);
}
output->count = count_before;
output->length = length_before;
@@ -122,8 +125,8 @@ static int zlib_compress(grpc_slice_buffer* input, grpc_slice_buffer* output,
return r;
}
-static int zlib_decompress(grpc_slice_buffer* input, grpc_slice_buffer* output,
- int gzip) {
+static int zlib_decompress(grpc_exec_ctx* exec_ctx, grpc_slice_buffer* input,
+ grpc_slice_buffer* output, int gzip) {
z_stream zs;
int r;
size_t i;
@@ -134,10 +137,10 @@ static int zlib_decompress(grpc_slice_buffer* input, grpc_slice_buffer* output,
zs.zfree = zfree_gpr;
r = inflateInit2(&zs, 15 | (gzip ? 16 : 0));
GPR_ASSERT(r == Z_OK);
- r = zlib_body(&zs, input, output, inflate);
+ r = zlib_body(exec_ctx, &zs, input, output, inflate);
if (!r) {
for (i = count_before; i < output->count; i++) {
- grpc_slice_unref(output->slices[i]);
+ grpc_slice_unref_internal(exec_ctx, output->slices[i]);
}
output->count = count_before;
output->length = length_before;
@@ -149,12 +152,13 @@ static int zlib_decompress(grpc_slice_buffer* input, grpc_slice_buffer* output,
static int copy(grpc_slice_buffer* input, grpc_slice_buffer* output) {
size_t i;
for (i = 0; i < input->count; i++) {
- grpc_slice_buffer_add(output, grpc_slice_ref(input->slices[i]));
+ grpc_slice_buffer_add(output, grpc_slice_ref_internal(input->slices[i]));
}
return 1;
}
-static int compress_inner(grpc_compression_algorithm algorithm,
+static int compress_inner(grpc_exec_ctx* exec_ctx,
+ grpc_compression_algorithm algorithm,
grpc_slice_buffer* input, grpc_slice_buffer* output) {
switch (algorithm) {
case GRPC_COMPRESS_NONE:
@@ -162,9 +166,9 @@ static int compress_inner(grpc_compression_algorithm algorithm,
rely on that here */
return 0;
case GRPC_COMPRESS_DEFLATE:
- return zlib_compress(input, output, 0);
+ return zlib_compress(exec_ctx, input, output, 0);
case GRPC_COMPRESS_GZIP:
- return zlib_compress(input, output, 1);
+ return zlib_compress(exec_ctx, input, output, 1);
case GRPC_COMPRESS_ALGORITHMS_COUNT:
break;
}
@@ -172,24 +176,26 @@ static int compress_inner(grpc_compression_algorithm algorithm,
return 0;
}
-int grpc_msg_compress(grpc_compression_algorithm algorithm,
+int grpc_msg_compress(grpc_exec_ctx* exec_ctx,
+ grpc_compression_algorithm algorithm,
grpc_slice_buffer* input, grpc_slice_buffer* output) {
- if (!compress_inner(algorithm, input, output)) {
+ if (!compress_inner(exec_ctx, algorithm, input, output)) {
copy(input, output);
return 0;
}
return 1;
}
-int grpc_msg_decompress(grpc_compression_algorithm algorithm,
+int grpc_msg_decompress(grpc_exec_ctx* exec_ctx,
+ grpc_compression_algorithm algorithm,
grpc_slice_buffer* input, grpc_slice_buffer* output) {
switch (algorithm) {
case GRPC_COMPRESS_NONE:
return copy(input, output);
case GRPC_COMPRESS_DEFLATE:
- return zlib_decompress(input, output, 0);
+ return zlib_decompress(exec_ctx, input, output, 0);
case GRPC_COMPRESS_GZIP:
- return zlib_decompress(input, output, 1);
+ return zlib_decompress(exec_ctx, input, output, 1);
case GRPC_COMPRESS_ALGORITHMS_COUNT:
break;
}
diff --git a/src/core/lib/compression/message_compress.h b/src/core/lib/compression/message_compress.h
index 448d36a863..7bd3d98607 100644
--- a/src/core/lib/compression/message_compress.h
+++ b/src/core/lib/compression/message_compress.h
@@ -40,13 +40,15 @@
/* compress 'input' to 'output' using 'algorithm'.
On success, appends compressed slices to output and returns 1.
On failure, appends uncompressed slices to output and returns 0. */
-int grpc_msg_compress(grpc_compression_algorithm algorithm,
+int grpc_msg_compress(grpc_exec_ctx* exec_ctx,
+ grpc_compression_algorithm algorithm,
grpc_slice_buffer* input, grpc_slice_buffer* output);
/* decompress 'input' to 'output' using 'algorithm'.
On success, appends slices to output and returns 1.
On failure, output is unchanged, and returns 0. */
-int grpc_msg_decompress(grpc_compression_algorithm algorithm,
+int grpc_msg_decompress(grpc_exec_ctx* exec_ctx,
+ grpc_compression_algorithm algorithm,
grpc_slice_buffer* input, grpc_slice_buffer* output);
#endif /* GRPC_CORE_LIB_COMPRESSION_MESSAGE_COMPRESS_H */
diff --git a/src/core/lib/http/httpcli.c b/src/core/lib/http/httpcli.c
index fdb8abaa2d..6bab7ef275 100644
--- a/src/core/lib/http/httpcli.c
+++ b/src/core/lib/http/httpcli.c
@@ -47,6 +47,7 @@
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/tcp_client.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/support/string.h"
typedef struct {
@@ -111,14 +112,14 @@ static void finish(grpc_exec_ctx *exec_ctx, internal_request *req,
if (req->ep != NULL) {
grpc_endpoint_destroy(exec_ctx, req->ep);
}
- grpc_slice_unref(req->request_text);
+ grpc_slice_unref_internal(exec_ctx, req->request_text);
gpr_free(req->host);
gpr_free(req->ssl_host_override);
grpc_iomgr_unregister_object(&req->iomgr_obj);
- grpc_slice_buffer_destroy(&req->incoming);
- grpc_slice_buffer_destroy(&req->outgoing);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &req->incoming);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &req->outgoing);
GRPC_ERROR_UNREF(req->overall_error);
- grpc_resource_quota_internal_unref(exec_ctx, req->resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, req->resource_quota);
gpr_free(req);
}
@@ -178,7 +179,7 @@ static void done_write(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
}
static void start_write(grpc_exec_ctx *exec_ctx, internal_request *req) {
- grpc_slice_ref(req->request_text);
+ grpc_slice_ref_internal(req->request_text);
grpc_slice_buffer_add(&req->outgoing, req->request_text);
grpc_endpoint_write(exec_ctx, req->ep, &req->outgoing, &req->done_write);
}
@@ -265,7 +266,7 @@ static void internal_request_begin(grpc_exec_ctx *exec_ctx,
req->context = context;
req->pollent = pollent;
req->overall_error = GRPC_ERROR_NONE;
- req->resource_quota = grpc_resource_quota_internal_ref(resource_quota);
+ req->resource_quota = grpc_resource_quota_ref_internal(resource_quota);
grpc_closure_init(&req->on_read, on_read, req);
grpc_closure_init(&req->done_write, done_write, req);
grpc_slice_buffer_init(&req->incoming);
diff --git a/src/core/lib/http/httpcli_security_connector.c b/src/core/lib/http/httpcli_security_connector.c
index 24d264c32a..e8575d4e6e 100644
--- a/src/core/lib/http/httpcli_security_connector.c
+++ b/src/core/lib/http/httpcli_security_connector.c
@@ -48,7 +48,8 @@ typedef struct {
char *secure_peer_name;
} grpc_httpcli_ssl_channel_security_connector;
-static void httpcli_ssl_destroy(grpc_security_connector *sc) {
+static void httpcli_ssl_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_security_connector *sc) {
grpc_httpcli_ssl_channel_security_connector *c =
(grpc_httpcli_ssl_channel_security_connector *)sc;
if (c->handshaker_factory != NULL) {
@@ -111,8 +112,9 @@ static grpc_security_connector_vtable httpcli_ssl_vtable = {
httpcli_ssl_destroy, httpcli_ssl_check_peer};
static grpc_security_status httpcli_ssl_channel_security_connector_create(
- const unsigned char *pem_root_certs, size_t pem_root_certs_size,
- const char *secure_peer_name, grpc_channel_security_connector **sc) {
+ grpc_exec_ctx *exec_ctx, const unsigned char *pem_root_certs,
+ size_t pem_root_certs_size, const char *secure_peer_name,
+ grpc_channel_security_connector **sc) {
tsi_result result = TSI_OK;
grpc_httpcli_ssl_channel_security_connector *c;
@@ -136,7 +138,7 @@ static grpc_security_status httpcli_ssl_channel_security_connector_create(
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
- httpcli_ssl_destroy(&c->base.base);
+ httpcli_ssl_destroy(exec_ctx, &c->base.base);
*sc = NULL;
return GRPC_SECURITY_ERROR;
}
@@ -184,11 +186,11 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
c->func = on_done;
c->arg = arg;
GPR_ASSERT(httpcli_ssl_channel_security_connector_create(
- pem_root_certs, pem_root_certs_size, host, &sc) ==
+ exec_ctx, pem_root_certs, pem_root_certs_size, host, &sc) ==
GRPC_SECURITY_OK);
grpc_channel_security_connector_do_handshake(
exec_ctx, sc, tcp, NULL, deadline, on_secure_transport_setup_done, c);
- GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli");
+ GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &sc->base, "httpcli");
}
const grpc_httpcli_handshaker grpc_httpcli_ssl = {"https", ssl_handshake};
diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h
index 2b4b271eaa..ec0114a2a4 100644
--- a/src/core/lib/iomgr/closure.h
+++ b/src/core/lib/iomgr/closure.h
@@ -35,6 +35,8 @@
#define GRPC_CORE_LIB_IOMGR_CLOSURE_H
#include <grpc/support/port_platform.h>
+
+#include <grpc/impl/codegen/exec_ctx_fwd.h>
#include <stdbool.h>
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/support/mpscq.h"
@@ -42,10 +44,6 @@
struct grpc_closure;
typedef struct grpc_closure grpc_closure;
-/* forward declaration for exec_ctx.h */
-struct grpc_exec_ctx;
-typedef struct grpc_exec_ctx grpc_exec_ctx;
-
typedef struct grpc_closure_list {
grpc_closure *head;
grpc_closure *tail;
diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c
index 91041a7c28..86674ca8c6 100644
--- a/src/core/lib/iomgr/ev_epoll_linux.c
+++ b/src/core/lib/iomgr/ev_epoll_linux.c
@@ -31,7 +31,6 @@
*
*/
-#include <grpc/grpc_posix.h>
#include "src/core/lib/iomgr/port.h"
/* This polling engine is only relevant on linux kernels supporting epoll() */
diff --git a/src/core/lib/iomgr/ev_posix.c b/src/core/lib/iomgr/ev_posix.c
index ab139895fd..e148416760 100644
--- a/src/core/lib/iomgr/ev_posix.c
+++ b/src/core/lib/iomgr/ev_posix.c
@@ -52,6 +52,8 @@
* tests */
grpc_poll_function_type grpc_poll_function = poll;
+grpc_wakeup_fd grpc_global_wakeup_fd;
+
static const grpc_event_engine_vtable *g_event_engine;
static const char *g_poll_strategy_name = NULL;
diff --git a/src/core/lib/iomgr/executor.c b/src/core/lib/iomgr/executor.c
index 8d7535d6fe..4e78b619fb 100644
--- a/src/core/lib/iomgr/executor.c
+++ b/src/core/lib/iomgr/executor.c
@@ -121,9 +121,8 @@ void grpc_executor_push(grpc_closure *closure, grpc_error *error) {
gpr_mu_unlock(&g_executor.mu);
}
-void grpc_executor_shutdown() {
+void grpc_executor_shutdown(grpc_exec_ctx *exec_ctx) {
int pending_join;
- grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_mu_lock(&g_executor.mu);
pending_join = g_executor.pending_join;
@@ -133,8 +132,7 @@ void grpc_executor_shutdown() {
* list below because we aren't accepting new work */
/* Execute pending callbacks, some may be performing cleanups */
- grpc_exec_ctx_enqueue_list(&exec_ctx, &g_executor.closures, NULL);
- grpc_exec_ctx_finish(&exec_ctx);
+ grpc_exec_ctx_enqueue_list(exec_ctx, &g_executor.closures, NULL);
GPR_ASSERT(grpc_closure_list_empty(g_executor.closures));
if (pending_join) {
gpr_thd_join(g_executor.tid);
diff --git a/src/core/lib/iomgr/executor.h b/src/core/lib/iomgr/executor.h
index da9dcd07d0..7bf8f21940 100644
--- a/src/core/lib/iomgr/executor.h
+++ b/src/core/lib/iomgr/executor.h
@@ -48,6 +48,6 @@ void grpc_executor_init();
void grpc_executor_push(grpc_closure *closure, grpc_error *error);
/** Shutdown the executor, running all pending work as part of the call */
-void grpc_executor_shutdown();
+void grpc_executor_shutdown(grpc_exec_ctx *exec_ctx);
#endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_H */
diff --git a/src/core/lib/iomgr/iomgr.c b/src/core/lib/iomgr/iomgr.c
index 4fd83e0b22..8a233d0ba8 100644
--- a/src/core/lib/iomgr/iomgr.c
+++ b/src/core/lib/iomgr/iomgr.c
@@ -83,11 +83,10 @@ static void dump_objects(const char *kind) {
}
}
-void grpc_iomgr_shutdown(void) {
+void grpc_iomgr_shutdown(grpc_exec_ctx *exec_ctx) {
gpr_timespec shutdown_deadline = gpr_time_add(
gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(10, GPR_TIMESPAN));
gpr_timespec last_warning_time = gpr_now(GPR_CLOCK_REALTIME);
- grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_iomgr_platform_flush();
@@ -104,10 +103,9 @@ void grpc_iomgr_shutdown(void) {
}
last_warning_time = gpr_now(GPR_CLOCK_REALTIME);
}
- if (grpc_timer_check(&exec_ctx, gpr_inf_future(GPR_CLOCK_MONOTONIC),
- NULL)) {
+ if (grpc_timer_check(exec_ctx, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL)) {
gpr_mu_unlock(&g_mu);
- grpc_exec_ctx_flush(&exec_ctx);
+ grpc_exec_ctx_flush(exec_ctx);
gpr_mu_lock(&g_mu);
continue;
}
@@ -138,8 +136,8 @@ void grpc_iomgr_shutdown(void) {
}
gpr_mu_unlock(&g_mu);
- grpc_timer_list_shutdown(&exec_ctx);
- grpc_exec_ctx_finish(&exec_ctx);
+ grpc_timer_list_shutdown(exec_ctx);
+ grpc_exec_ctx_flush(exec_ctx);
/* ensure all threads have left g_mu */
gpr_mu_lock(&g_mu);
diff --git a/src/core/lib/iomgr/iomgr.h b/src/core/lib/iomgr/iomgr.h
index c1cfaf302e..245a1e08aa 100644
--- a/src/core/lib/iomgr/iomgr.h
+++ b/src/core/lib/iomgr/iomgr.h
@@ -34,12 +34,14 @@
#ifndef GRPC_CORE_LIB_IOMGR_IOMGR_H
#define GRPC_CORE_LIB_IOMGR_IOMGR_H
+#include <grpc/impl/codegen/exec_ctx_fwd.h>
#include "src/core/lib/iomgr/port.h"
/** Initializes the iomgr. */
void grpc_iomgr_init(void);
-/** Signals the intention to shutdown the iomgr. */
-void grpc_iomgr_shutdown(void);
+/** Signals the intention to shutdown the iomgr. Expects to be able to flush
+ * exec_ctx. */
+void grpc_iomgr_shutdown(grpc_exec_ctx *exec_ctx);
#endif /* GRPC_CORE_LIB_IOMGR_IOMGR_H */
diff --git a/src/core/lib/iomgr/load_file.c b/src/core/lib/iomgr/load_file.c
index 217bc5da59..f40c8b28cc 100644
--- a/src/core/lib/iomgr/load_file.c
+++ b/src/core/lib/iomgr/load_file.c
@@ -47,7 +47,7 @@ grpc_error *grpc_load_file(const char *filename, int add_null_terminator,
grpc_slice *output) {
unsigned char *contents = NULL;
size_t contents_size = 0;
- grpc_slice result = gpr_empty_slice();
+ grpc_slice result = grpc_empty_slice();
FILE *file;
size_t bytes_read = 0;
grpc_error *error = GRPC_ERROR_NONE;
diff --git a/src/core/lib/iomgr/resource_quota.c b/src/core/lib/iomgr/resource_quota.c
index 051a30baa3..3b63773071 100644
--- a/src/core/lib/iomgr/resource_quota.c
+++ b/src/core/lib/iomgr/resource_quota.c
@@ -247,14 +247,14 @@ static void rq_step(grpc_exec_ctx *exec_ctx, void *rq, grpc_error *error) {
}
done:
- grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
}
static void rq_step_sched(grpc_exec_ctx *exec_ctx,
grpc_resource_quota *resource_quota) {
if (resource_quota->step_scheduled) return;
resource_quota->step_scheduled = true;
- grpc_resource_quota_internal_ref(resource_quota);
+ grpc_resource_quota_ref_internal(resource_quota);
grpc_combiner_execute_finally(exec_ctx, resource_quota->combiner,
&resource_quota->rq_step_closure,
GRPC_ERROR_NONE, false);
@@ -335,7 +335,7 @@ static bool rq_reclaim(grpc_exec_ctx *exec_ctx,
destructive ? "destructive" : "benign");
}
resource_quota->reclaiming = true;
- grpc_resource_quota_internal_ref(resource_quota);
+ grpc_resource_quota_ref_internal(resource_quota);
grpc_closure *c = resource_user->reclaimers[destructive];
resource_user->reclaimers[destructive] = NULL;
grpc_closure_run(exec_ctx, c, GRPC_ERROR_NONE);
@@ -358,30 +358,21 @@ static void ru_slice_ref(void *p) {
gpr_ref(&rc->refs);
}
-static void ru_slice_unref(void *p) {
+static void ru_slice_unref(grpc_exec_ctx *exec_ctx, void *p) {
ru_slice_refcount *rc = p;
if (gpr_unref(&rc->refs)) {
- /* TODO(ctiller): this is dangerous, but I think safe for now:
- we have no guarantee here that we're at a safe point for creating an
- execution context, but we have no way of writing this code otherwise.
- In the future: consider lifting grpc_slice to grpc, and offering an
- internal_{ref,unref} pair that is execution context aware.
- Alternatively,
- make exec_ctx be thread local and 'do the right thing' (whatever that
- is)
- if NULL */
- grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- grpc_resource_user_free(&exec_ctx, rc->resource_user, rc->size);
- grpc_exec_ctx_finish(&exec_ctx);
+ grpc_resource_user_free(exec_ctx, rc->resource_user, rc->size);
gpr_free(rc);
}
}
+static const grpc_slice_refcount_vtable ru_slice_vtable = {
+ ru_slice_ref, ru_slice_unref, grpc_slice_default_hash_impl};
+
static grpc_slice ru_slice_create(grpc_resource_user *resource_user,
size_t size) {
ru_slice_refcount *rc = gpr_malloc(sizeof(ru_slice_refcount) + size);
- rc->base.ref = ru_slice_ref;
- rc->base.unref = ru_slice_unref;
+ rc->base.vtable = &ru_slice_vtable;
gpr_ref_init(&rc->refs, 1);
rc->resource_user = resource_user;
rc->size = size;
@@ -472,7 +463,7 @@ static void ru_destroy(grpc_exec_ctx *exec_ctx, void *ru, grpc_error *error) {
resource_user->resource_quota->free_pool += resource_user->free_pool;
rq_step_sched(exec_ctx, resource_user->resource_quota);
}
- grpc_resource_quota_internal_unref(exec_ctx, resource_user->resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, resource_user->resource_quota);
gpr_mu_destroy(&resource_user->mu);
gpr_free(resource_user->name);
gpr_free(resource_user);
@@ -508,7 +499,7 @@ static void rq_resize(grpc_exec_ctx *exec_ctx, void *args, grpc_error *error) {
a->resource_quota->size += delta;
a->resource_quota->free_pool += delta;
rq_step_sched(exec_ctx, a->resource_quota);
- grpc_resource_quota_internal_unref(exec_ctx, a->resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, a->resource_quota);
gpr_free(a);
}
@@ -517,7 +508,7 @@ static void rq_reclamation_done(grpc_exec_ctx *exec_ctx, void *rq,
grpc_resource_quota *resource_quota = rq;
resource_quota->reclaiming = false;
rq_step_sched(exec_ctx, resource_quota);
- grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
}
/*******************************************************************************
@@ -548,7 +539,7 @@ grpc_resource_quota *grpc_resource_quota_create(const char *name) {
return resource_quota;
}
-void grpc_resource_quota_internal_unref(grpc_exec_ctx *exec_ctx,
+void grpc_resource_quota_unref_internal(grpc_exec_ctx *exec_ctx,
grpc_resource_quota *resource_quota) {
if (gpr_unref(&resource_quota->refs)) {
grpc_combiner_destroy(exec_ctx, resource_quota->combiner);
@@ -560,11 +551,11 @@ void grpc_resource_quota_internal_unref(grpc_exec_ctx *exec_ctx,
/* Public API */
void grpc_resource_quota_unref(grpc_resource_quota *resource_quota) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
grpc_exec_ctx_finish(&exec_ctx);
}
-grpc_resource_quota *grpc_resource_quota_internal_ref(
+grpc_resource_quota *grpc_resource_quota_ref_internal(
grpc_resource_quota *resource_quota) {
gpr_ref(&resource_quota->refs);
return resource_quota;
@@ -572,7 +563,7 @@ grpc_resource_quota *grpc_resource_quota_internal_ref(
/* Public API */
void grpc_resource_quota_ref(grpc_resource_quota *resource_quota) {
- grpc_resource_quota_internal_ref(resource_quota);
+ grpc_resource_quota_ref_internal(resource_quota);
}
/* Public API */
@@ -580,7 +571,7 @@ void grpc_resource_quota_resize(grpc_resource_quota *resource_quota,
size_t size) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
rq_resize_args *a = gpr_malloc(sizeof(*a));
- a->resource_quota = grpc_resource_quota_internal_ref(resource_quota);
+ a->resource_quota = grpc_resource_quota_ref_internal(resource_quota);
a->size = (int64_t)size;
grpc_closure_init(&a->closure, rq_resize, a);
grpc_combiner_execute(&exec_ctx, resource_quota->combiner, &a->closure,
@@ -597,7 +588,7 @@ grpc_resource_quota *grpc_resource_quota_from_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_internal_ref(
+ return grpc_resource_quota_ref_internal(
channel_args->args[i].value.pointer.p);
} else {
gpr_log(GPR_DEBUG, GRPC_ARG_RESOURCE_QUOTA " should be a pointer");
@@ -612,7 +603,9 @@ static void *rq_copy(void *rq) {
return rq;
}
-static void rq_destroy(void *rq) { grpc_resource_quota_unref(rq); }
+static void rq_destroy(grpc_exec_ctx *exec_ctx, void *rq) {
+ grpc_resource_quota_unref_internal(exec_ctx, rq);
+}
static int rq_cmp(void *a, void *b) { return GPR_ICMP(a, b); }
@@ -629,7 +622,7 @@ grpc_resource_user *grpc_resource_user_create(
grpc_resource_quota *resource_quota, const char *name) {
grpc_resource_user *resource_user = gpr_malloc(sizeof(*resource_user));
resource_user->resource_quota =
- grpc_resource_quota_internal_ref(resource_quota);
+ grpc_resource_quota_ref_internal(resource_quota);
grpc_closure_init(&resource_user->allocate_closure, &ru_allocate,
resource_user);
grpc_closure_init(&resource_user->add_to_free_pool_closure,
diff --git a/src/core/lib/iomgr/resource_quota.h b/src/core/lib/iomgr/resource_quota.h
index 0181fd978b..ef286c2fce 100644
--- a/src/core/lib/iomgr/resource_quota.h
+++ b/src/core/lib/iomgr/resource_quota.h
@@ -77,9 +77,9 @@
extern int grpc_resource_quota_trace;
-grpc_resource_quota *grpc_resource_quota_internal_ref(
+grpc_resource_quota *grpc_resource_quota_ref_internal(
grpc_resource_quota *resource_quota);
-void grpc_resource_quota_internal_unref(grpc_exec_ctx *exec_ctx,
+void grpc_resource_quota_unref_internal(grpc_exec_ctx *exec_ctx,
grpc_resource_quota *resource_quota);
grpc_resource_quota *grpc_resource_quota_from_channel_args(
const grpc_channel_args *channel_args);
diff --git a/src/core/lib/iomgr/socket_mutator.c b/src/core/lib/iomgr/socket_mutator.c
index 8b1efb6bab..34b61dcfe5 100644
--- a/src/core/lib/iomgr/socket_mutator.c
+++ b/src/core/lib/iomgr/socket_mutator.c
@@ -76,7 +76,7 @@ static void *socket_mutator_arg_copy(void *p) {
return grpc_socket_mutator_ref(p);
}
-static void socket_mutator_arg_destroy(void *p) {
+static void socket_mutator_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
grpc_socket_mutator_unref(p);
}
diff --git a/src/core/lib/iomgr/tcp_client_posix.c b/src/core/lib/iomgr/tcp_client_posix.c
index 13347735df..7e49d89aa8 100644
--- a/src/core/lib/iomgr/tcp_client_posix.c
+++ b/src/core/lib/iomgr/tcp_client_posix.c
@@ -128,7 +128,7 @@ static void tc_on_alarm(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
if (done) {
gpr_mu_destroy(&ac->mu);
gpr_free(ac->addr_str);
- grpc_channel_args_destroy(ac->channel_args);
+ grpc_channel_args_destroy(exec_ctx, ac->channel_args);
gpr_free(ac);
}
}
@@ -148,8 +148,8 @@ grpc_endpoint *grpc_tcp_client_create_from_fd(
&channel_args->args[i], options);
} else if (0 ==
strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
- grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
- resource_quota = grpc_resource_quota_internal_ref(
+ grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
+ resource_quota = grpc_resource_quota_ref_internal(
channel_args->args[i].value.pointer.p);
}
}
@@ -157,7 +157,7 @@ grpc_endpoint *grpc_tcp_client_create_from_fd(
grpc_endpoint *ep =
grpc_tcp_create(fd, resource_quota, tcp_read_chunk_size, addr_str);
- grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
return ep;
}
@@ -259,7 +259,7 @@ finish:
if (done) {
gpr_mu_destroy(&ac->mu);
gpr_free(ac->addr_str);
- grpc_channel_args_destroy(ac->channel_args);
+ grpc_channel_args_destroy(exec_ctx, ac->channel_args);
gpr_free(ac);
}
grpc_exec_ctx_sched(exec_ctx, closure, error, NULL);
diff --git a/src/core/lib/iomgr/tcp_client_windows.c b/src/core/lib/iomgr/tcp_client_windows.c
index 4d1e809872..4ad417f77d 100644
--- a/src/core/lib/iomgr/tcp_client_windows.c
+++ b/src/core/lib/iomgr/tcp_client_windows.c
@@ -71,7 +71,7 @@ static void async_connect_unlock_and_cleanup(grpc_exec_ctx *exec_ctx,
int done = (--ac->refs == 0);
gpr_mu_unlock(&ac->mu);
if (done) {
- grpc_resource_quota_internal_unref(exec_ctx, ac->resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, ac->resource_quota);
gpr_mu_destroy(&ac->mu);
gpr_free(ac->addr_name);
gpr_free(ac);
@@ -153,8 +153,8 @@ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done,
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_internal_unref(exec_ctx, resource_quota);
- resource_quota = grpc_resource_quota_internal_ref(
+ grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
+ resource_quota = grpc_resource_quota_ref_internal(
channel_args->args[i].value.pointer.p);
}
}
@@ -242,7 +242,7 @@ failure:
} else if (sock != INVALID_SOCKET) {
closesocket(sock);
}
- grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
grpc_exec_ctx_sched(exec_ctx, on_done, final_error, NULL);
}
diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c
index 12a4797e6f..ba288c768e 100644
--- a/src/core/lib/iomgr/tcp_posix.c
+++ b/src/core/lib/iomgr/tcp_posix.c
@@ -56,6 +56,7 @@
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
@@ -121,7 +122,7 @@ static void tcp_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
static void tcp_free(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
grpc_fd_orphan(exec_ctx, tcp->em_fd, tcp->release_fd_cb, tcp->release_fd,
"tcp_unref_orphan");
- grpc_slice_buffer_destroy(&tcp->last_read_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &tcp->last_read_buffer);
grpc_resource_user_unref(exec_ctx, tcp->resource_user);
gpr_free(tcp->peer_string);
gpr_free(tcp);
@@ -162,7 +163,7 @@ static void tcp_ref(grpc_tcp *tcp) { gpr_ref(&tcp->refcount); }
static void tcp_destroy(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
grpc_network_status_unregister_endpoint(ep);
grpc_tcp *tcp = (grpc_tcp *)ep;
- grpc_slice_buffer_reset_and_unref(&tcp->last_read_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &tcp->last_read_buffer);
TCP_UNREF(exec_ctx, tcp, "destroy");
}
@@ -229,13 +230,14 @@ static void tcp_do_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
/* We've consumed the edge, request a new one */
grpc_fd_notify_on_read(exec_ctx, tcp->em_fd, &tcp->read_closure);
} else {
- grpc_slice_buffer_reset_and_unref(tcp->incoming_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
+ tcp->incoming_buffer);
call_read_cb(exec_ctx, tcp, GRPC_OS_ERROR(errno, "recvmsg"));
TCP_UNREF(exec_ctx, tcp, "read");
}
} else if (read_bytes == 0) {
/* 0 read size ==> end of stream */
- grpc_slice_buffer_reset_and_unref(tcp->incoming_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, tcp->incoming_buffer);
call_read_cb(exec_ctx, tcp, GRPC_ERROR_CREATE("Socket closed"));
TCP_UNREF(exec_ctx, tcp, "read");
} else {
@@ -260,8 +262,9 @@ static void tcp_read_allocation_done(grpc_exec_ctx *exec_ctx, void *tcpp,
grpc_error *error) {
grpc_tcp *tcp = tcpp;
if (error != GRPC_ERROR_NONE) {
- grpc_slice_buffer_reset_and_unref(tcp->incoming_buffer);
- grpc_slice_buffer_reset_and_unref(&tcp->last_read_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, tcp->incoming_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
+ &tcp->last_read_buffer);
call_read_cb(exec_ctx, tcp, GRPC_ERROR_REF(error));
TCP_UNREF(exec_ctx, tcp, "read");
} else {
@@ -286,8 +289,9 @@ static void tcp_handle_read(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */,
GPR_ASSERT(!tcp->finished_edge);
if (error != GRPC_ERROR_NONE) {
- grpc_slice_buffer_reset_and_unref(tcp->incoming_buffer);
- grpc_slice_buffer_reset_and_unref(&tcp->last_read_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, tcp->incoming_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
+ &tcp->last_read_buffer);
call_read_cb(exec_ctx, tcp, GRPC_ERROR_REF(error));
TCP_UNREF(exec_ctx, tcp, "read");
} else {
@@ -301,7 +305,7 @@ static void tcp_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
GPR_ASSERT(tcp->read_cb == NULL);
tcp->read_cb = cb;
tcp->incoming_buffer = incoming_buffer;
- grpc_slice_buffer_reset_and_unref(incoming_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, incoming_buffer);
grpc_slice_buffer_swap(incoming_buffer, &tcp->last_read_buffer);
TCP_REF(tcp, "read");
if (tcp->finished_edge) {
@@ -565,7 +569,7 @@ void grpc_tcp_destroy_and_release_fd(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
GPR_ASSERT(ep->vtable == &vtable);
tcp->release_fd = fd;
tcp->release_fd_cb = done;
- grpc_slice_buffer_reset_and_unref(&tcp->last_read_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &tcp->last_read_buffer);
TCP_UNREF(exec_ctx, tcp, "destroy");
}
diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c
index 7e2fb0f1f9..c8401d442e 100644
--- a/src/core/lib/iomgr/tcp_server_posix.c
+++ b/src/core/lib/iomgr/tcp_server_posix.c
@@ -167,18 +167,18 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
s->so_reuseport =
has_so_reuseport && (args->args[i].value.integer != 0);
} else {
- grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
gpr_free(s);
return GRPC_ERROR_CREATE(GRPC_ARG_ALLOW_REUSEPORT
" must be an integer");
}
} else if (0 == strcmp(GRPC_ARG_RESOURCE_QUOTA, args->args[i].key)) {
if (args->args[i].type == GRPC_ARG_POINTER) {
- grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
s->resource_quota =
- grpc_resource_quota_internal_ref(args->args[i].value.pointer.p);
+ grpc_resource_quota_ref_internal(args->args[i].value.pointer.p);
} else {
- grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
gpr_free(s);
return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
" must be a pointer to a buffer pool");
@@ -219,7 +219,7 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
gpr_free(sp);
}
- grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
gpr_free(s);
}
diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index ae54c70d2d..c2a6d1736e 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -115,11 +115,11 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
for (size_t i = 0; i < (args == NULL ? 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_internal_unref(exec_ctx, s->resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
s->resource_quota =
- grpc_resource_quota_internal_ref(args->args[i].value.pointer.p);
+ grpc_resource_quota_ref_internal(args->args[i].value.pointer.p);
} else {
- grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
gpr_free(s);
return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
" must be a pointer to a buffer pool");
@@ -155,7 +155,7 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
grpc_winsocket_destroy(sp->socket);
gpr_free(sp);
}
- grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
gpr_free(s);
}
diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c
index 62afbcef51..34afe51df0 100644
--- a/src/core/lib/iomgr/tcp_windows.c
+++ b/src/core/lib/iomgr/tcp_windows.c
@@ -174,13 +174,13 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *tcpp, grpc_error *error) {
char *utf8_message = gpr_format_message(info->wsa_error);
error = GRPC_ERROR_CREATE(utf8_message);
gpr_free(utf8_message);
- grpc_slice_unref(tcp->read_slice);
+ grpc_slice_unref_internal(exec_ctx, tcp->read_slice);
} else {
if (info->bytes_transfered != 0 && !tcp->shutting_down) {
sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered);
grpc_slice_buffer_add(tcp->read_slices, sub);
} else {
- grpc_slice_unref(tcp->read_slice);
+ grpc_slice_unref_internal(exec_ctx, tcp->read_slice);
error = GRPC_ERROR_CREATE("End of TCP stream");
}
}
@@ -209,7 +209,7 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
tcp->read_cb = cb;
tcp->read_slices = read_slices;
- grpc_slice_buffer_reset_and_unref(read_slices);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, read_slices);
tcp->read_slice = grpc_slice_malloc(8192);
diff --git a/src/core/lib/security/context/security_context.c b/src/core/lib/security/context/security_context.c
index 2204fadf54..fe82fabc31 100644
--- a/src/core/lib/security/context/security_context.c
+++ b/src/core/lib/security/context/security_context.c
@@ -47,6 +47,7 @@
grpc_call_error grpc_call_set_credentials(grpc_call *call,
grpc_call_credentials *creds) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_client_security_context *ctx = NULL;
GRPC_API_TRACE("grpc_call_set_credentials(call=%p, creds=%p)", 2,
(call, creds));
@@ -62,9 +63,10 @@ grpc_call_error grpc_call_set_credentials(grpc_call *call,
grpc_call_context_set(call, GRPC_CONTEXT_SECURITY, ctx,
grpc_client_security_context_destroy);
} else {
- grpc_call_credentials_unref(ctx->creds);
+ grpc_call_credentials_unref(&exec_ctx, ctx->creds);
ctx->creds = grpc_call_credentials_ref(creds);
}
+ grpc_exec_ctx_finish(&exec_ctx);
return GRPC_CALL_OK;
}
@@ -96,13 +98,15 @@ grpc_client_security_context *grpc_client_security_context_create(void) {
}
void grpc_client_security_context_destroy(void *ctx) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_client_security_context *c = (grpc_client_security_context *)ctx;
- grpc_call_credentials_unref(c->creds);
+ grpc_call_credentials_unref(&exec_ctx, c->creds);
GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "client_security_context");
if (c->extension.instance != NULL && c->extension.destroy != NULL) {
c->extension.destroy(c->extension.instance);
}
gpr_free(ctx);
+ grpc_exec_ctx_finish(&exec_ctx);
}
/* --- grpc_server_security_context --- */
@@ -307,7 +311,7 @@ void grpc_auth_property_reset(grpc_auth_property *property) {
memset(property, 0, sizeof(grpc_auth_property));
}
-static void auth_context_pointer_arg_destroy(void *p) {
+static void auth_context_pointer_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
GRPC_AUTH_CONTEXT_UNREF(p, "auth_context_pointer_arg");
}
diff --git a/src/core/lib/security/credentials/composite/composite_credentials.c b/src/core/lib/security/credentials/composite/composite_credentials.c
index d55d00b7b6..be1588dd8b 100644
--- a/src/core/lib/security/credentials/composite/composite_credentials.c
+++ b/src/core/lib/security/credentials/composite/composite_credentials.c
@@ -54,18 +54,20 @@ typedef struct {
grpc_credentials_metadata_cb cb;
} grpc_composite_call_credentials_metadata_context;
-static void composite_call_destruct(grpc_call_credentials *creds) {
+static void composite_call_destruct(grpc_exec_ctx *exec_ctx,
+ grpc_call_credentials *creds) {
grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds;
size_t i;
for (i = 0; i < c->inner.num_creds; i++) {
- grpc_call_credentials_unref(c->inner.creds_array[i]);
+ grpc_call_credentials_unref(exec_ctx, c->inner.creds_array[i]);
}
gpr_free(c->inner.creds_array);
}
static void composite_call_md_context_destroy(
+ grpc_exec_ctx *exec_ctx,
grpc_composite_call_credentials_metadata_context *ctx) {
- grpc_credentials_md_store_unref(ctx->md_elems);
+ grpc_credentials_md_store_unref(exec_ctx, ctx->md_elems);
gpr_free(ctx);
}
@@ -103,7 +105,7 @@ static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data,
/* We're done!. */
ctx->cb(exec_ctx, ctx->user_data, ctx->md_elems->entries,
ctx->md_elems->num_entries, GRPC_CREDENTIALS_OK, NULL);
- composite_call_md_context_destroy(ctx);
+ composite_call_md_context_destroy(exec_ctx, ctx);
}
static void composite_call_get_request_metadata(
@@ -209,17 +211,19 @@ grpc_call_credentials *grpc_credentials_contains_type(
/* -- Composite channel credentials. -- */
-static void composite_channel_destruct(grpc_channel_credentials *creds) {
+static void composite_channel_destruct(grpc_exec_ctx *exec_ctx,
+ grpc_channel_credentials *creds) {
grpc_composite_channel_credentials *c =
(grpc_composite_channel_credentials *)creds;
- grpc_channel_credentials_unref(c->inner_creds);
- grpc_call_credentials_unref(c->call_creds);
+ grpc_channel_credentials_unref(exec_ctx, c->inner_creds);
+ grpc_call_credentials_unref(exec_ctx, c->call_creds);
}
static grpc_security_status composite_channel_create_security_connector(
- grpc_channel_credentials *creds, grpc_call_credentials *call_creds,
- const char *target, const grpc_channel_args *args,
- grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+ grpc_exec_ctx *exec_ctx, grpc_channel_credentials *creds,
+ grpc_call_credentials *call_creds, const char *target,
+ const grpc_channel_args *args, grpc_channel_security_connector **sc,
+ grpc_channel_args **new_args) {
grpc_composite_channel_credentials *c =
(grpc_composite_channel_credentials *)creds;
grpc_security_status status = GRPC_SECURITY_ERROR;
@@ -233,11 +237,12 @@ static grpc_security_status composite_channel_create_security_connector(
grpc_call_credentials *composite_call_creds =
grpc_composite_call_credentials_create(c->call_creds, call_creds, NULL);
status = c->inner_creds->vtable->create_security_connector(
- c->inner_creds, composite_call_creds, target, args, sc, new_args);
- grpc_call_credentials_unref(composite_call_creds);
+ exec_ctx, c->inner_creds, composite_call_creds, target, args, sc,
+ new_args);
+ grpc_call_credentials_unref(exec_ctx, composite_call_creds);
} else {
status = c->inner_creds->vtable->create_security_connector(
- c->inner_creds, c->call_creds, target, args, sc, new_args);
+ exec_ctx, c->inner_creds, c->call_creds, target, args, sc, new_args);
}
return status;
}
diff --git a/src/core/lib/security/credentials/credentials.c b/src/core/lib/security/credentials/credentials.c
index 1149e5c2ed..9781a22a86 100644
--- a/src/core/lib/security/credentials/credentials.c
+++ b/src/core/lib/security/credentials/credentials.c
@@ -66,8 +66,8 @@ grpc_credentials_metadata_request *grpc_credentials_metadata_request_create(
}
void grpc_credentials_metadata_request_destroy(
- grpc_credentials_metadata_request *r) {
- grpc_call_credentials_unref(r->creds);
+ grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *r) {
+ grpc_call_credentials_unref(exec_ctx, r->creds);
grpc_http_response_destroy(&r->response);
gpr_free(r);
}
@@ -79,17 +79,22 @@ grpc_channel_credentials *grpc_channel_credentials_ref(
return creds;
}
-void grpc_channel_credentials_unref(grpc_channel_credentials *creds) {
+void grpc_channel_credentials_unref(grpc_exec_ctx *exec_ctx,
+ grpc_channel_credentials *creds) {
if (creds == NULL) return;
if (gpr_unref(&creds->refcount)) {
- if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
+ if (creds->vtable->destruct != NULL) {
+ creds->vtable->destruct(exec_ctx, creds);
+ }
gpr_free(creds);
}
}
void grpc_channel_credentials_release(grpc_channel_credentials *creds) {
GRPC_API_TRACE("grpc_channel_credentials_release(creds=%p)", 1, (creds));
- grpc_channel_credentials_unref(creds);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_credentials_unref(&exec_ctx, creds);
+ grpc_exec_ctx_finish(&exec_ctx);
}
grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds) {
@@ -98,17 +103,22 @@ grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds) {
return creds;
}
-void grpc_call_credentials_unref(grpc_call_credentials *creds) {
+void grpc_call_credentials_unref(grpc_exec_ctx *exec_ctx,
+ grpc_call_credentials *creds) {
if (creds == NULL) return;
if (gpr_unref(&creds->refcount)) {
- if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
+ if (creds->vtable->destruct != NULL) {
+ creds->vtable->destruct(exec_ctx, creds);
+ }
gpr_free(creds);
}
}
void grpc_call_credentials_release(grpc_call_credentials *creds) {
GRPC_API_TRACE("grpc_call_credentials_release(creds=%p)", 1, (creds));
- grpc_call_credentials_unref(creds);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_call_credentials_unref(&exec_ctx, creds);
+ grpc_exec_ctx_finish(&exec_ctx);
}
void grpc_call_credentials_get_request_metadata(
@@ -126,16 +136,16 @@ void grpc_call_credentials_get_request_metadata(
}
grpc_security_status grpc_channel_credentials_create_security_connector(
- grpc_channel_credentials *channel_creds, const char *target,
- const grpc_channel_args *args, grpc_channel_security_connector **sc,
- grpc_channel_args **new_args) {
+ grpc_exec_ctx *exec_ctx, grpc_channel_credentials *channel_creds,
+ const char *target, const grpc_channel_args *args,
+ grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
*new_args = NULL;
if (channel_creds == NULL) {
return GRPC_SECURITY_ERROR;
}
GPR_ASSERT(channel_creds->vtable->create_security_connector != NULL);
return channel_creds->vtable->create_security_connector(
- channel_creds, NULL, target, args, sc, new_args);
+ exec_ctx, channel_creds, NULL, target, args, sc, new_args);
}
grpc_channel_credentials *
@@ -157,10 +167,13 @@ grpc_server_credentials *grpc_server_credentials_ref(
return creds;
}
-void grpc_server_credentials_unref(grpc_server_credentials *creds) {
+void grpc_server_credentials_unref(grpc_exec_ctx *exec_ctx,
+ grpc_server_credentials *creds) {
if (creds == NULL) return;
if (gpr_unref(&creds->refcount)) {
- if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
+ if (creds->vtable->destruct != NULL) {
+ creds->vtable->destruct(exec_ctx, creds);
+ }
if (creds->processor.destroy != NULL && creds->processor.state != NULL) {
creds->processor.destroy(creds->processor.state);
}
@@ -170,16 +183,19 @@ void grpc_server_credentials_unref(grpc_server_credentials *creds) {
void grpc_server_credentials_release(grpc_server_credentials *creds) {
GRPC_API_TRACE("grpc_server_credentials_release(creds=%p)", 1, (creds));
- grpc_server_credentials_unref(creds);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_server_credentials_unref(&exec_ctx, creds);
+ grpc_exec_ctx_finish(&exec_ctx);
}
grpc_security_status grpc_server_credentials_create_security_connector(
- grpc_server_credentials *creds, grpc_server_security_connector **sc) {
+ grpc_exec_ctx *exec_ctx, grpc_server_credentials *creds,
+ grpc_server_security_connector **sc) {
if (creds == NULL || creds->vtable->create_security_connector == NULL) {
gpr_log(GPR_ERROR, "Server credentials cannot create security context.");
return GRPC_SECURITY_ERROR;
}
- return creds->vtable->create_security_connector(creds, sc);
+ return creds->vtable->create_security_connector(exec_ctx, creds, sc);
}
void grpc_server_credentials_set_auth_metadata_processor(
@@ -196,8 +212,9 @@ void grpc_server_credentials_set_auth_metadata_processor(
creds->processor = processor;
}
-static void server_credentials_pointer_arg_destroy(void *p) {
- grpc_server_credentials_unref(p);
+static void server_credentials_pointer_arg_destroy(grpc_exec_ctx *exec_ctx,
+ void *p) {
+ grpc_server_credentials_unref(exec_ctx, p);
}
static void *server_credentials_pointer_arg_copy(void *p) {
diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h
index 85b3bc5350..3011df6b8a 100644
--- a/src/core/lib/security/credentials/credentials.h
+++ b/src/core/lib/security/credentials/credentials.h
@@ -101,12 +101,13 @@ void grpc_override_well_known_credentials_path_getter(
/* --- grpc_channel_credentials. --- */
typedef struct {
- void (*destruct)(grpc_channel_credentials *c);
+ void (*destruct)(grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c);
grpc_security_status (*create_security_connector)(
- grpc_channel_credentials *c, grpc_call_credentials *call_creds,
- const char *target, const grpc_channel_args *args,
- grpc_channel_security_connector **sc, grpc_channel_args **new_args);
+ grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c,
+ grpc_call_credentials *call_creds, const char *target,
+ const grpc_channel_args *args, grpc_channel_security_connector **sc,
+ grpc_channel_args **new_args);
grpc_channel_credentials *(*duplicate_without_call_credentials)(
grpc_channel_credentials *c);
@@ -120,16 +121,17 @@ struct grpc_channel_credentials {
grpc_channel_credentials *grpc_channel_credentials_ref(
grpc_channel_credentials *creds);
-void grpc_channel_credentials_unref(grpc_channel_credentials *creds);
+void grpc_channel_credentials_unref(grpc_exec_ctx *exec_ctx,
+ grpc_channel_credentials *creds);
/* Creates a security connector for the channel. May also create new channel
args for the channel to be used in place of the passed in const args if
returned non NULL. In that case the caller is responsible for destroying
new_args after channel creation. */
grpc_security_status grpc_channel_credentials_create_security_connector(
- grpc_channel_credentials *creds, const char *target,
- const grpc_channel_args *args, grpc_channel_security_connector **sc,
- grpc_channel_args **new_args);
+ grpc_exec_ctx *exec_ctx, grpc_channel_credentials *creds,
+ const char *target, const grpc_channel_args *args,
+ grpc_channel_security_connector **sc, grpc_channel_args **new_args);
/* Creates a version of the channel credentials without any attached call
credentials. This can be used in order to open a channel to a non-trusted
@@ -162,7 +164,8 @@ void grpc_credentials_md_store_add_cstrings(grpc_credentials_md_store *store,
const char *key, const char *value);
grpc_credentials_md_store *grpc_credentials_md_store_ref(
grpc_credentials_md_store *store);
-void grpc_credentials_md_store_unref(grpc_credentials_md_store *store);
+void grpc_credentials_md_store_unref(grpc_exec_ctx *exec_ctx,
+ grpc_credentials_md_store *store);
/* --- grpc_call_credentials. --- */
@@ -172,7 +175,7 @@ typedef void (*grpc_credentials_metadata_cb)(
size_t num_md, grpc_credentials_status status, const char *error_details);
typedef struct {
- void (*destruct)(grpc_call_credentials *c);
+ void (*destruct)(grpc_exec_ctx *exec_ctx, grpc_call_credentials *c);
void (*get_request_metadata)(grpc_exec_ctx *exec_ctx,
grpc_call_credentials *c,
grpc_polling_entity *pollent,
@@ -188,7 +191,8 @@ struct grpc_call_credentials {
};
grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds);
-void grpc_call_credentials_unref(grpc_call_credentials *creds);
+void grpc_call_credentials_unref(grpc_exec_ctx *exec_ctx,
+ grpc_call_credentials *creds);
void grpc_call_credentials_get_request_metadata(
grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
grpc_polling_entity *pollent, grpc_auth_metadata_context context,
@@ -202,9 +206,10 @@ grpc_call_credentials *grpc_md_only_test_credentials_create(
/* --- grpc_server_credentials. --- */
typedef struct {
- void (*destruct)(grpc_server_credentials *c);
+ void (*destruct)(grpc_exec_ctx *exec_ctx, grpc_server_credentials *c);
grpc_security_status (*create_security_connector)(
- grpc_server_credentials *c, grpc_server_security_connector **sc);
+ grpc_exec_ctx *exec_ctx, grpc_server_credentials *c,
+ grpc_server_security_connector **sc);
} grpc_server_credentials_vtable;
struct grpc_server_credentials {
@@ -215,12 +220,14 @@ struct grpc_server_credentials {
};
grpc_security_status grpc_server_credentials_create_security_connector(
- grpc_server_credentials *creds, grpc_server_security_connector **sc);
+ grpc_exec_ctx *exec_ctx, grpc_server_credentials *creds,
+ grpc_server_security_connector **sc);
grpc_server_credentials *grpc_server_credentials_ref(
grpc_server_credentials *creds);
-void grpc_server_credentials_unref(grpc_server_credentials *creds);
+void grpc_server_credentials_unref(grpc_exec_ctx *exec_ctx,
+ grpc_server_credentials *creds);
#define GRPC_SERVER_CREDENTIALS_ARG "grpc.server_credentials"
@@ -243,6 +250,6 @@ grpc_credentials_metadata_request *grpc_credentials_metadata_request_create(
void *user_data);
void grpc_credentials_metadata_request_destroy(
- grpc_credentials_metadata_request *r);
+ grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *r);
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/credentials_metadata.c b/src/core/lib/security/credentials/credentials_metadata.c
index e6cb567734..68da5fb4a8 100644
--- a/src/core/lib/security/credentials/credentials_metadata.c
+++ b/src/core/lib/security/credentials/credentials_metadata.c
@@ -37,6 +37,8 @@
#include <string.h>
+#include "src/core/lib/slice/slice_internal.h"
+
static void store_ensure_capacity(grpc_credentials_md_store *store) {
if (store->num_entries == store->allocated) {
store->allocated = (store->allocated == 0) ? 1 : store->allocated * 2;
@@ -62,8 +64,8 @@ void grpc_credentials_md_store_add(grpc_credentials_md_store *store,
grpc_slice key, grpc_slice value) {
if (store == NULL) return;
store_ensure_capacity(store);
- store->entries[store->num_entries].key = grpc_slice_ref(key);
- store->entries[store->num_entries].value = grpc_slice_ref(value);
+ store->entries[store->num_entries].key = grpc_slice_ref_internal(key);
+ store->entries[store->num_entries].value = grpc_slice_ref_internal(value);
store->num_entries++;
}
@@ -85,14 +87,15 @@ grpc_credentials_md_store *grpc_credentials_md_store_ref(
return store;
}
-void grpc_credentials_md_store_unref(grpc_credentials_md_store *store) {
+void grpc_credentials_md_store_unref(grpc_exec_ctx *exec_ctx,
+ grpc_credentials_md_store *store) {
if (store == NULL) return;
if (gpr_unref(&store->refcount)) {
if (store->entries != NULL) {
size_t i;
for (i = 0; i < store->num_entries; i++) {
- grpc_slice_unref(store->entries[i].key);
- grpc_slice_unref(store->entries[i].value);
+ grpc_slice_unref_internal(exec_ctx, store->entries[i].key);
+ grpc_slice_unref_internal(exec_ctx, store->entries[i].value);
}
gpr_free(store->entries);
}
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.c b/src/core/lib/security/credentials/fake/fake_credentials.c
index ea4cb76fb9..f41184f9f9 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.c
+++ b/src/core/lib/security/credentials/fake/fake_credentials.c
@@ -45,16 +45,18 @@
/* -- Fake transport security credentials. -- */
static grpc_security_status fake_transport_security_create_security_connector(
- grpc_channel_credentials *c, grpc_call_credentials *call_creds,
- const char *target, const grpc_channel_args *args,
- grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+ grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c,
+ grpc_call_credentials *call_creds, const char *target,
+ const grpc_channel_args *args, grpc_channel_security_connector **sc,
+ grpc_channel_args **new_args) {
*sc = grpc_fake_channel_security_connector_create(call_creds);
return GRPC_SECURITY_OK;
}
static grpc_security_status
fake_transport_security_server_create_security_connector(
- grpc_server_credentials *c, grpc_server_security_connector **sc) {
+ grpc_exec_ctx *exec_ctx, grpc_server_credentials *c,
+ grpc_server_security_connector **sc) {
*sc = grpc_fake_server_security_connector_create();
return GRPC_SECURITY_OK;
}
@@ -89,9 +91,10 @@ grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
/* -- Metadata-only test credentials. -- */
-static void md_only_test_destruct(grpc_call_credentials *creds) {
+static void md_only_test_destruct(grpc_exec_ctx *exec_ctx,
+ grpc_call_credentials *creds) {
grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;
- grpc_credentials_md_store_unref(c->md_store);
+ grpc_credentials_md_store_unref(exec_ctx, c->md_store);
}
static void on_simulated_token_fetch_done(grpc_exec_ctx *exec_ctx,
@@ -101,7 +104,7 @@ static void on_simulated_token_fetch_done(grpc_exec_ctx *exec_ctx,
grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)r->creds;
r->cb(exec_ctx, r->user_data, c->md_store->entries, c->md_store->num_entries,
GRPC_CREDENTIALS_OK, NULL);
- grpc_credentials_metadata_request_destroy(r);
+ grpc_credentials_metadata_request_destroy(exec_ctx, r);
}
static void md_only_test_get_request_metadata(
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.c b/src/core/lib/security/credentials/google_default/google_default_credentials.c
index afe0e3d357..65eb02bbb9 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.c
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.c
@@ -45,6 +45,7 @@
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
#include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/env.h"
#include "src/core/lib/support/string.h"
@@ -101,11 +102,10 @@ static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, grpc_error *e) {
grpc_pollset_destroy(p);
}
-static int is_stack_running_on_compute_engine(void) {
+static int is_stack_running_on_compute_engine(grpc_exec_ctx *exec_ctx) {
compute_engine_detector detector;
grpc_httpcli_request request;
grpc_httpcli_context context;
- grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_closure destroy_closure;
/* The http call is local. If it takes more than one sec, it is for sure not
@@ -128,13 +128,13 @@ static int is_stack_running_on_compute_engine(void) {
grpc_resource_quota *resource_quota =
grpc_resource_quota_create("google_default_credentials");
grpc_httpcli_get(
- &exec_ctx, &context, &detector.pollent, resource_quota, &request,
+ exec_ctx, &context, &detector.pollent, resource_quota, &request,
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), max_detection_delay),
grpc_closure_create(on_compute_engine_detection_http_response, &detector),
&detector.response);
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
- grpc_exec_ctx_flush(&exec_ctx);
+ grpc_exec_ctx_flush(exec_ctx);
/* Block until we get the response. This is not ideal but this should only be
called once for the lifetime of the process by the default credentials. */
@@ -143,7 +143,7 @@ static int is_stack_running_on_compute_engine(void) {
grpc_pollset_worker *worker = NULL;
if (!GRPC_LOG_IF_ERROR(
"pollset_work",
- grpc_pollset_work(&exec_ctx,
+ grpc_pollset_work(exec_ctx,
grpc_polling_entity_pollset(&detector.pollent),
&worker, gpr_now(GPR_CLOCK_MONOTONIC),
gpr_inf_future(GPR_CLOCK_MONOTONIC)))) {
@@ -156,10 +156,9 @@ static int is_stack_running_on_compute_engine(void) {
grpc_httpcli_context_destroy(&context);
grpc_closure_init(&destroy_closure, destroy_pollset,
grpc_polling_entity_pollset(&detector.pollent));
- grpc_pollset_shutdown(&exec_ctx,
+ grpc_pollset_shutdown(exec_ctx,
grpc_polling_entity_pollset(&detector.pollent),
&destroy_closure);
- grpc_exec_ctx_finish(&exec_ctx);
g_polling_mu = NULL;
gpr_free(grpc_polling_entity_pollset(&detector.pollent));
@@ -170,12 +169,12 @@ static int is_stack_running_on_compute_engine(void) {
/* Takes ownership of creds_path if not NULL. */
static grpc_error *create_default_creds_from_path(
- char *creds_path, grpc_call_credentials **creds) {
+ grpc_exec_ctx *exec_ctx, char *creds_path, grpc_call_credentials **creds) {
grpc_json *json = NULL;
grpc_auth_json_key key;
grpc_auth_refresh_token token;
grpc_call_credentials *result = NULL;
- grpc_slice creds_data = gpr_empty_slice();
+ grpc_slice creds_data = grpc_empty_slice();
grpc_error *error = GRPC_ERROR_NONE;
if (creds_path == NULL) {
error = GRPC_ERROR_CREATE("creds_path unset");
@@ -200,7 +199,7 @@ static grpc_error *create_default_creds_from_path(
if (grpc_auth_json_key_is_valid(&key)) {
result =
grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
- key, grpc_max_auth_token_lifetime());
+ exec_ctx, key, grpc_max_auth_token_lifetime());
if (result == NULL) {
error = GRPC_ERROR_CREATE(
"grpc_service_account_jwt_access_credentials_create_from_auth_json_"
@@ -225,7 +224,7 @@ static grpc_error *create_default_creds_from_path(
end:
GPR_ASSERT((result == NULL) + (error == GRPC_ERROR_NONE) == 1);
if (creds_path != NULL) gpr_free(creds_path);
- grpc_slice_unref(creds_data);
+ grpc_slice_unref_internal(exec_ctx, creds_data);
if (json != NULL) grpc_json_destroy(json);
*creds = result;
return error;
@@ -236,6 +235,7 @@ grpc_channel_credentials *grpc_google_default_credentials_create(void) {
grpc_call_credentials *call_creds = NULL;
grpc_error *error = GRPC_ERROR_CREATE("Failed to create Google credentials");
grpc_error *err;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
GRPC_API_TRACE("grpc_google_default_credentials_create(void)", 0, ());
@@ -250,20 +250,22 @@ grpc_channel_credentials *grpc_google_default_credentials_create(void) {
/* First, try the environment variable. */
err = create_default_creds_from_path(
- gpr_getenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR), &call_creds);
+ &exec_ctx, gpr_getenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR), &call_creds);
if (err == GRPC_ERROR_NONE) goto end;
error = grpc_error_add_child(error, err);
/* Then the well-known file. */
err = create_default_creds_from_path(
- grpc_get_well_known_google_credentials_file_path(), &call_creds);
+ &exec_ctx, grpc_get_well_known_google_credentials_file_path(),
+ &call_creds);
if (err == GRPC_ERROR_NONE) goto end;
error = grpc_error_add_child(error, err);
/* At last try to see if we're on compute engine (do the detection only once
since it requires a network test). */
if (!compute_engine_detection_done) {
- int need_compute_engine_creds = is_stack_running_on_compute_engine();
+ int need_compute_engine_creds =
+ is_stack_running_on_compute_engine(&exec_ctx);
compute_engine_detection_done = 1;
if (need_compute_engine_creds) {
call_creds = grpc_google_compute_engine_credentials_create(NULL);
@@ -286,8 +288,8 @@ end:
grpc_composite_channel_credentials_create(ssl_creds, call_creds,
NULL));
GPR_ASSERT(default_credentials != NULL);
- grpc_channel_credentials_unref(ssl_creds);
- grpc_call_credentials_unref(call_creds);
+ grpc_channel_credentials_unref(&exec_ctx, ssl_creds);
+ grpc_call_credentials_unref(&exec_ctx, call_creds);
result = default_credentials;
} else {
gpr_log(GPR_ERROR, "Could not create google default credentials.");
@@ -299,18 +301,21 @@ end:
} else {
GRPC_ERROR_UNREF(error);
}
+ grpc_exec_ctx_finish(&exec_ctx);
return result;
}
void grpc_flush_cached_google_default_credentials(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_once_init(&g_once, init_default_credentials);
gpr_mu_lock(&g_state_mu);
if (default_credentials != NULL) {
- grpc_channel_credentials_unref(default_credentials);
+ grpc_channel_credentials_unref(&exec_ctx, default_credentials);
default_credentials = NULL;
}
compute_engine_detection_done = 0;
gpr_mu_unlock(&g_state_mu);
+ grpc_exec_ctx_finish(&exec_ctx);
}
/* -- Well known credentials path. -- */
diff --git a/src/core/lib/security/credentials/iam/iam_credentials.c b/src/core/lib/security/credentials/iam/iam_credentials.c
index 370a384d0e..abd69a9670 100644
--- a/src/core/lib/security/credentials/iam/iam_credentials.c
+++ b/src/core/lib/security/credentials/iam/iam_credentials.c
@@ -42,9 +42,10 @@
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-static void iam_destruct(grpc_call_credentials *creds) {
+static void iam_destruct(grpc_exec_ctx *exec_ctx,
+ grpc_call_credentials *creds) {
grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds;
- grpc_credentials_md_store_unref(c->iam_md);
+ grpc_credentials_md_store_unref(exec_ctx, c->iam_md);
}
static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.c b/src/core/lib/security/credentials/jwt/jwt_credentials.c
index 3daf0f4ef7..616be64a54 100644
--- a/src/core/lib/security/credentials/jwt/jwt_credentials.c
+++ b/src/core/lib/security/credentials/jwt/jwt_credentials.c
@@ -42,9 +42,10 @@
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-static void jwt_reset_cache(grpc_service_account_jwt_access_credentials *c) {
+static void jwt_reset_cache(grpc_exec_ctx *exec_ctx,
+ grpc_service_account_jwt_access_credentials *c) {
if (c->cached.jwt_md != NULL) {
- grpc_credentials_md_store_unref(c->cached.jwt_md);
+ grpc_credentials_md_store_unref(exec_ctx, c->cached.jwt_md);
c->cached.jwt_md = NULL;
}
if (c->cached.service_url != NULL) {
@@ -54,11 +55,12 @@ static void jwt_reset_cache(grpc_service_account_jwt_access_credentials *c) {
c->cached.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
}
-static void jwt_destruct(grpc_call_credentials *creds) {
+static void jwt_destruct(grpc_exec_ctx *exec_ctx,
+ grpc_call_credentials *creds) {
grpc_service_account_jwt_access_credentials *c =
(grpc_service_account_jwt_access_credentials *)creds;
grpc_auth_json_key_destruct(&c->key);
- jwt_reset_cache(c);
+ jwt_reset_cache(exec_ctx, c);
gpr_mu_destroy(&c->cache_mu);
}
@@ -92,7 +94,7 @@ static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
char *jwt = NULL;
/* Generate a new jwt. */
gpr_mu_lock(&c->cache_mu);
- jwt_reset_cache(c);
+ jwt_reset_cache(exec_ctx, c);
jwt = grpc_jwt_encode_and_sign(&c->key, context.service_url,
c->jwt_lifetime, NULL);
if (jwt != NULL) {
@@ -114,7 +116,7 @@ static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
if (jwt_md != NULL) {
cb(exec_ctx, user_data, jwt_md->entries, jwt_md->num_entries,
GRPC_CREDENTIALS_OK, NULL);
- grpc_credentials_md_store_unref(jwt_md);
+ grpc_credentials_md_store_unref(exec_ctx, jwt_md);
} else {
cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_ERROR,
"Could not generate JWT.");
@@ -126,7 +128,8 @@ static grpc_call_credentials_vtable jwt_vtable = {jwt_destruct,
grpc_call_credentials *
grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
- grpc_auth_json_key key, gpr_timespec token_lifetime) {
+ grpc_exec_ctx *exec_ctx, grpc_auth_json_key key,
+ gpr_timespec token_lifetime) {
grpc_service_account_jwt_access_credentials *c;
if (!grpc_auth_json_key_is_valid(&key)) {
gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation");
@@ -140,7 +143,7 @@ grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
c->key = key;
c->jwt_lifetime = token_lifetime;
gpr_mu_init(&c->cache_mu);
- jwt_reset_cache(c);
+ jwt_reset_cache(exec_ctx, c);
return &c->base;
}
@@ -183,6 +186,11 @@ grpc_call_credentials *grpc_service_account_jwt_access_credentials_create(
gpr_free(clean_json);
}
GPR_ASSERT(reserved == NULL);
- return grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
- grpc_auth_json_key_create_from_string(json_key), token_lifetime);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_call_credentials *creds =
+ grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
+ &exec_ctx, grpc_auth_json_key_create_from_string(json_key),
+ token_lifetime);
+ grpc_exec_ctx_finish(&exec_ctx);
+ return creds;
}
diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.h b/src/core/lib/security/credentials/jwt/jwt_credentials.h
index d572606179..39b7aeafe8 100644
--- a/src/core/lib/security/credentials/jwt/jwt_credentials.h
+++ b/src/core/lib/security/credentials/jwt/jwt_credentials.h
@@ -57,6 +57,7 @@ typedef struct {
// Takes ownership of the key.
grpc_call_credentials *
grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
- grpc_auth_json_key key, gpr_timespec token_lifetime);
+ grpc_exec_ctx *exec_ctx, grpc_auth_json_key key,
+ gpr_timespec token_lifetime);
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.c b/src/core/lib/security/credentials/jwt/jwt_verifier.c
index 42bd89dd0a..71febc248a 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.c
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.c
@@ -36,11 +36,6 @@
#include <limits.h>
#include <string.h>
-#include "src/core/lib/http/httpcli.h"
-#include "src/core/lib/iomgr/polling_entity.h"
-#include "src/core/lib/security/util/b64.h"
-#include "src/core/lib/tsi/ssl_types.h"
-
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
@@ -48,6 +43,12 @@
#include <grpc/support/useful.h>
#include <openssl/pem.h>
+#include "src/core/lib/http/httpcli.h"
+#include "src/core/lib/iomgr/polling_entity.h"
+#include "src/core/lib/security/util/b64.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/tsi/ssl_types.h"
+
/* --- Utils. --- */
const char *grpc_jwt_verifier_status_to_string(
@@ -84,11 +85,12 @@ static const EVP_MD *evp_md_from_alg(const char *alg) {
}
}
-static grpc_json *parse_json_part_from_jwt(const char *str, size_t len,
+static grpc_json *parse_json_part_from_jwt(grpc_exec_ctx *exec_ctx,
+ const char *str, size_t len,
grpc_slice *buffer) {
grpc_json *json;
- *buffer = grpc_base64_decode_with_len(str, len, 1);
+ *buffer = grpc_base64_decode_with_len(exec_ctx, str, len, 1);
if (GRPC_SLICE_IS_EMPTY(*buffer)) {
gpr_log(GPR_ERROR, "Invalid base64.");
return NULL;
@@ -96,7 +98,7 @@ static grpc_json *parse_json_part_from_jwt(const char *str, size_t len,
json = grpc_json_parse_string_with_len((char *)GRPC_SLICE_START_PTR(*buffer),
GRPC_SLICE_LENGTH(*buffer));
if (json == NULL) {
- grpc_slice_unref(*buffer);
+ grpc_slice_unref_internal(exec_ctx, *buffer);
gpr_log(GPR_ERROR, "JSON parsing error.");
}
return json;
@@ -132,13 +134,14 @@ typedef struct {
grpc_slice buffer;
} jose_header;
-static void jose_header_destroy(jose_header *h) {
- grpc_slice_unref(h->buffer);
+static void jose_header_destroy(grpc_exec_ctx *exec_ctx, jose_header *h) {
+ grpc_slice_unref_internal(exec_ctx, h->buffer);
gpr_free(h);
}
/* Takes ownership of json and buffer. */
-static jose_header *jose_header_from_json(grpc_json *json, grpc_slice buffer) {
+static jose_header *jose_header_from_json(grpc_exec_ctx *exec_ctx,
+ grpc_json *json, grpc_slice buffer) {
grpc_json *cur;
jose_header *h = gpr_malloc(sizeof(jose_header));
memset(h, 0, sizeof(jose_header));
@@ -173,7 +176,7 @@ static jose_header *jose_header_from_json(grpc_json *json, grpc_slice buffer) {
error:
grpc_json_destroy(json);
- jose_header_destroy(h);
+ jose_header_destroy(exec_ctx, h);
return NULL;
}
@@ -193,9 +196,9 @@ struct grpc_jwt_claims {
grpc_slice buffer;
};
-void grpc_jwt_claims_destroy(grpc_jwt_claims *claims) {
+void grpc_jwt_claims_destroy(grpc_exec_ctx *exec_ctx, grpc_jwt_claims *claims) {
grpc_json_destroy(claims->json);
- grpc_slice_unref(claims->buffer);
+ grpc_slice_unref_internal(exec_ctx, claims->buffer);
gpr_free(claims);
}
@@ -240,7 +243,8 @@ gpr_timespec grpc_jwt_claims_not_before(const grpc_jwt_claims *claims) {
}
/* Takes ownership of json and buffer even in case of failure. */
-grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, grpc_slice buffer) {
+grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_exec_ctx *exec_ctx,
+ grpc_json *json, grpc_slice buffer) {
grpc_json *cur;
grpc_jwt_claims *claims = gpr_malloc(sizeof(grpc_jwt_claims));
memset(claims, 0, sizeof(grpc_jwt_claims));
@@ -281,7 +285,7 @@ grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, grpc_slice buffer) {
return claims;
error:
- grpc_jwt_claims_destroy(claims);
+ grpc_jwt_claims_destroy(exec_ctx, claims);
return NULL;
}
@@ -362,12 +366,12 @@ static verifier_cb_ctx *verifier_cb_ctx_create(
return ctx;
}
-void verifier_cb_ctx_destroy(verifier_cb_ctx *ctx) {
+void verifier_cb_ctx_destroy(grpc_exec_ctx *exec_ctx, verifier_cb_ctx *ctx) {
if (ctx->audience != NULL) gpr_free(ctx->audience);
- if (ctx->claims != NULL) grpc_jwt_claims_destroy(ctx->claims);
- grpc_slice_unref(ctx->signature);
- grpc_slice_unref(ctx->signed_data);
- jose_header_destroy(ctx->header);
+ if (ctx->claims != NULL) grpc_jwt_claims_destroy(exec_ctx, ctx->claims);
+ grpc_slice_unref_internal(exec_ctx, ctx->signature);
+ grpc_slice_unref_internal(exec_ctx, ctx->signed_data);
+ jose_header_destroy(exec_ctx, ctx->header);
for (size_t i = 0; i < HTTP_RESPONSE_COUNT; i++) {
grpc_http_response_destroy(&ctx->responses[i]);
}
@@ -447,23 +451,24 @@ end:
return result;
}
-static BIGNUM *bignum_from_base64(const char *b64) {
+static BIGNUM *bignum_from_base64(grpc_exec_ctx *exec_ctx, const char *b64) {
BIGNUM *result = NULL;
grpc_slice bin;
if (b64 == NULL) return NULL;
- bin = grpc_base64_decode(b64, 1);
+ bin = grpc_base64_decode(exec_ctx, b64, 1);
if (GRPC_SLICE_IS_EMPTY(bin)) {
gpr_log(GPR_ERROR, "Invalid base64 for big num.");
return NULL;
}
result = BN_bin2bn(GRPC_SLICE_START_PTR(bin),
TSI_SIZE_AS_SIZE(GRPC_SLICE_LENGTH(bin)), NULL);
- grpc_slice_unref(bin);
+ grpc_slice_unref_internal(exec_ctx, bin);
return result;
}
-static EVP_PKEY *pkey_from_jwk(const grpc_json *json, const char *kty) {
+static EVP_PKEY *pkey_from_jwk(grpc_exec_ctx *exec_ctx, const grpc_json *json,
+ const char *kty) {
const grpc_json *key_prop;
RSA *rsa = NULL;
EVP_PKEY *result = NULL;
@@ -480,10 +485,12 @@ static EVP_PKEY *pkey_from_jwk(const grpc_json *json, const char *kty) {
}
for (key_prop = json->child; key_prop != NULL; key_prop = key_prop->next) {
if (strcmp(key_prop->key, "n") == 0) {
- rsa->n = bignum_from_base64(validate_string_field(key_prop, "n"));
+ rsa->n =
+ bignum_from_base64(exec_ctx, validate_string_field(key_prop, "n"));
if (rsa->n == NULL) goto end;
} else if (strcmp(key_prop->key, "e") == 0) {
- rsa->e = bignum_from_base64(validate_string_field(key_prop, "e"));
+ rsa->e =
+ bignum_from_base64(exec_ctx, validate_string_field(key_prop, "e"));
if (rsa->e == NULL) goto end;
}
}
@@ -499,7 +506,8 @@ end:
return result;
}
-static EVP_PKEY *find_verification_key(const grpc_json *json,
+static EVP_PKEY *find_verification_key(grpc_exec_ctx *exec_ctx,
+ const grpc_json *json,
const char *header_alg,
const char *header_kid) {
const grpc_json *jkey;
@@ -543,7 +551,7 @@ static EVP_PKEY *find_verification_key(const grpc_json *json,
}
if (alg != NULL && kid != NULL && kty != NULL &&
strcmp(kid, header_kid) == 0 && strcmp(alg, header_alg) == 0) {
- return pkey_from_jwk(jkey, kty);
+ return pkey_from_jwk(exec_ctx, jkey, kty);
}
}
gpr_log(GPR_ERROR,
@@ -597,7 +605,7 @@ static void on_keys_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
goto end;
}
verification_key =
- find_verification_key(json, ctx->header->alg, ctx->header->kid);
+ find_verification_key(exec_ctx, json, ctx->header->alg, ctx->header->kid);
if (verification_key == NULL) {
gpr_log(GPR_ERROR, "Could not find verification key with kid %s.",
ctx->header->kid);
@@ -621,8 +629,8 @@ static void on_keys_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
end:
if (json != NULL) grpc_json_destroy(json);
if (verification_key != NULL) EVP_PKEY_free(verification_key);
- ctx->user_cb(ctx->user_data, status, claims);
- verifier_cb_ctx_destroy(ctx);
+ ctx->user_cb(exec_ctx, ctx->user_data, status, claims);
+ verifier_cb_ctx_destroy(exec_ctx, ctx);
}
static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
@@ -667,15 +675,16 @@ static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
grpc_closure_create(on_keys_retrieved, ctx),
&ctx->responses[HTTP_RESPONSE_KEYS]);
- grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
grpc_json_destroy(json);
gpr_free(req.host);
return;
error:
if (json != NULL) grpc_json_destroy(json);
- ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, NULL);
- verifier_cb_ctx_destroy(ctx);
+ ctx->user_cb(exec_ctx, ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR,
+ NULL);
+ verifier_cb_ctx_destroy(exec_ctx, ctx);
}
static email_key_mapping *verifier_get_mapping(grpc_jwt_verifier *v,
@@ -779,14 +788,15 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx,
exec_ctx, &ctx->verifier->http_ctx, &ctx->pollent, resource_quota, &req,
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
http_cb, &ctx->responses[rsp_idx]);
- grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
gpr_free(req.host);
gpr_free(req.http.path);
return;
error:
- ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, NULL);
- verifier_cb_ctx_destroy(ctx);
+ ctx->user_cb(exec_ctx, ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR,
+ NULL);
+ verifier_cb_ctx_destroy(exec_ctx, ctx);
}
void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx,
@@ -808,22 +818,24 @@ void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(verifier != NULL && jwt != NULL && audience != NULL && cb != NULL);
dot = strchr(cur, '.');
if (dot == NULL) goto error;
- json = parse_json_part_from_jwt(cur, (size_t)(dot - cur), &header_buffer);
+ json = parse_json_part_from_jwt(exec_ctx, cur, (size_t)(dot - cur),
+ &header_buffer);
if (json == NULL) goto error;
- header = jose_header_from_json(json, header_buffer);
+ header = jose_header_from_json(exec_ctx, json, header_buffer);
if (header == NULL) goto error;
cur = dot + 1;
dot = strchr(cur, '.');
if (dot == NULL) goto error;
- json = parse_json_part_from_jwt(cur, (size_t)(dot - cur), &claims_buffer);
+ json = parse_json_part_from_jwt(exec_ctx, cur, (size_t)(dot - cur),
+ &claims_buffer);
if (json == NULL) goto error;
- claims = grpc_jwt_claims_from_json(json, claims_buffer);
+ claims = grpc_jwt_claims_from_json(exec_ctx, json, claims_buffer);
if (claims == NULL) goto error;
signed_jwt_len = (size_t)(dot - jwt);
cur = dot + 1;
- signature = grpc_base64_decode(cur, 1);
+ signature = grpc_base64_decode(exec_ctx, cur, 1);
if (GRPC_SLICE_IS_EMPTY(signature)) goto error;
retrieve_key_and_verify(
exec_ctx,
@@ -832,9 +844,9 @@ void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx,
return;
error:
- if (header != NULL) jose_header_destroy(header);
- if (claims != NULL) grpc_jwt_claims_destroy(claims);
- cb(user_data, GRPC_JWT_VERIFIER_BAD_FORMAT, NULL);
+ if (header != NULL) jose_header_destroy(exec_ctx, header);
+ if (claims != NULL) grpc_jwt_claims_destroy(exec_ctx, claims);
+ cb(exec_ctx, user_data, GRPC_JWT_VERIFIER_BAD_FORMAT, NULL);
}
grpc_jwt_verifier *grpc_jwt_verifier_create(
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.h b/src/core/lib/security/credentials/jwt/jwt_verifier.h
index f09f9d5d47..b79f411903 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.h
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.h
@@ -66,7 +66,7 @@ const char *grpc_jwt_verifier_status_to_string(grpc_jwt_verifier_status status);
typedef struct grpc_jwt_claims grpc_jwt_claims;
-void grpc_jwt_claims_destroy(grpc_jwt_claims *claims);
+void grpc_jwt_claims_destroy(grpc_exec_ctx *exec_ctx, grpc_jwt_claims *claims);
/* Returns the whole JSON tree of the claims. */
const grpc_json *grpc_jwt_claims_json(const grpc_jwt_claims *claims);
@@ -115,7 +115,8 @@ void grpc_jwt_verifier_destroy(grpc_jwt_verifier *verifier);
is done (maybe in another thread).
It is the responsibility of the callee to call grpc_jwt_claims_destroy on
the claims. */
-typedef void (*grpc_jwt_verification_done_cb)(void *user_data,
+typedef void (*grpc_jwt_verification_done_cb)(grpc_exec_ctx *exec_ctx,
+ void *user_data,
grpc_jwt_verifier_status status,
grpc_jwt_claims *claims);
@@ -129,7 +130,8 @@ void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx,
/* --- TESTING ONLY exposed functions. --- */
-grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, grpc_slice buffer);
+grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_exec_ctx *exec_ctx,
+ grpc_json *json, grpc_slice buffer);
grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims,
const char *audience);
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
index b3625b22c0..cbcd74958c 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
@@ -118,18 +118,19 @@ void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token) {
// Oauth2 Token Fetcher credentials.
//
-static void oauth2_token_fetcher_destruct(grpc_call_credentials *creds) {
+static void oauth2_token_fetcher_destruct(grpc_exec_ctx *exec_ctx,
+ grpc_call_credentials *creds) {
grpc_oauth2_token_fetcher_credentials *c =
(grpc_oauth2_token_fetcher_credentials *)creds;
- grpc_credentials_md_store_unref(c->access_token_md);
+ grpc_credentials_md_store_unref(exec_ctx, c->access_token_md);
gpr_mu_destroy(&c->mu);
grpc_httpcli_context_destroy(&c->httpcli_context);
}
grpc_credentials_status
grpc_oauth2_token_fetcher_credentials_parse_server_response(
- const grpc_http_response *response, grpc_credentials_md_store **token_md,
- gpr_timespec *token_lifetime) {
+ grpc_exec_ctx *exec_ctx, const grpc_http_response *response,
+ grpc_credentials_md_store **token_md, gpr_timespec *token_lifetime) {
char *null_terminated_body = NULL;
char *new_access_token = NULL;
grpc_credentials_status status = GRPC_CREDENTIALS_OK;
@@ -198,7 +199,7 @@ grpc_oauth2_token_fetcher_credentials_parse_server_response(
token_lifetime->tv_sec = strtol(expires_in->value, NULL, 10);
token_lifetime->tv_nsec = 0;
token_lifetime->clock_type = GPR_TIMESPAN;
- if (*token_md != NULL) grpc_credentials_md_store_unref(*token_md);
+ if (*token_md != NULL) grpc_credentials_md_store_unref(exec_ctx, *token_md);
*token_md = grpc_credentials_md_store_create(1);
grpc_credentials_md_store_add_cstrings(
*token_md, GRPC_AUTHORIZATION_METADATA_KEY, new_access_token);
@@ -207,7 +208,7 @@ grpc_oauth2_token_fetcher_credentials_parse_server_response(
end:
if (status != GRPC_CREDENTIALS_OK && (*token_md != NULL)) {
- grpc_credentials_md_store_unref(*token_md);
+ grpc_credentials_md_store_unref(exec_ctx, *token_md);
*token_md = NULL;
}
if (null_terminated_body != NULL) gpr_free(null_terminated_body);
@@ -230,7 +231,7 @@ static void on_oauth2_token_fetcher_http_response(grpc_exec_ctx *exec_ctx,
gpr_mu_lock(&c->mu);
status = grpc_oauth2_token_fetcher_credentials_parse_server_response(
- &r->response, &c->access_token_md, &token_lifetime);
+ exec_ctx, &r->response, &c->access_token_md, &token_lifetime);
if (status == GRPC_CREDENTIALS_OK) {
c->token_expiration =
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), token_lifetime);
@@ -242,7 +243,7 @@ static void on_oauth2_token_fetcher_http_response(grpc_exec_ctx *exec_ctx,
"Error occured when fetching oauth2 token.");
}
gpr_mu_unlock(&c->mu);
- grpc_credentials_metadata_request_destroy(r);
+ grpc_credentials_metadata_request_destroy(exec_ctx, r);
}
static void oauth2_token_fetcher_get_request_metadata(
@@ -268,7 +269,7 @@ static void oauth2_token_fetcher_get_request_metadata(
if (cached_access_token_md != NULL) {
cb(exec_ctx, user_data, cached_access_token_md->entries,
cached_access_token_md->num_entries, GRPC_CREDENTIALS_OK, NULL);
- grpc_credentials_md_store_unref(cached_access_token_md);
+ grpc_credentials_md_store_unref(exec_ctx, cached_access_token_md);
} else {
c->fetch_func(
exec_ctx,
@@ -315,7 +316,7 @@ static void compute_engine_fetch_oauth2(
grpc_httpcli_get(exec_ctx, httpcli_context, pollent, resource_quota, &request,
deadline, grpc_closure_create(response_cb, metadata_req),
&metadata_req->response);
- grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
}
grpc_call_credentials *grpc_google_compute_engine_credentials_create(
@@ -334,11 +335,12 @@ grpc_call_credentials *grpc_google_compute_engine_credentials_create(
// Google Refresh Token credentials.
//
-static void refresh_token_destruct(grpc_call_credentials *creds) {
+static void refresh_token_destruct(grpc_exec_ctx *exec_ctx,
+ grpc_call_credentials *creds) {
grpc_google_refresh_token_credentials *c =
(grpc_google_refresh_token_credentials *)creds;
grpc_auth_refresh_token_destruct(&c->refresh_token);
- oauth2_token_fetcher_destruct(&c->base.base);
+ oauth2_token_fetcher_destruct(exec_ctx, &c->base.base);
}
static grpc_call_credentials_vtable refresh_token_vtable = {
@@ -372,7 +374,7 @@ static void refresh_token_fetch_oauth2(
&request, body, strlen(body), deadline,
grpc_closure_create(response_cb, metadata_req),
&metadata_req->response);
- grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
gpr_free(body);
}
@@ -424,9 +426,10 @@ grpc_call_credentials *grpc_google_refresh_token_credentials_create(
// Oauth2 Access Token credentials.
//
-static void access_token_destruct(grpc_call_credentials *creds) {
+static void access_token_destruct(grpc_exec_ctx *exec_ctx,
+ grpc_call_credentials *creds) {
grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
- grpc_credentials_md_store_unref(c->access_token_md);
+ grpc_credentials_md_store_unref(exec_ctx, c->access_token_md);
}
static void access_token_get_request_metadata(
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
index 7f6f205c22..2d7c02ccf5 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
@@ -103,7 +103,7 @@ grpc_refresh_token_credentials_create_from_auth_refresh_token(
// Exposed for testing only.
grpc_credentials_status
grpc_oauth2_token_fetcher_credentials_parse_server_response(
- const struct grpc_http_response *response,
+ grpc_exec_ctx *exec_ctx, const struct grpc_http_response *response,
grpc_credentials_md_store **token_md, gpr_timespec *token_lifetime);
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_OAUTH2_OAUTH2_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.c b/src/core/lib/security/credentials/plugin/plugin_credentials.c
index 5d950098a0..66e501cffc 100644
--- a/src/core/lib/security/credentials/plugin/plugin_credentials.c
+++ b/src/core/lib/security/credentials/plugin/plugin_credentials.c
@@ -35,20 +35,23 @@
#include <string.h>
-#include "src/core/lib/surface/api_trace.h"
-
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
+#include "src/core/lib/surface/api_trace.h"
+
typedef struct {
void *user_data;
grpc_credentials_metadata_cb cb;
} grpc_metadata_plugin_request;
-static void plugin_destruct(grpc_call_credentials *creds) {
+static void plugin_destruct(grpc_exec_ctx *exec_ctx,
+ grpc_call_credentials *creds) {
grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds;
if (c->plugin.state != NULL && c->plugin.destroy != NULL) {
c->plugin.destroy(c->plugin.state);
@@ -75,13 +78,14 @@ static void plugin_md_request_metadata_ready(void *request,
bool seen_illegal_header = false;
grpc_credentials_md *md_array = NULL;
for (i = 0; i < num_md; i++) {
- if (!grpc_header_key_is_legal(md[i].key, strlen(md[i].key))) {
- gpr_log(GPR_ERROR, "Plugin added invalid metadata key: %s", md[i].key);
+ if (!grpc_header_key_is_legal(md[i].key)) {
+ char *key = grpc_dump_slice(md[i].key, GPR_DUMP_ASCII);
+ gpr_log(GPR_ERROR, "Plugin added invalid metadata key: %s", key);
+ gpr_free(key);
seen_illegal_header = true;
break;
- } else if (!grpc_is_binary_header(md[i].key, strlen(md[i].key)) &&
- !grpc_header_nonbin_value_is_legal(md[i].value,
- md[i].value_length)) {
+ } else if (!grpc_is_binary_header(md[i].key) &&
+ !grpc_header_nonbin_value_is_legal(md[i].value)) {
gpr_log(GPR_ERROR, "Plugin added invalid metadata value.");
seen_illegal_header = true;
break;
@@ -93,15 +97,14 @@ static void plugin_md_request_metadata_ready(void *request,
} else if (num_md > 0) {
md_array = gpr_malloc(num_md * sizeof(grpc_credentials_md));
for (i = 0; i < num_md; i++) {
- md_array[i].key = grpc_slice_from_copied_string(md[i].key);
- md_array[i].value =
- grpc_slice_from_copied_buffer(md[i].value, md[i].value_length);
+ md_array[i].key = grpc_slice_ref(md[i].key);
+ md_array[i].value = grpc_slice_ref(md[i].value);
}
r->cb(&exec_ctx, r->user_data, md_array, num_md, GRPC_CREDENTIALS_OK,
NULL);
for (i = 0; i < num_md; i++) {
- grpc_slice_unref(md_array[i].key);
- grpc_slice_unref(md_array[i].value);
+ grpc_slice_unref_internal(&exec_ctx, md_array[i].key);
+ grpc_slice_unref_internal(&exec_ctx, md_array[i].value);
}
gpr_free(md_array);
} else if (num_md == 0) {
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.c b/src/core/lib/security/credentials/ssl/ssl_credentials.c
index 0dc1fccec4..4eebb7d613 100644
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.c
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.c
@@ -57,7 +57,8 @@ static void ssl_copy_key_material(const char *input, unsigned char **output,
// SSL Channel Credentials.
//
-static void ssl_destruct(grpc_channel_credentials *creds) {
+static void ssl_destruct(grpc_exec_ctx *exec_ctx,
+ grpc_channel_credentials *creds) {
grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
if (c->config.pem_private_key != NULL) gpr_free(c->config.pem_private_key);
@@ -65,9 +66,10 @@ static void ssl_destruct(grpc_channel_credentials *creds) {
}
static grpc_security_status ssl_create_security_connector(
- grpc_channel_credentials *creds, grpc_call_credentials *call_creds,
- const char *target, const grpc_channel_args *args,
- grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+ grpc_exec_ctx *exec_ctx, grpc_channel_credentials *creds,
+ grpc_call_credentials *call_creds, const char *target,
+ const grpc_channel_args *args, grpc_channel_security_connector **sc,
+ grpc_channel_args **new_args) {
grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
grpc_security_status status = GRPC_SECURITY_OK;
size_t i = 0;
@@ -83,7 +85,7 @@ static grpc_security_status ssl_create_security_connector(
}
}
status = grpc_ssl_channel_security_connector_create(
- call_creds, &c->config, target, overridden_target_name, sc);
+ exec_ctx, call_creds, &c->config, target, overridden_target_name, sc);
if (status != GRPC_SECURITY_OK) {
return status;
}
@@ -138,7 +140,8 @@ grpc_channel_credentials *grpc_ssl_credentials_create(
// SSL Server Credentials.
//
-static void ssl_server_destruct(grpc_server_credentials *creds) {
+static void ssl_server_destruct(grpc_exec_ctx *exec_ctx,
+ grpc_server_credentials *creds) {
grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
size_t i;
for (i = 0; i < c->config.num_key_cert_pairs; i++) {
@@ -161,9 +164,10 @@ static void ssl_server_destruct(grpc_server_credentials *creds) {
}
static grpc_security_status ssl_server_create_security_connector(
- grpc_server_credentials *creds, grpc_server_security_connector **sc) {
+ grpc_exec_ctx *exec_ctx, grpc_server_credentials *creds,
+ grpc_server_security_connector **sc) {
grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
- return grpc_ssl_server_security_connector_create(&c->config, sc);
+ return grpc_ssl_server_security_connector_create(exec_ctx, &c->config, sc);
}
static grpc_server_credentials_vtable ssl_server_vtable = {
diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c
index 053bf5972c..d680c1ef13 100644
--- a/src/core/lib/security/transport/client_auth_filter.c
+++ b/src/core/lib/security/transport/client_auth_filter.c
@@ -44,6 +44,8 @@
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/transport/security_connector.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/transport/static_metadata.h"
@@ -53,8 +55,10 @@
/* We can have a per-call credentials. */
typedef struct {
grpc_call_credentials *creds;
- grpc_mdstr *host;
- grpc_mdstr *method;
+ bool have_host;
+ bool have_method;
+ grpc_slice host;
+ grpc_slice method;
/* pollset{_set} bound to this call; if we need to make external
network requests, they should be done under a pollset added to this
pollset_set so that work can progress when this call wants work to progress
@@ -93,7 +97,8 @@ static void bubble_up_error(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
call_data *calld = elem->call_data;
gpr_log(GPR_ERROR, "Client side authentication failure: %s", error_msg);
grpc_slice error_slice = grpc_slice_from_copied_string(error_msg);
- grpc_transport_stream_op_add_close(&calld->op, status, &error_slice);
+ grpc_transport_stream_op_add_close(exec_ctx, &calld->op, status,
+ &error_slice);
grpc_call_next_op(exec_ctx, elem, &calld->op);
}
@@ -121,8 +126,9 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
for (i = 0; i < num_md; i++) {
grpc_metadata_batch_add_tail(
mdb, &calld->md_links[i],
- grpc_mdelem_from_slices(grpc_slice_ref(md_elems[i].key),
- grpc_slice_ref(md_elems[i].value)));
+ grpc_mdelem_from_slices(exec_ctx,
+ grpc_slice_ref_internal(md_elems[i].key),
+ grpc_slice_ref_internal(md_elems[i].value)));
}
grpc_call_next_op(exec_ctx, elem, op);
}
@@ -130,7 +136,7 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
void build_auth_metadata_context(grpc_security_connector *sc,
grpc_auth_context *auth_context,
call_data *calld) {
- char *service = gpr_strdup(grpc_mdstr_as_c_string(calld->method));
+ char *service = grpc_dump_slice(calld->method, GPR_DUMP_ASCII);
char *last_slash = strrchr(service, '/');
char *method_name = NULL;
char *service_url = NULL;
@@ -146,14 +152,15 @@ void build_auth_metadata_context(grpc_security_connector *sc,
method_name = gpr_strdup(last_slash + 1);
}
if (method_name == NULL) method_name = gpr_strdup("");
+ char *host = grpc_dump_slice(calld->host, GPR_DUMP_ASCII);
gpr_asprintf(&service_url, "%s://%s%s",
- sc->url_scheme == NULL ? "" : sc->url_scheme,
- grpc_mdstr_as_c_string(calld->host), service);
+ sc->url_scheme == NULL ? "" : sc->url_scheme, host, service);
calld->auth_md_context.service_url = service_url;
calld->auth_md_context.method_name = method_name;
calld->auth_md_context.channel_auth_context =
GRPC_AUTH_CONTEXT_REF(auth_context, "grpc_auth_metadata_context");
gpr_free(service);
+ gpr_free(host);
}
static void send_security_metadata(grpc_exec_ctx *exec_ctx,
@@ -204,8 +211,10 @@ static void on_host_checked(grpc_exec_ctx *exec_ctx, void *user_data,
send_security_metadata(exec_ctx, elem, &calld->op);
} else {
char *error_msg;
+ char *host = grpc_dump_slice(calld->host, GPR_DUMP_ASCII);
gpr_asprintf(&error_msg, "Invalid host %s set in :authority metadata.",
- grpc_mdstr_as_c_string(calld->host));
+ host);
+ gpr_free(host);
bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED, error_msg);
gpr_free(error_msg);
}
@@ -244,23 +253,30 @@ static void auth_start_transport_op(grpc_exec_ctx *exec_ctx,
if (op->send_initial_metadata != NULL) {
for (l = op->send_initial_metadata->list.head; l != NULL; l = l->next) {
- grpc_mdelem *md = l->md;
+ grpc_mdelem md = l->md;
/* Pointer comparison is OK for md_elems created from the same context.
*/
- if (md->key == GRPC_MDSTR_AUTHORITY) {
- if (calld->host != NULL) GRPC_MDSTR_UNREF(calld->host);
- calld->host = GRPC_MDSTR_REF(md->value);
- } else if (md->key == GRPC_MDSTR_PATH) {
- if (calld->method != NULL) GRPC_MDSTR_UNREF(calld->method);
- calld->method = GRPC_MDSTR_REF(md->value);
+ if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_AUTHORITY) == 0) {
+ if (calld->have_host) {
+ grpc_slice_unref_internal(exec_ctx, calld->host);
+ }
+ calld->host = grpc_slice_ref_internal(GRPC_MDVALUE(md));
+ calld->have_host = true;
+ } else if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_PATH) == 0) {
+ if (calld->have_method) {
+ grpc_slice_unref_internal(exec_ctx, calld->method);
+ }
+ calld->method = grpc_slice_ref_internal(GRPC_MDVALUE(md));
+ calld->have_method = true;
}
}
- if (calld->host != NULL) {
- const char *call_host = grpc_mdstr_as_c_string(calld->host);
+ if (calld->have_host) {
+ char *call_host = grpc_dump_slice(calld->host, GPR_DUMP_ASCII);
calld->op = *op; /* Copy op (originates from the caller's stack). */
grpc_channel_security_connector_check_call_host(
exec_ctx, chand->security_connector, call_host, chand->auth_context,
on_host_checked, elem);
+ gpr_free(call_host);
GPR_TIMER_END("auth_start_transport_op", 0);
return; /* early exit */
}
@@ -292,12 +308,12 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info,
void *ignored) {
call_data *calld = elem->call_data;
- grpc_call_credentials_unref(calld->creds);
- if (calld->host != NULL) {
- GRPC_MDSTR_UNREF(calld->host);
+ grpc_call_credentials_unref(exec_ctx, calld->creds);
+ if (calld->have_host) {
+ grpc_slice_unref_internal(exec_ctx, calld->host);
}
- if (calld->method != NULL) {
- GRPC_MDSTR_UNREF(calld->method);
+ if (calld->have_method) {
+ grpc_slice_unref_internal(exec_ctx, calld->method);
}
reset_auth_metadata_context(&calld->auth_md_context);
}
@@ -336,7 +352,7 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
channel_data *chand = elem->channel_data;
grpc_channel_security_connector *sc = chand->security_connector;
if (sc != NULL) {
- GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "client_auth_filter");
+ GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &sc->base, "client_auth_filter");
}
GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "client_auth_filter");
}
diff --git a/src/core/lib/security/transport/handshake.c b/src/core/lib/security/transport/handshake.c
index 9623797610..16d758d7a1 100644
--- a/src/core/lib/security/transport/handshake.c
+++ b/src/core/lib/security/transport/handshake.c
@@ -43,6 +43,7 @@
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/transport/secure_endpoint.h"
#include "src/core/lib/security/transport/tsi_error.h"
+#include "src/core/lib/slice/slice_internal.h"
#define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256
@@ -100,15 +101,16 @@ static void security_connector_remove_handshake(grpc_security_handshake *h) {
gpr_mu_unlock(&sc->mu);
}
-static void unref_handshake(grpc_security_handshake *h) {
+static void unref_handshake(grpc_exec_ctx *exec_ctx,
+ grpc_security_handshake *h) {
if (gpr_unref(&h->refs)) {
if (h->handshaker != NULL) tsi_handshaker_destroy(h->handshaker);
if (h->handshake_buffer != NULL) gpr_free(h->handshake_buffer);
- grpc_slice_buffer_destroy(&h->left_overs);
- grpc_slice_buffer_destroy(&h->outgoing);
- grpc_slice_buffer_destroy(&h->incoming);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &h->left_overs);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &h->outgoing);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &h->incoming);
GRPC_AUTH_CONTEXT_UNREF(h->auth_context, "handshake");
- GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake");
+ GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, h->connector, "handshake");
gpr_free(h);
}
}
@@ -136,7 +138,7 @@ static void security_handshake_done(grpc_exec_ctx *exec_ctx,
}
h->cb(exec_ctx, h->user_data, GRPC_SECURITY_ERROR, NULL, NULL);
}
- unref_handshake(h);
+ unref_handshake(exec_ctx, h);
GRPC_ERROR_UNREF(error);
}
@@ -213,7 +215,7 @@ static void send_handshake_bytes_to_peer(grpc_exec_ctx *exec_ctx,
to_send =
grpc_slice_from_copied_buffer((const char *)h->handshake_buffer, offset);
- grpc_slice_buffer_reset_and_unref(&h->outgoing);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &h->outgoing);
grpc_slice_buffer_add(&h->outgoing, to_send);
/* TODO(klempner,jboeuf): This should probably use the client setup
deadline */
@@ -280,7 +282,8 @@ static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
grpc_slice_buffer_add(
&h->left_overs,
grpc_slice_split_tail(&h->incoming.slices[i], consumed_slice_size));
- grpc_slice_unref(
+ grpc_slice_unref_internal(
+ exec_ctx,
h->incoming.slices[i]); /* split_tail above increments refcount. */
}
grpc_slice_buffer_addn(
@@ -319,7 +322,7 @@ static void on_timeout(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
if (error == GRPC_ERROR_NONE) {
grpc_endpoint_shutdown(exec_ctx, h->wrapped_endpoint);
}
- unref_handshake(h);
+ unref_handshake(exec_ctx, h);
}
void grpc_do_security_handshake(
diff --git a/src/core/lib/security/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.c
index 1b278410e8..0e9a392c60 100644
--- a/src/core/lib/security/transport/secure_endpoint.c
+++ b/src/core/lib/security/transport/secure_endpoint.c
@@ -46,6 +46,7 @@
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/security/transport/secure_endpoint.h"
#include "src/core/lib/security/transport/tsi_error.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/tsi/transport_security_interface.h"
@@ -80,11 +81,11 @@ static void destroy(grpc_exec_ctx *exec_ctx, secure_endpoint *secure_ep) {
secure_endpoint *ep = secure_ep;
grpc_endpoint_destroy(exec_ctx, ep->wrapped_ep);
tsi_frame_protector_destroy(ep->protector);
- grpc_slice_buffer_destroy(&ep->leftover_bytes);
- grpc_slice_unref(ep->read_staging_buffer);
- grpc_slice_unref(ep->write_staging_buffer);
- grpc_slice_buffer_destroy(&ep->output_buffer);
- grpc_slice_buffer_destroy(&ep->source_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &ep->leftover_bytes);
+ grpc_slice_unref_internal(exec_ctx, ep->read_staging_buffer);
+ grpc_slice_unref_internal(exec_ctx, ep->write_staging_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &ep->output_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &ep->source_buffer);
gpr_mu_destroy(&ep->protector_mu);
gpr_free(ep);
}
@@ -160,7 +161,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *user_data,
uint8_t *end = GRPC_SLICE_END_PTR(ep->read_staging_buffer);
if (error != GRPC_ERROR_NONE) {
- grpc_slice_buffer_reset_and_unref(ep->read_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, ep->read_buffer);
call_read_cb(exec_ctx, ep, GRPC_ERROR_CREATE_REFERENCING(
"Secure read failed", &error, 1));
return;
@@ -215,10 +216,10 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *user_data,
/* TODO(yangg) experiment with moving this block after read_cb to see if it
helps latency */
- grpc_slice_buffer_reset_and_unref(&ep->source_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &ep->source_buffer);
if (result != TSI_OK) {
- grpc_slice_buffer_reset_and_unref(ep->read_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, ep->read_buffer);
call_read_cb(exec_ctx, ep, grpc_set_tsi_error_result(
GRPC_ERROR_CREATE("Unwrap failed"), result));
return;
@@ -232,7 +233,7 @@ static void endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep,
secure_endpoint *ep = (secure_endpoint *)secure_ep;
ep->read_cb = cb;
ep->read_buffer = slices;
- grpc_slice_buffer_reset_and_unref(ep->read_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, ep->read_buffer);
SECURE_ENDPOINT_REF(ep, "read");
if (ep->leftover_bytes.count) {
@@ -264,7 +265,7 @@ static void endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep,
uint8_t *cur = GRPC_SLICE_START_PTR(ep->write_staging_buffer);
uint8_t *end = GRPC_SLICE_END_PTR(ep->write_staging_buffer);
- grpc_slice_buffer_reset_and_unref(&ep->output_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &ep->output_buffer);
if (grpc_trace_secure_endpoint) {
for (i = 0; i < slices->count; i++) {
@@ -328,7 +329,7 @@ static void endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep,
if (result != TSI_OK) {
/* TODO(yangg) do different things according to the error type? */
- grpc_slice_buffer_reset_and_unref(&ep->output_buffer);
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &ep->output_buffer);
grpc_exec_ctx_sched(
exec_ctx, cb,
grpc_set_tsi_error_result(GRPC_ERROR_CREATE("Wrap failed"), result),
@@ -407,7 +408,7 @@ grpc_endpoint *grpc_secure_endpoint_create(
grpc_slice_buffer_init(&ep->leftover_bytes);
for (i = 0; i < leftover_nslices; i++) {
grpc_slice_buffer_add(&ep->leftover_bytes,
- grpc_slice_ref(leftover_slices[i]));
+ grpc_slice_ref_internal(leftover_slices[i]));
}
ep->write_staging_buffer = grpc_slice_malloc(STAGING_BUFFER_SIZE);
ep->read_staging_buffer = grpc_slice_malloc(STAGING_BUFFER_SIZE);
diff --git a/src/core/lib/security/transport/security_connector.c b/src/core/lib/security/transport/security_connector.c
index 0fbd63a7e1..53bccb3efb 100644
--- a/src/core/lib/security/transport/security_connector.c
+++ b/src/core/lib/security/transport/security_connector.c
@@ -195,7 +195,8 @@ grpc_security_connector *grpc_security_connector_ref(
}
#ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG
-void grpc_security_connector_unref(grpc_security_connector *sc,
+void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx,
+ grpc_security_connector *sc,
const char *file, int line,
const char *reason) {
if (sc == NULL) return;
@@ -203,14 +204,15 @@ void grpc_security_connector_unref(grpc_security_connector *sc,
"SECURITY_CONNECTOR:%p unref %d -> %d %s", sc,
(int)sc->refcount.count, (int)sc->refcount.count - 1, reason);
#else
-void grpc_security_connector_unref(grpc_security_connector *sc) {
+void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx,
+ grpc_security_connector *sc) {
if (sc == NULL) return;
#endif
- if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc);
+ if (gpr_unref(&sc->refcount)) sc->vtable->destroy(exec_ctx, sc);
}
-static void connector_pointer_arg_destroy(void *p) {
- GRPC_SECURITY_CONNECTOR_UNREF(p, "connector_pointer_arg_destroy");
+static void connector_pointer_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
+ GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, p, "connector_pointer_arg_destroy");
}
static void *connector_pointer_arg_copy(void *p) {
@@ -256,13 +258,15 @@ grpc_security_connector *grpc_find_security_connector_in_args(
/* -- Fake implementation. -- */
-static void fake_channel_destroy(grpc_security_connector *sc) {
+static void fake_channel_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_security_connector *sc) {
grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc;
- grpc_call_credentials_unref(c->request_metadata_creds);
+ grpc_call_credentials_unref(exec_ctx, c->request_metadata_creds);
gpr_free(sc);
}
-static void fake_server_destroy(grpc_security_connector *sc) {
+static void fake_server_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_security_connector *sc) {
grpc_server_security_connector *c = (grpc_server_security_connector *)sc;
gpr_mu_destroy(&c->mu);
gpr_free(sc);
@@ -381,10 +385,11 @@ typedef struct {
tsi_ssl_handshaker_factory *handshaker_factory;
} grpc_ssl_server_security_connector;
-static void ssl_channel_destroy(grpc_security_connector *sc) {
+static void ssl_channel_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_security_connector *sc) {
grpc_ssl_channel_security_connector *c =
(grpc_ssl_channel_security_connector *)sc;
- grpc_call_credentials_unref(c->base.request_metadata_creds);
+ grpc_call_credentials_unref(exec_ctx, c->base.request_metadata_creds);
if (c->handshaker_factory != NULL) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
}
@@ -393,7 +398,8 @@ static void ssl_channel_destroy(grpc_security_connector *sc) {
gpr_free(sc);
}
-static void ssl_server_destroy(grpc_security_connector *sc) {
+static void ssl_server_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_security_connector *sc) {
grpc_ssl_server_security_connector *c =
(grpc_ssl_server_security_connector *)sc;
@@ -643,7 +649,7 @@ static grpc_security_connector_vtable ssl_server_vtable = {
ssl_server_destroy, ssl_server_check_peer};
static grpc_slice compute_default_pem_root_certs_once(void) {
- grpc_slice result = gpr_empty_slice();
+ grpc_slice result = grpc_empty_slice();
/* First try to load the roots from the environment. */
char *default_root_certs_path =
@@ -719,7 +725,7 @@ size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs) {
}
grpc_security_status grpc_ssl_channel_security_connector_create(
- grpc_call_credentials *request_metadata_creds,
+ grpc_exec_ctx *exec_ctx, grpc_call_credentials *request_metadata_creds,
const grpc_ssl_config *config, const char *target_name,
const char *overridden_target_name, grpc_channel_security_connector **sc) {
size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
@@ -780,7 +786,7 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
- ssl_channel_destroy(&c->base.base);
+ ssl_channel_destroy(exec_ctx, &c->base.base);
*sc = NULL;
goto error;
}
@@ -796,7 +802,8 @@ error:
}
grpc_security_status grpc_ssl_server_security_connector_create(
- const grpc_ssl_server_config *config, grpc_server_security_connector **sc) {
+ grpc_exec_ctx *exec_ctx, const grpc_ssl_server_config *config,
+ grpc_server_security_connector **sc) {
size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
const unsigned char **alpn_protocol_strings =
gpr_malloc(sizeof(const char *) * num_alpn_protocols);
@@ -836,7 +843,7 @@ grpc_security_status grpc_ssl_server_security_connector_create(
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
- ssl_server_destroy(&c->base.base);
+ ssl_server_destroy(exec_ctx, &c->base.base);
*sc = NULL;
goto error;
}
diff --git a/src/core/lib/security/transport/security_connector.h b/src/core/lib/security/transport/security_connector.h
index dc02692b01..6e89bfd779 100644
--- a/src/core/lib/security/transport/security_connector.h
+++ b/src/core/lib/security/transport/security_connector.h
@@ -68,7 +68,7 @@ typedef void (*grpc_security_handshake_done_cb)(
grpc_endpoint *secure_endpoint, grpc_auth_context *auth_context);
typedef struct {
- void (*destroy)(grpc_security_connector *sc);
+ void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc);
void (*check_peer)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc,
tsi_peer peer, grpc_security_peer_check_cb cb,
void *user_data);
@@ -89,20 +89,23 @@ struct grpc_security_connector {
#ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG
#define GRPC_SECURITY_CONNECTOR_REF(p, r) \
grpc_security_connector_ref((p), __FILE__, __LINE__, (r))
-#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) \
- grpc_security_connector_unref((p), __FILE__, __LINE__, (r))
+#define GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, p, r) \
+ grpc_security_connector_unref((exec_ctx), (p), __FILE__, __LINE__, (r))
grpc_security_connector *grpc_security_connector_ref(
grpc_security_connector *policy, const char *file, int line,
const char *reason);
-void grpc_security_connector_unref(grpc_security_connector *policy,
+void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx,
+ grpc_security_connector *policy,
const char *file, int line,
const char *reason);
#else
#define GRPC_SECURITY_CONNECTOR_REF(p, r) grpc_security_connector_ref((p))
-#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) grpc_security_connector_unref((p))
+#define GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, p, r) \
+ grpc_security_connector_unref((exec_ctx), (p))
grpc_security_connector *grpc_security_connector_ref(
grpc_security_connector *policy);
-void grpc_security_connector_unref(grpc_security_connector *policy);
+void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx,
+ grpc_security_connector *policy);
#endif
/* Check the peer. Callee takes ownership of the peer object.
@@ -225,7 +228,7 @@ typedef struct {
specific error code otherwise.
*/
grpc_security_status grpc_ssl_channel_security_connector_create(
- grpc_call_credentials *request_metadata_creds,
+ grpc_exec_ctx *exec_ctx, grpc_call_credentials *request_metadata_creds,
const grpc_ssl_config *config, const char *target_name,
const char *overridden_target_name, grpc_channel_security_connector **sc);
@@ -254,7 +257,8 @@ typedef struct {
specific error code otherwise.
*/
grpc_security_status grpc_ssl_server_security_connector_create(
- const grpc_ssl_server_config *config, grpc_server_security_connector **sc);
+ grpc_exec_ctx *exec_ctx, const grpc_ssl_server_config *config,
+ grpc_server_security_connector **sc);
/* Util. */
const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,
diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c
index eaa1d0720b..1c4843fc14 100644
--- a/src/core/lib/security/transport/server_auth_filter.c
+++ b/src/core/lib/security/transport/server_auth_filter.c
@@ -33,12 +33,13 @@
#include <string.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/transport/auth_filters.h"
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
+#include "src/core/lib/slice/slice_internal.h"
typedef struct call_data {
grpc_metadata_batch *recv_initial_metadata;
@@ -67,41 +68,31 @@ static grpc_metadata_array metadata_batch_to_md_array(
grpc_metadata_array_init(&result);
for (l = batch->list.head; l != NULL; l = l->next) {
grpc_metadata *usr_md = NULL;
- grpc_mdelem *md = l->md;
- grpc_mdstr *key = md->key;
- grpc_mdstr *value = md->value;
+ grpc_mdelem md = l->md;
+ grpc_slice key = GRPC_MDKEY(md);
+ grpc_slice value = GRPC_MDVALUE(md);
if (result.count == result.capacity) {
result.capacity = GPR_MAX(result.capacity + 8, result.capacity * 2);
result.metadata =
gpr_realloc(result.metadata, result.capacity * sizeof(grpc_metadata));
}
usr_md = &result.metadata[result.count++];
- usr_md->key = grpc_mdstr_as_c_string(key);
- usr_md->value = grpc_mdstr_as_c_string(value);
- usr_md->value_length = GRPC_SLICE_LENGTH(value->slice);
+ usr_md->key = grpc_slice_ref_internal(key);
+ usr_md->value = grpc_slice_ref_internal(value);
}
return result;
}
-static grpc_mdelem *remove_consumed_md(void *user_data, grpc_mdelem *md) {
+static grpc_mdelem remove_consumed_md(grpc_exec_ctx *exec_ctx, void *user_data,
+ grpc_mdelem md) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
size_t i;
for (i = 0; i < calld->num_consumed_md; i++) {
const grpc_metadata *consumed_md = &calld->consumed_md[i];
- /* Maybe we could do a pointer comparison but we do not have any guarantee
- that the metadata processor used the same pointers for consumed_md in the
- callback. */
- if (GRPC_SLICE_LENGTH(md->key->slice) != strlen(consumed_md->key) ||
- GRPC_SLICE_LENGTH(md->value->slice) != consumed_md->value_length) {
- continue;
- }
- if (memcmp(GRPC_SLICE_START_PTR(md->key->slice), consumed_md->key,
- GRPC_SLICE_LENGTH(md->key->slice)) == 0 &&
- memcmp(GRPC_SLICE_START_PTR(md->value->slice), consumed_md->value,
- GRPC_SLICE_LENGTH(md->value->slice)) == 0) {
- return NULL; /* Delete. */
- }
+ if (grpc_slice_cmp(GRPC_MDKEY(md), consumed_md->key) == 0 &&
+ grpc_slice_cmp(GRPC_MDKEY(md), consumed_md->value) == 0)
+ return GRPC_MDNULL;
}
return md;
}
@@ -129,8 +120,8 @@ static void on_md_processing_done(
if (status == GRPC_STATUS_OK) {
calld->consumed_md = consumed_md;
calld->num_consumed_md = num_consumed_md;
- grpc_metadata_batch_filter(calld->recv_initial_metadata, remove_consumed_md,
- elem);
+ grpc_metadata_batch_filter(&exec_ctx, calld->recv_initial_metadata,
+ remove_consumed_md, elem);
grpc_metadata_array_destroy(&calld->md);
grpc_exec_ctx_sched(&exec_ctx, calld->on_done_recv, GRPC_ERROR_NONE, NULL);
} else {
@@ -149,7 +140,7 @@ static void on_md_processing_done(
}
calld->transport_op->send_trailing_metadata = NULL;
close_op->on_complete = grpc_closure_create(destroy_op, close_op);
- grpc_transport_stream_op_add_close(close_op, status, &message);
+ grpc_transport_stream_op_add_close(&exec_ctx, close_op, status, &message);
grpc_call_next_op(&exec_ctx, elem, close_op);
grpc_exec_ctx_sched(&exec_ctx, calld->on_done_recv,
grpc_error_set_int(GRPC_ERROR_CREATE(error_details),
@@ -264,7 +255,7 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
/* grab pointers to our data from the channel element */
channel_data *chand = elem->channel_data;
GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "server_auth_filter");
- grpc_server_credentials_unref(chand->creds);
+ grpc_server_credentials_unref(exec_ctx, chand->creds);
}
const grpc_channel_filter grpc_server_auth_filter = {
diff --git a/src/core/lib/security/util/b64.c b/src/core/lib/security/util/b64.c
index 4892e8e621..09c8213131 100644
--- a/src/core/lib/security/util/b64.c
+++ b/src/core/lib/security/util/b64.c
@@ -40,6 +40,8 @@
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
+#include "src/core/lib/slice/slice_internal.h"
+
/* --- Constants. --- */
static const int8_t base64_bytes[] = {
@@ -120,8 +122,9 @@ char *grpc_base64_encode(const void *vdata, size_t data_size, int url_safe,
return result;
}
-grpc_slice grpc_base64_decode(const char *b64, int url_safe) {
- return grpc_base64_decode_with_len(b64, strlen(b64), url_safe);
+grpc_slice grpc_base64_decode(grpc_exec_ctx *exec_ctx, const char *b64,
+ int url_safe) {
+ return grpc_base64_decode_with_len(exec_ctx, b64, strlen(b64), url_safe);
}
static void decode_one_char(const unsigned char *codes, unsigned char *result,
@@ -182,8 +185,8 @@ static int decode_group(const unsigned char *codes, size_t num_codes,
return 1;
}
-grpc_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len,
- int url_safe) {
+grpc_slice grpc_base64_decode_with_len(grpc_exec_ctx *exec_ctx, const char *b64,
+ size_t b64_len, int url_safe) {
grpc_slice result = grpc_slice_malloc(b64_len);
unsigned char *current = GRPC_SLICE_START_PTR(result);
size_t result_size = 0;
@@ -228,6 +231,6 @@ grpc_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len,
return result;
fail:
- grpc_slice_unref(result);
- return gpr_empty_slice();
+ grpc_slice_unref_internal(exec_ctx, result);
+ return grpc_empty_slice();
}
diff --git a/src/core/lib/security/util/b64.h b/src/core/lib/security/util/b64.h
index 6ea0b5365b..d42a136f61 100644
--- a/src/core/lib/security/util/b64.h
+++ b/src/core/lib/security/util/b64.h
@@ -43,10 +43,11 @@ char *grpc_base64_encode(const void *data, size_t data_size, int url_safe,
/* Decodes data according to the base64 specification. Returns an empty
slice in case of failure. */
-grpc_slice grpc_base64_decode(const char *b64, int url_safe);
+grpc_slice grpc_base64_decode(grpc_exec_ctx *exec_ctx, const char *b64,
+ int url_safe);
/* Same as above except that the length is provided by the caller. */
-grpc_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len,
- int url_safe);
+grpc_slice grpc_base64_decode_with_len(grpc_exec_ctx *exec_ctx, const char *b64,
+ size_t b64_len, int url_safe);
#endif /* GRPC_CORE_LIB_SECURITY_UTIL_B64_H */
diff --git a/src/core/lib/slice/percent_encoding.c b/src/core/lib/slice/percent_encoding.c
index b9e35f1c71..c76c58d371 100644
--- a/src/core/lib/slice/percent_encoding.c
+++ b/src/core/lib/slice/percent_encoding.c
@@ -35,6 +35,8 @@
#include <grpc/support/log.h>
+#include "src/core/lib/slice/slice_internal.h"
+
const uint8_t grpc_url_percent_encoding_unreserved_bytes[256 / 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0xfe, 0xff, 0xff,
0x87, 0xfe, 0xff, 0xff, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -66,7 +68,7 @@ grpc_slice grpc_percent_encode_slice(grpc_slice slice,
}
// no unreserved bytes: return the string unmodified
if (!any_reserved_bytes) {
- return grpc_slice_ref(slice);
+ return grpc_slice_ref_internal(slice);
}
// second pass: actually encode
grpc_slice out = grpc_slice_malloc(output_length);
@@ -119,7 +121,7 @@ bool grpc_strict_percent_decode_slice(grpc_slice slice_in,
}
}
if (!any_percent_encoded_stuff) {
- *slice_out = grpc_slice_ref(slice_in);
+ *slice_out = grpc_slice_ref_internal(slice_in);
return true;
}
p = GRPC_SLICE_START_PTR(slice_in);
@@ -158,7 +160,7 @@ grpc_slice grpc_permissive_percent_decode_slice(grpc_slice slice_in) {
}
}
if (!any_percent_encoded_stuff) {
- return grpc_slice_ref(slice_in);
+ return grpc_slice_ref_internal(slice_in);
}
p = GRPC_SLICE_START_PTR(slice_in);
grpc_slice out = grpc_slice_malloc(out_length);
diff --git a/src/core/lib/slice/slice.c b/src/core/lib/slice/slice.c
index 52977e6d9a..64988bae64 100644
--- a/src/core/lib/slice/slice.c
+++ b/src/core/lib/slice/slice.c
@@ -31,47 +31,69 @@
*
*/
+#include "src/core/lib/slice/slice_internal.h"
+
#include <grpc/slice.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <string.h>
-grpc_slice gpr_empty_slice(void) {
+#include "src/core/lib/iomgr/exec_ctx.h"
+
+grpc_slice grpc_empty_slice(void) {
grpc_slice out;
out.refcount = 0;
out.data.inlined.length = 0;
return out;
}
-grpc_slice grpc_slice_ref(grpc_slice slice) {
+grpc_slice grpc_slice_ref_internal(grpc_slice slice) {
if (slice.refcount) {
- slice.refcount->ref(slice.refcount);
+ slice.refcount->vtable->ref(slice.refcount);
}
return slice;
}
-void grpc_slice_unref(grpc_slice slice) {
+void grpc_slice_unref_internal(grpc_exec_ctx *exec_ctx, grpc_slice slice) {
if (slice.refcount) {
- slice.refcount->unref(slice.refcount);
+ slice.refcount->vtable->unref(exec_ctx, slice.refcount);
}
}
+/* Public API */
+grpc_slice grpc_slice_ref(grpc_slice slice) {
+ return grpc_slice_ref_internal(slice);
+}
+
+/* Public API */
+void grpc_slice_unref(grpc_slice slice) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_slice_unref_internal(&exec_ctx, slice);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
/* grpc_slice_from_static_string support structure - a refcount that does
nothing */
-static void noop_ref_or_unref(void *unused) {}
+static void noop_ref(void *unused) {}
+static void noop_unref(grpc_exec_ctx *exec_ctx, void *unused) {}
-static grpc_slice_refcount noop_refcount = {noop_ref_or_unref,
- noop_ref_or_unref};
+static const grpc_slice_refcount_vtable noop_refcount_vtable = {
+ noop_ref, noop_unref, grpc_slice_default_hash_impl};
+static grpc_slice_refcount noop_refcount = {&noop_refcount_vtable};
-grpc_slice grpc_slice_from_static_string(const char *s) {
+grpc_slice grpc_slice_from_static_buffer(const void *s, size_t len) {
grpc_slice slice;
slice.refcount = &noop_refcount;
slice.data.refcounted.bytes = (uint8_t *)s;
- slice.data.refcounted.length = strlen(s);
+ slice.data.refcounted.length = len;
return slice;
}
+grpc_slice grpc_slice_from_static_string(const char *s) {
+ return grpc_slice_from_static_buffer(s, strlen(s));
+}
+
/* grpc_slice_new support structures - we create a refcount object extended
with the user provided data pointer & destroy function */
typedef struct new_slice_refcount {
@@ -86,7 +108,7 @@ static void new_slice_ref(void *p) {
gpr_ref(&r->refs);
}
-static void new_slice_unref(void *p) {
+static void new_slice_unref(grpc_exec_ctx *exec_ctx, void *p) {
new_slice_refcount *r = p;
if (gpr_unref(&r->refs)) {
r->user_destroy(r->user_data);
@@ -94,14 +116,16 @@ static void new_slice_unref(void *p) {
}
}
+static const grpc_slice_refcount_vtable new_slice_vtable = {
+ new_slice_ref, new_slice_unref, grpc_slice_default_hash_impl};
+
grpc_slice grpc_slice_new_with_user_data(void *p, size_t len,
void (*destroy)(void *),
void *user_data) {
grpc_slice slice;
new_slice_refcount *rc = gpr_malloc(sizeof(new_slice_refcount));
gpr_ref_init(&rc->refs, 1);
- rc->rc.ref = new_slice_ref;
- rc->rc.unref = new_slice_unref;
+ rc->rc.vtable = &new_slice_vtable;
rc->user_destroy = destroy;
rc->user_data = user_data;
@@ -131,7 +155,7 @@ static void new_with_len_ref(void *p) {
gpr_ref(&r->refs);
}
-static void new_with_len_unref(void *p) {
+static void new_with_len_unref(grpc_exec_ctx *exec_ctx, void *p) {
new_with_len_slice_refcount *r = p;
if (gpr_unref(&r->refs)) {
r->user_destroy(r->user_data, r->user_length);
@@ -139,14 +163,16 @@ static void new_with_len_unref(void *p) {
}
}
+static const grpc_slice_refcount_vtable new_with_len_vtable = {
+ new_with_len_ref, new_with_len_unref, grpc_slice_default_hash_impl};
+
grpc_slice grpc_slice_new_with_len(void *p, size_t len,
void (*destroy)(void *, size_t)) {
grpc_slice slice;
new_with_len_slice_refcount *rc =
gpr_malloc(sizeof(new_with_len_slice_refcount));
gpr_ref_init(&rc->refs, 1);
- rc->rc.ref = new_with_len_ref;
- rc->rc.unref = new_with_len_unref;
+ rc->rc.vtable = &new_with_len_vtable;
rc->user_destroy = destroy;
rc->user_data = p;
rc->user_length = len;
@@ -177,13 +203,16 @@ static void malloc_ref(void *p) {
gpr_ref(&r->refs);
}
-static void malloc_unref(void *p) {
+static void malloc_unref(grpc_exec_ctx *exec_ctx, void *p) {
malloc_refcount *r = p;
if (gpr_unref(&r->refs)) {
gpr_free(r);
}
}
+static const grpc_slice_refcount_vtable malloc_vtable = {
+ malloc_ref, malloc_unref, grpc_slice_default_hash_impl};
+
grpc_slice grpc_slice_malloc(size_t length) {
grpc_slice slice;
@@ -203,8 +232,7 @@ grpc_slice grpc_slice_malloc(size_t length) {
this reference. */
gpr_ref_init(&rc->refs, 1);
- rc->base.ref = malloc_ref;
- rc->base.unref = malloc_unref;
+ rc->base.vtable = &malloc_vtable;
/* Build up the slice to be returned. */
/* The slices refcount points back to the allocated block. */
@@ -257,7 +285,7 @@ grpc_slice grpc_slice_sub(grpc_slice source, size_t begin, size_t end) {
} else {
subset = grpc_slice_sub_no_ref(source, begin, end);
/* Bump the refcount */
- subset.refcount->ref(subset.refcount);
+ subset.refcount->vtable->ref(subset.refcount);
}
return subset;
}
@@ -286,7 +314,7 @@ grpc_slice grpc_slice_split_tail(grpc_slice *source, size_t split) {
/* Build the result */
tail.refcount = source->refcount;
/* Bump the refcount */
- tail.refcount->ref(tail.refcount);
+ tail.refcount->vtable->ref(tail.refcount);
/* Point into the source array */
tail.data.refcounted.bytes = source->data.refcounted.bytes + split;
tail.data.refcounted.length = tail_length;
@@ -324,7 +352,7 @@ grpc_slice grpc_slice_split_head(grpc_slice *source, size_t split) {
/* Build the result */
head.refcount = source->refcount;
/* Bump the refcount */
- head.refcount->ref(head.refcount);
+ head.refcount->vtable->ref(head.refcount);
/* Point into the source array */
head.data.refcounted.bytes = source->data.refcounted.bytes;
head.data.refcounted.length = split;
@@ -336,6 +364,10 @@ grpc_slice grpc_slice_split_head(grpc_slice *source, size_t split) {
}
int grpc_slice_cmp(grpc_slice a, grpc_slice b) {
+ if (GRPC_SLICE_START_PTR(a) == GRPC_SLICE_START_PTR(b) &&
+ GRPC_SLICE_LENGTH(a) == GRPC_SLICE_LENGTH(b)) {
+ return 0;
+ }
int d = (int)(GRPC_SLICE_LENGTH(a) - GRPC_SLICE_LENGTH(b));
if (d != 0) return d;
return memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b),
@@ -356,3 +388,48 @@ int grpc_slice_is_equivalent(grpc_slice a, grpc_slice b) {
return a.data.refcounted.length == b.data.refcounted.length &&
a.data.refcounted.bytes == b.data.refcounted.bytes;
}
+
+int grpc_slice_buf_start_eq(grpc_slice a, const void *b, size_t len) {
+ if (GRPC_SLICE_LENGTH(a) < len) return 0;
+ return 0 == memcmp(GRPC_SLICE_START_PTR(a), b, len);
+}
+
+int grpc_slice_rchr(grpc_slice s, char c) {
+ const char *b = (const char *)GRPC_SLICE_START_PTR(s);
+ int i;
+ for (i = (int)GRPC_SLICE_LENGTH(s) - 1; i != -1 && b[i] != c; i--)
+ ;
+ return i;
+}
+
+int grpc_slice_chr(grpc_slice s, char c) {
+ const char *b = (const char *)GRPC_SLICE_START_PTR(s);
+ const char *p = memchr(b, c, GRPC_SLICE_LENGTH(s));
+ return p == NULL ? -1 : (int)(p - b);
+}
+
+int grpc_slice_slice(grpc_slice haystack, grpc_slice needle) {
+ size_t haystack_len = GRPC_SLICE_LENGTH(haystack);
+ const uint8_t *haystack_bytes = GRPC_SLICE_START_PTR(haystack);
+ size_t needle_len = GRPC_SLICE_LENGTH(needle);
+ const uint8_t *needle_bytes = GRPC_SLICE_START_PTR(needle);
+
+ if (haystack_len == 0 || needle_len == 0) return -1;
+ if (haystack_len < needle_len) return -1;
+ if (needle_len == 1) return grpc_slice_chr(haystack, (char)*needle_bytes);
+
+ const uint8_t *last = haystack_bytes + haystack_len - needle_len;
+ for (const uint8_t *cur = haystack_bytes; cur != last; ++cur) {
+ if (0 == memcmp(cur, needle_bytes, needle_len)) {
+ return (int)(cur - haystack_bytes);
+ }
+ }
+ return -1;
+}
+
+grpc_slice grpc_slice_dup(grpc_slice a) {
+ grpc_slice copy = grpc_slice_malloc(GRPC_SLICE_LENGTH(a));
+ memcpy(GRPC_SLICE_START_PTR(copy), GRPC_SLICE_START_PTR(a),
+ GRPC_SLICE_LENGTH(a));
+ return copy;
+}
diff --git a/src/core/lib/slice/slice_buffer.c b/src/core/lib/slice/slice_buffer.c
index 990ef128bd..08eaf4963a 100644
--- a/src/core/lib/slice/slice_buffer.c
+++ b/src/core/lib/slice/slice_buffer.c
@@ -40,6 +40,8 @@
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
+#include "src/core/lib/slice/slice_internal.h"
+
/* grow a buffer; requires GRPC_SLICE_BUFFER_INLINE_ELEMENTS > 1 */
#define GROW(x) (3 * (x) / 2)
@@ -63,13 +65,20 @@ void grpc_slice_buffer_init(grpc_slice_buffer *sb) {
sb->slices = sb->inlined;
}
-void grpc_slice_buffer_destroy(grpc_slice_buffer *sb) {
- grpc_slice_buffer_reset_and_unref(sb);
+void grpc_slice_buffer_destroy_internal(grpc_exec_ctx *exec_ctx,
+ grpc_slice_buffer *sb) {
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, sb);
if (sb->slices != sb->inlined) {
gpr_free(sb->slices);
}
}
+void grpc_slice_buffer_destroy(grpc_slice_buffer *sb) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_slice_buffer_destroy_internal(&exec_ctx, sb);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
uint8_t *grpc_slice_buffer_tiny_add(grpc_slice_buffer *sb, size_t n) {
grpc_slice *back;
uint8_t *out;
@@ -154,17 +163,24 @@ void grpc_slice_buffer_pop(grpc_slice_buffer *sb) {
}
}
-void grpc_slice_buffer_reset_and_unref(grpc_slice_buffer *sb) {
+void grpc_slice_buffer_reset_and_unref_internal(grpc_exec_ctx *exec_ctx,
+ grpc_slice_buffer *sb) {
size_t i;
for (i = 0; i < sb->count; i++) {
- grpc_slice_unref(sb->slices[i]);
+ grpc_slice_unref_internal(exec_ctx, sb->slices[i]);
}
sb->count = 0;
sb->length = 0;
}
+void grpc_slice_buffer_reset_and_unref(grpc_slice_buffer *sb) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_slice_buffer_reset_and_unref_internal(&exec_ctx, sb);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
void grpc_slice_buffer_swap(grpc_slice_buffer *a, grpc_slice_buffer *b) {
GPR_SWAP(size_t, a->count, b->count);
GPR_SWAP(size_t, a->capacity, b->capacity);
diff --git a/src/core/lib/transport/mdstr_hash_table.c b/src/core/lib/slice/slice_hash_table.c
index 3d01e56df7..017bf03da9 100644
--- a/src/core/lib/transport/mdstr_hash_table.c
+++ b/src/core/lib/slice/slice_hash_table.c
@@ -29,7 +29,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-#include "src/core/lib/transport/mdstr_hash_table.h"
+#include "src/core/lib/slice/slice_hash_table.h"
#include <stdbool.h>
#include <string.h>
@@ -37,70 +37,80 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/metadata.h"
-struct grpc_mdstr_hash_table {
+struct grpc_slice_hash_table {
gpr_refcount refs;
size_t size;
- grpc_mdstr_hash_table_entry* entries;
+ grpc_slice_hash_table_entry* entries;
};
+static bool is_empty(grpc_slice_hash_table_entry *entry) {
+ return entry->vtable == NULL;
+}
+
// Helper function for insert and get operations that performs quadratic
// probing (https://en.wikipedia.org/wiki/Quadratic_probing).
-static size_t grpc_mdstr_hash_table_find_index(
- const grpc_mdstr_hash_table* table, const grpc_mdstr* key,
- bool find_empty) {
+static size_t grpc_slice_hash_table_find_index(
+ const grpc_slice_hash_table* table, const grpc_slice key, bool find_empty) {
+ size_t hash = grpc_slice_hash(key);
for (size_t i = 0; i < table->size; ++i) {
- const size_t idx = (key->hash + i * i) % table->size;
- if (table->entries[idx].key == NULL) return find_empty ? idx : table->size;
- if (table->entries[idx].key == key) return idx;
+ const size_t idx = (hash + i * i) % table->size;
+ if (is_empty(&table->entries[idx])) {
+ return find_empty ? idx : table->size;
+ }
+ if (grpc_slice_cmp(table->entries[idx].key, key) == 0) {
+ return idx;
+ }
}
return table->size; // Not found.
}
-static void grpc_mdstr_hash_table_add(
- grpc_mdstr_hash_table* table, grpc_mdstr* key, void* value,
- const grpc_mdstr_hash_table_vtable* vtable) {
+static void grpc_slice_hash_table_add(
+ grpc_slice_hash_table* table, grpc_slice key, void* value,
+ const grpc_slice_hash_table_vtable* vtable) {
GPR_ASSERT(value != NULL);
const size_t idx =
- grpc_mdstr_hash_table_find_index(table, key, true /* find_empty */);
+ grpc_slice_hash_table_find_index(table, key, true /* find_empty */);
GPR_ASSERT(idx != table->size); // Table should never be full.
- grpc_mdstr_hash_table_entry* entry = &table->entries[idx];
- entry->key = GRPC_MDSTR_REF(key);
+ grpc_slice_hash_table_entry* entry = &table->entries[idx];
+ entry->key = grpc_slice_ref(key);
entry->value = vtable->copy_value(value);
entry->vtable = vtable;
}
-grpc_mdstr_hash_table* grpc_mdstr_hash_table_create(
- size_t num_entries, grpc_mdstr_hash_table_entry* entries) {
- grpc_mdstr_hash_table* table = gpr_malloc(sizeof(*table));
+grpc_slice_hash_table* grpc_slice_hash_table_create(
+ size_t num_entries, grpc_slice_hash_table_entry* entries) {
+ grpc_slice_hash_table* table = gpr_malloc(sizeof(*table));
memset(table, 0, sizeof(*table));
gpr_ref_init(&table->refs, 1);
// Quadratic probing gets best performance when the table is no more
// than half full.
table->size = num_entries * 2;
- const size_t entry_size = sizeof(grpc_mdstr_hash_table_entry) * table->size;
+ const size_t entry_size = sizeof(grpc_slice_hash_table_entry) * table->size;
table->entries = gpr_malloc(entry_size);
memset(table->entries, 0, entry_size);
for (size_t i = 0; i < num_entries; ++i) {
- grpc_mdstr_hash_table_entry* entry = &entries[i];
- grpc_mdstr_hash_table_add(table, entry->key, entry->value, entry->vtable);
+ grpc_slice_hash_table_entry* entry = &entries[i];
+ grpc_slice_hash_table_add(table, entry->key, entry->value, entry->vtable);
}
return table;
}
-grpc_mdstr_hash_table* grpc_mdstr_hash_table_ref(grpc_mdstr_hash_table* table) {
+grpc_slice_hash_table* grpc_slice_hash_table_ref(grpc_slice_hash_table* table) {
if (table != NULL) gpr_ref(&table->refs);
return table;
}
-void grpc_mdstr_hash_table_unref(grpc_mdstr_hash_table* table) {
+void grpc_slice_hash_table_unref(grpc_exec_ctx* exec_ctx,
+ grpc_slice_hash_table* table) {
if (table != NULL && gpr_unref(&table->refs)) {
for (size_t i = 0; i < table->size; ++i) {
- grpc_mdstr_hash_table_entry* entry = &table->entries[i];
- if (entry->key != NULL) {
- GRPC_MDSTR_UNREF(entry->key);
- entry->vtable->destroy_value(entry->value);
+ grpc_slice_hash_table_entry* entry = &table->entries[i];
+ if (!is_empty(entry)) {
+ grpc_slice_unref_internal(exec_ctx, entry->key);
+ entry->vtable->destroy_value(exec_ctx, entry->value);
}
}
gpr_free(table->entries);
@@ -108,10 +118,10 @@ void grpc_mdstr_hash_table_unref(grpc_mdstr_hash_table* table) {
}
}
-void* grpc_mdstr_hash_table_get(const grpc_mdstr_hash_table* table,
- const grpc_mdstr* key) {
+void* grpc_slice_hash_table_get(const grpc_slice_hash_table* table,
+ const grpc_slice key) {
const size_t idx =
- grpc_mdstr_hash_table_find_index(table, key, false /* find_empty */);
+ grpc_slice_hash_table_find_index(table, key, false /* find_empty */);
if (idx == table->size) return NULL; // Not found.
return table->entries[idx].value;
}
diff --git a/src/core/lib/transport/mdstr_hash_table.h b/src/core/lib/slice/slice_hash_table.h
index 8982ec3a8d..f760836a48 100644
--- a/src/core/lib/transport/mdstr_hash_table.h
+++ b/src/core/lib/slice/slice_hash_table.h
@@ -40,37 +40,39 @@
* (https://en.wikipedia.org/wiki/Open_addressing) with quadratic
* probing (https://en.wikipedia.org/wiki/Quadratic_probing).
*
- * The keys are \a grpc_mdstr objects. The values are arbitrary pointers
+ * The keys are \a grpc_slice objects. The values are arbitrary pointers
* with a common vtable.
*
* Hash tables are intentionally immutable, to avoid the need for locking.
*/
-typedef struct grpc_mdstr_hash_table grpc_mdstr_hash_table;
+typedef struct grpc_slice_hash_table grpc_slice_hash_table;
-typedef struct grpc_mdstr_hash_table_vtable {
- void (*destroy_value)(void* value);
- void* (*copy_value)(void* value);
-} grpc_mdstr_hash_table_vtable;
+typedef struct grpc_slice_hash_table_vtable {
+ void (*destroy_value)(grpc_exec_ctx *exec_ctx, void *value);
+ void *(*copy_value)(void *value);
+} grpc_slice_hash_table_vtable;
-typedef struct grpc_mdstr_hash_table_entry {
- grpc_mdstr* key;
- void* value; /* Must not be NULL. */
- const grpc_mdstr_hash_table_vtable* vtable;
-} grpc_mdstr_hash_table_entry;
+typedef struct grpc_slice_hash_table_entry {
+ grpc_slice key;
+ void *value; /* Must not be NULL. */
+ const grpc_slice_hash_table_vtable *vtable;
+} grpc_slice_hash_table_entry;
/** Creates a new hash table of containing \a entries, which is an array
of length \a num_entries.
Creates its own copy of all keys and values from \a entries. */
-grpc_mdstr_hash_table* grpc_mdstr_hash_table_create(
- size_t num_entries, grpc_mdstr_hash_table_entry* entries);
+grpc_slice_hash_table *grpc_slice_hash_table_create(
+ size_t num_entries, grpc_slice_hash_table_entry *entries);
-grpc_mdstr_hash_table* grpc_mdstr_hash_table_ref(grpc_mdstr_hash_table* table);
-void grpc_mdstr_hash_table_unref(grpc_mdstr_hash_table* table);
+grpc_slice_hash_table *grpc_slice_hash_table_ref(grpc_slice_hash_table *table);
+/** Returns 1 when \a table is destroyed. */
+void grpc_slice_hash_table_unref(grpc_exec_ctx *exec_ctx,
+ grpc_slice_hash_table *table);
/** Returns the value from \a table associated with \a key.
Returns NULL if \a key is not found. */
-void* grpc_mdstr_hash_table_get(const grpc_mdstr_hash_table* table,
- const grpc_mdstr* key);
+void *grpc_slice_hash_table_get(const grpc_slice_hash_table *table,
+ const grpc_slice key);
#endif /* GRPC_CORE_LIB_TRANSPORT_MDSTR_HASH_TABLE_H */
diff --git a/src/core/lib/slice/slice_intern.c b/src/core/lib/slice/slice_intern.c
new file mode 100644
index 0000000000..2d93284926
--- /dev/null
+++ b/src/core/lib/slice/slice_intern.c
@@ -0,0 +1,325 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/lib/slice/slice_internal.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/iomgr/iomgr_internal.h" /* for iomgr_abort_on_leaks() */
+#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
+#include "src/core/lib/support/murmur_hash.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#define LOG2_SHARD_COUNT 5
+#define SHARD_COUNT (1 << LOG2_SHARD_COUNT)
+#define INITIAL_SHARD_CAPACITY 8
+
+#define TABLE_IDX(hash, capacity) (((hash) >> LOG2_SHARD_COUNT) % (capacity))
+#define SHARD_IDX(hash) ((hash) & ((1 << LOG2_SHARD_COUNT) - 1))
+
+typedef struct interned_slice_refcount {
+ grpc_slice_refcount base;
+ size_t length;
+ gpr_atm refcnt;
+ uint32_t hash;
+ struct interned_slice_refcount *bucket_next;
+} interned_slice_refcount;
+
+typedef struct slice_shard {
+ gpr_mu mu;
+ interned_slice_refcount **strs;
+ size_t count;
+ size_t capacity;
+} slice_shard;
+
+/* hash seed: decided at initialization time */
+static uint32_t g_hash_seed;
+static int g_forced_hash_seed = 0;
+
+static slice_shard g_shards[SHARD_COUNT];
+
+typedef struct {
+ uint32_t hash;
+ uint32_t idx;
+} static_metadata_hash_ent;
+
+static static_metadata_hash_ent
+ static_metadata_hash[4 * GRPC_STATIC_MDSTR_COUNT];
+static uint32_t max_static_metadata_hash_probe;
+static uint32_t static_metadata_hash_values[GRPC_STATIC_MDSTR_COUNT];
+
+static void interned_slice_ref(void *p) {
+ interned_slice_refcount *s = p;
+ GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&s->refcnt, 1) > 0);
+}
+
+static void interned_slice_destroy(interned_slice_refcount *s) {
+ slice_shard *shard = &g_shards[SHARD_IDX(s->hash)];
+ gpr_mu_lock(&shard->mu);
+ GPR_ASSERT(0 == gpr_atm_no_barrier_load(&s->refcnt));
+ interned_slice_refcount **prev_next;
+ interned_slice_refcount *cur;
+ for (prev_next = &shard->strs[TABLE_IDX(s->hash, shard->capacity)],
+ cur = *prev_next;
+ cur != s; prev_next = &cur->bucket_next, cur = cur->bucket_next)
+ ;
+ *prev_next = cur->bucket_next;
+ shard->count--;
+ gpr_free(s);
+ gpr_mu_unlock(&shard->mu);
+}
+
+static void interned_slice_unref(grpc_exec_ctx *exec_ctx, void *p) {
+ interned_slice_refcount *s = p;
+ if (1 == gpr_atm_full_fetch_add(&s->refcnt, -1)) {
+ interned_slice_destroy(s);
+ }
+}
+
+static uint32_t interned_slice_hash(void *p, grpc_slice slice) {
+ interned_slice_refcount *s = p;
+ if (slice.data.refcounted.bytes == (uint8_t *)(s + 1) &&
+ slice.data.refcounted.length == s->length) {
+ return s->hash;
+ }
+ return grpc_slice_default_hash_impl(p, slice);
+}
+
+static const grpc_slice_refcount_vtable interned_slice_vtable = {
+ interned_slice_ref, interned_slice_unref, interned_slice_hash};
+
+static void grow_shard(slice_shard *shard) {
+ size_t capacity = shard->capacity * 2;
+ size_t i;
+ interned_slice_refcount **strtab;
+ interned_slice_refcount *s, *next;
+
+ GPR_TIMER_BEGIN("grow_strtab", 0);
+
+ strtab = gpr_malloc(sizeof(interned_slice_refcount *) * capacity);
+ memset(strtab, 0, sizeof(interned_slice_refcount *) * capacity);
+
+ for (i = 0; i < shard->capacity; i++) {
+ for (s = shard->strs[i]; s; s = next) {
+ size_t idx = TABLE_IDX(s->hash, capacity);
+ next = s->bucket_next;
+ s->bucket_next = strtab[idx];
+ strtab[idx] = s;
+ }
+ }
+
+ gpr_free(shard->strs);
+ shard->strs = strtab;
+ shard->capacity = capacity;
+
+ GPR_TIMER_END("grow_strtab", 0);
+}
+
+static grpc_slice materialize(interned_slice_refcount *s) {
+ grpc_slice slice;
+ slice.refcount = &s->base;
+ slice.data.refcounted.bytes = (uint8_t *)(s + 1);
+ slice.data.refcounted.length = s->length;
+ return slice;
+}
+
+uint32_t grpc_slice_default_hash_impl(void *unused_refcnt, grpc_slice s) {
+ return gpr_murmur_hash3(GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s),
+ g_hash_seed);
+}
+
+uint32_t grpc_static_slice_hash(void *unused_refcnt, grpc_slice s) {
+ int id = grpc_static_metadata_index(s);
+ if (id == -1) {
+ return grpc_slice_default_hash_impl(unused_refcnt, s);
+ }
+ return static_metadata_hash_values[id];
+}
+
+uint32_t grpc_slice_hash(grpc_slice s) {
+ return s.refcount == NULL ? grpc_slice_default_hash_impl(NULL, s)
+ : s.refcount->vtable->hash(s.refcount, s);
+}
+
+void grpc_slice_static_intern(grpc_slice *slice) {
+ if (grpc_is_static_metadata_string(*slice)) {
+ return;
+ }
+
+ uint32_t hash = grpc_slice_hash(*slice);
+ for (uint32_t i = 0; i <= max_static_metadata_hash_probe; i++) {
+ static_metadata_hash_ent ent =
+ static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)];
+ if (ent.hash == hash && ent.idx < GRPC_STATIC_MDSTR_COUNT &&
+ 0 == grpc_slice_cmp(grpc_static_slice_table[ent.idx], *slice)) {
+ grpc_slice_unref(*slice);
+ *slice = grpc_static_slice_table[ent.idx];
+ return;
+ }
+ }
+}
+
+bool grpc_slice_is_interned(grpc_slice slice) {
+ return (slice.refcount && slice.refcount->vtable == &interned_slice_vtable) ||
+ grpc_is_static_metadata_string(slice);
+}
+
+grpc_slice grpc_slice_intern(grpc_slice slice) {
+ if (grpc_is_static_metadata_string(slice)) {
+ return slice;
+ }
+
+ uint32_t hash = grpc_slice_hash(slice);
+ for (uint32_t i = 0; i <= max_static_metadata_hash_probe; i++) {
+ static_metadata_hash_ent ent =
+ static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)];
+ if (ent.hash == hash && ent.idx < GRPC_STATIC_MDSTR_COUNT &&
+ 0 == grpc_slice_cmp(grpc_static_slice_table[ent.idx], slice)) {
+ return grpc_static_slice_table[ent.idx];
+ }
+ }
+
+ interned_slice_refcount *s;
+ slice_shard *shard = &g_shards[SHARD_IDX(hash)];
+
+ gpr_mu_lock(&shard->mu);
+
+ /* search for an existing string */
+ size_t idx = TABLE_IDX(hash, shard->capacity);
+ for (s = shard->strs[idx]; s; s = s->bucket_next) {
+ if (s->hash == hash && grpc_slice_cmp(slice, materialize(s)) == 0) {
+ if (gpr_atm_no_barrier_fetch_add(&s->refcnt, 1) == 0) {
+ /* If we get here, we've added a ref to something that was about to
+ * die - drop it immediately.
+ * The *only* possible path here (given the shard mutex) should be to
+ * drop from one ref back to zero - assert that with a CAS */
+ GPR_ASSERT(gpr_atm_rel_cas(&s->refcnt, 1, 0));
+ /* and treat this as if we were never here... sshhh */
+ } else {
+ gpr_mu_unlock(&shard->mu);
+ GPR_TIMER_END("grpc_mdstr_from_buffer", 0);
+ return materialize(s);
+ }
+ }
+ }
+
+ /* not found: create a new string */
+ /* string data goes after the internal_string header */
+ s = gpr_malloc(sizeof(*s) + GRPC_SLICE_LENGTH(slice));
+ gpr_atm_rel_store(&s->refcnt, 1);
+ s->length = GRPC_SLICE_LENGTH(slice);
+ s->hash = hash;
+ s->base.vtable = &interned_slice_vtable;
+ s->bucket_next = shard->strs[idx];
+ shard->strs[idx] = s;
+ memcpy(s + 1, GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice));
+
+ shard->count++;
+
+ if (shard->count > shard->capacity * 2) {
+ grow_shard(shard);
+ }
+
+ gpr_mu_unlock(&shard->mu);
+
+ return materialize(s);
+}
+
+void grpc_test_only_set_slice_hash_seed(uint32_t seed) {
+ g_hash_seed = seed;
+ g_forced_hash_seed = 1;
+}
+
+void grpc_slice_intern_init(void) {
+ if (!g_forced_hash_seed) {
+ g_hash_seed = (uint32_t)gpr_now(GPR_CLOCK_REALTIME).tv_nsec;
+ }
+ for (size_t i = 0; i < SHARD_COUNT; i++) {
+ slice_shard *shard = &g_shards[i];
+ gpr_mu_init(&shard->mu);
+ shard->count = 0;
+ shard->capacity = INITIAL_SHARD_CAPACITY;
+ shard->strs = gpr_malloc(sizeof(*shard->strs) * shard->capacity);
+ memset(shard->strs, 0, sizeof(*shard->strs) * shard->capacity);
+ }
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(static_metadata_hash); i++) {
+ static_metadata_hash[i].hash = 0;
+ static_metadata_hash[i].idx = GRPC_STATIC_MDSTR_COUNT;
+ }
+ max_static_metadata_hash_probe = 0;
+ for (size_t i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) {
+ static_metadata_hash_values[i] =
+ grpc_slice_default_hash_impl(NULL, grpc_static_slice_table[i]);
+ for (size_t j = 0; j < GPR_ARRAY_SIZE(static_metadata_hash); j++) {
+ size_t slot = (static_metadata_hash_values[i] + j) %
+ GPR_ARRAY_SIZE(static_metadata_hash);
+ if (static_metadata_hash[slot].idx == GRPC_STATIC_MDSTR_COUNT) {
+ static_metadata_hash[slot].hash = static_metadata_hash_values[i];
+ static_metadata_hash[slot].idx = (uint32_t)i;
+ if (j > max_static_metadata_hash_probe) {
+ max_static_metadata_hash_probe = (uint32_t)j;
+ }
+ break;
+ }
+ }
+ }
+}
+
+void grpc_slice_intern_shutdown(void) {
+ for (size_t i = 0; i < SHARD_COUNT; i++) {
+ slice_shard *shard = &g_shards[i];
+ gpr_mu_destroy(&shard->mu);
+ /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */
+ if (shard->count != 0) {
+ gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata strings were leaked",
+ shard->count);
+ for (size_t j = 0; j < shard->capacity; j++) {
+ for (interned_slice_refcount *s = shard->strs[j]; s;
+ s = s->bucket_next) {
+ char *text =
+ grpc_dump_slice(materialize(s), GPR_DUMP_HEX | GPR_DUMP_ASCII);
+ gpr_log(GPR_DEBUG, "LEAKED: %s", text);
+ gpr_free(text);
+ }
+ }
+ if (grpc_iomgr_abort_on_leaks()) {
+ abort();
+ }
+ }
+ gpr_free(shard->strs);
+ }
+}
diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h
new file mode 100644
index 0000000000..211d5f06be
--- /dev/null
+++ b/src/core/lib/slice/slice_internal.h
@@ -0,0 +1,60 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H
+#define GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H
+
+#include <grpc/slice.h>
+#include <grpc/slice_buffer.h>
+
+#include "src/core/lib/iomgr/exec_ctx.h"
+
+grpc_slice grpc_slice_ref_internal(grpc_slice slice);
+void grpc_slice_unref_internal(grpc_exec_ctx *exec_ctx, grpc_slice slice);
+void grpc_slice_buffer_reset_and_unref_internal(grpc_exec_ctx *exec_ctx,
+ grpc_slice_buffer *sb);
+void grpc_slice_buffer_destroy_internal(grpc_exec_ctx *exec_ctx,
+ grpc_slice_buffer *sb);
+
+/* Check if a slice is interned */
+bool grpc_slice_is_interned(grpc_slice slice);
+
+void grpc_slice_intern_init(void);
+void grpc_slice_intern_shutdown(void);
+void grpc_test_only_set_slice_hash_seed(uint32_t key);
+// if slice matches a static slice, consume it and replace it with the static
+// slice, otherwise do nothing: this is a fast interning for well known strings
+void grpc_slice_static_intern(grpc_slice *slice);
+uint32_t grpc_static_slice_hash(void *refcnt, grpc_slice s);
+
+#endif /* GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H */
diff --git a/src/core/lib/slice/slice_string_helpers.c b/src/core/lib/slice/slice_string_helpers.c
index 4731762ece..99695007cc 100644
--- a/src/core/lib/slice/slice_string_helpers.c
+++ b/src/core/lib/slice/slice_string_helpers.c
@@ -37,6 +37,7 @@
#include <grpc/support/log.h>
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/support/string.h"
char *grpc_dump_slice(grpc_slice s, uint32_t flags) {
@@ -84,6 +85,11 @@ void grpc_slice_split(grpc_slice str, const char *sep, grpc_slice_buffer *dst) {
grpc_slice_buffer_add_indexed(
dst, grpc_slice_sub(str, end + sep_len, GRPC_SLICE_LENGTH(str)));
} else { /* no sep found, add whole input */
- grpc_slice_buffer_add_indexed(dst, grpc_slice_ref(str));
+ grpc_slice_buffer_add_indexed(dst, grpc_slice_ref_internal(str));
}
}
+
+bool grpc_parse_slice_to_uint32(grpc_slice str, uint32_t *result) {
+ return gpr_parse_bytes_to_uint32((const char *)GRPC_SLICE_START_PTR(str),
+ GRPC_SLICE_LENGTH(str), result) != 0;
+}
diff --git a/src/core/lib/slice/slice_string_helpers.h b/src/core/lib/slice/slice_string_helpers.h
index 151c720777..4a4deec6e5 100644
--- a/src/core/lib/slice/slice_string_helpers.h
+++ b/src/core/lib/slice/slice_string_helpers.h
@@ -34,12 +34,15 @@
#ifndef GRPC_CORE_LIB_SLICE_SLICE_STRING_HELPERS_H
#define GRPC_CORE_LIB_SLICE_SLICE_STRING_HELPERS_H
+#include <stdbool.h>
#include <stddef.h>
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
#include <grpc/support/port_platform.h>
+#include "src/core/lib/support/string.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -51,6 +54,8 @@ char *grpc_dump_slice(grpc_slice slice, uint32_t flags);
* should be a properly initialized instance. */
void grpc_slice_split(grpc_slice str, const char *sep, grpc_slice_buffer *dst);
+bool grpc_parse_slice_to_uint32(grpc_slice str, uint32_t *result);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/core/lib/slice/slice_traits.h b/src/core/lib/slice/slice_traits.h
new file mode 100644
index 0000000000..facbd0dd81
--- /dev/null
+++ b/src/core/lib/slice/slice_traits.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef SLICE_TRAITS_H
+#define SLICE_TRAITS_H
+
+#include <grpc/slice.h>
+#include <stdbool.h>
+
+bool grpc_slice_is_legal_header(grpc_slice s);
+bool grpc_slice_is_legal_nonbin_header(grpc_slice s);
+bool grpc_slice_is_bin_suffixed(grpc_slice s);
+
+#endif
diff --git a/src/core/lib/support/string.c b/src/core/lib/support/string.c
index f10a30f0fd..0dc55c2ca3 100644
--- a/src/core/lib/support/string.c
+++ b/src/core/lib/support/string.c
@@ -275,3 +275,29 @@ int gpr_stricmp(const char *a, const char *b) {
} while (ca == cb && ca && cb);
return ca - cb;
}
+
+static void add_string_to_split(const char *beg, const char *end, char ***strs,
+ size_t *nstrs, size_t *capstrs) {
+ char *out = gpr_malloc((size_t)(end - beg) + 1);
+ memcpy(out, beg, (size_t)(end - beg));
+ out[end - beg] = 0;
+ if (*nstrs == *capstrs) {
+ *capstrs = GPR_MAX(8, 2 * *capstrs);
+ *strs = gpr_realloc(*strs, sizeof(*strs) * *capstrs);
+ }
+ (*strs)[*nstrs] = out;
+ ++*nstrs;
+}
+
+void gpr_string_split(const char *input, const char *sep, char ***strs,
+ size_t *nstrs) {
+ char *next;
+ *strs = NULL;
+ *nstrs = 0;
+ size_t capstrs = 0;
+ while ((next = strstr(input, sep))) {
+ add_string_to_split(input, next, strs, nstrs, &capstrs);
+ input = next + strlen(sep);
+ }
+ add_string_to_split(input, input + strlen(input), strs, nstrs, &capstrs);
+}
diff --git a/src/core/lib/support/string.h b/src/core/lib/support/string.h
index e933e2eb46..43ab4dc1be 100644
--- a/src/core/lib/support/string.h
+++ b/src/core/lib/support/string.h
@@ -98,6 +98,9 @@ char *gpr_strjoin(const char **strs, size_t nstrs, size_t *total_length);
char *gpr_strjoin_sep(const char **strs, size_t nstrs, const char *sep,
size_t *total_length);
+void gpr_string_split(const char *input, const char *sep, char ***strs,
+ size_t *nstrs);
+
/* A vector of strings... for building up a final string one piece at a time */
typedef struct {
char **strs;
diff --git a/src/core/lib/surface/byte_buffer.c b/src/core/lib/surface/byte_buffer.c
index d646591a65..c8e2fdfdad 100644
--- a/src/core/lib/surface/byte_buffer.c
+++ b/src/core/lib/surface/byte_buffer.c
@@ -35,6 +35,8 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include "src/core/lib/slice/slice_internal.h"
+
grpc_byte_buffer *grpc_raw_byte_buffer_create(grpc_slice *slices,
size_t nslices) {
return grpc_raw_compressed_byte_buffer_create(slices, nslices,
@@ -50,7 +52,7 @@ grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create(
bb->data.raw.compression = compression;
grpc_slice_buffer_init(&bb->data.raw.slice_buffer);
for (i = 0; i < nslices; i++) {
- grpc_slice_ref(slices[i]);
+ grpc_slice_ref_internal(slices[i]);
grpc_slice_buffer_add(&bb->data.raw.slice_buffer, slices[i]);
}
return bb;
@@ -82,12 +84,14 @@ grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb) {
void grpc_byte_buffer_destroy(grpc_byte_buffer *bb) {
if (!bb) return;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
switch (bb->type) {
case GRPC_BB_RAW:
- grpc_slice_buffer_destroy(&bb->data.raw.slice_buffer);
+ grpc_slice_buffer_destroy_internal(&exec_ctx, &bb->data.raw.slice_buffer);
break;
}
gpr_free(bb);
+ grpc_exec_ctx_finish(&exec_ctx);
}
size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) {
diff --git a/src/core/lib/surface/byte_buffer_reader.c b/src/core/lib/surface/byte_buffer_reader.c
index 0089959fbb..1a6ccdaddb 100644
--- a/src/core/lib/surface/byte_buffer_reader.c
+++ b/src/core/lib/surface/byte_buffer_reader.c
@@ -42,6 +42,7 @@
#include <grpc/support/log.h>
#include "src/core/lib/compression/message_compress.h"
+#include "src/core/lib/slice/slice_internal.h"
static int is_compressed(grpc_byte_buffer *buffer) {
switch (buffer->type) {
@@ -56,13 +57,15 @@ static int is_compressed(grpc_byte_buffer *buffer) {
int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
grpc_byte_buffer *buffer) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_slice_buffer decompressed_slices_buffer;
reader->buffer_in = buffer;
switch (reader->buffer_in->type) {
case GRPC_BB_RAW:
grpc_slice_buffer_init(&decompressed_slices_buffer);
if (is_compressed(reader->buffer_in)) {
- if (grpc_msg_decompress(reader->buffer_in->data.raw.compression,
+ if (grpc_msg_decompress(&exec_ctx,
+ reader->buffer_in->data.raw.compression,
&reader->buffer_in->data.raw.slice_buffer,
&decompressed_slices_buffer) == 0) {
gpr_log(GPR_ERROR,
@@ -76,13 +79,15 @@ int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
grpc_raw_byte_buffer_create(decompressed_slices_buffer.slices,
decompressed_slices_buffer.count);
}
- grpc_slice_buffer_destroy(&decompressed_slices_buffer);
+ grpc_slice_buffer_destroy_internal(&exec_ctx,
+ &decompressed_slices_buffer);
} else { /* not compressed, use the input buffer as output */
reader->buffer_out = reader->buffer_in;
}
reader->current.index = 0;
break;
}
+ grpc_exec_ctx_finish(&exec_ctx);
return 1;
}
@@ -104,7 +109,8 @@ int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader,
grpc_slice_buffer *slice_buffer;
slice_buffer = &reader->buffer_out->data.raw.slice_buffer;
if (reader->current.index < slice_buffer->count) {
- *slice = grpc_slice_ref(slice_buffer->slices[reader->current.index]);
+ *slice = grpc_slice_ref_internal(
+ slice_buffer->slices[reader->current.index]);
reader->current.index += 1;
return 1;
}
@@ -121,12 +127,14 @@ grpc_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader) {
grpc_slice out_slice = grpc_slice_malloc(input_size);
uint8_t *const outbuf = GRPC_SLICE_START_PTR(out_slice); /* just an alias */
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (grpc_byte_buffer_reader_next(reader, &in_slice) != 0) {
const size_t slice_length = GRPC_SLICE_LENGTH(in_slice);
memcpy(&(outbuf[bytes_read]), GRPC_SLICE_START_PTR(in_slice), slice_length);
bytes_read += slice_length;
- grpc_slice_unref(in_slice);
+ grpc_slice_unref_internal(&exec_ctx, in_slice);
GPR_ASSERT(bytes_read <= input_size);
}
+ grpc_exec_ctx_finish(&exec_ctx);
return out_slice;
}
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index 1e0f3eeca5..0ca97337e2 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -49,6 +49,7 @@
#include "src/core/lib/compression/algorithm_metadata.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/surface/api_trace.h"
@@ -91,9 +92,10 @@ typedef enum {
} status_source;
typedef struct {
- uint8_t is_set;
+ bool is_code_set;
+ bool is_details_set;
grpc_status_code code;
- grpc_mdstr *details;
+ grpc_slice details;
} received_status;
typedef struct batch_control {
@@ -195,8 +197,7 @@ struct grpc_call {
union {
struct {
grpc_status_code *status;
- char **status_details;
- size_t *status_details_capacity;
+ grpc_slice *status_details;
} client;
struct {
int *cancelled;
@@ -226,12 +227,12 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call_stack,
static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
grpc_error *error);
-grpc_error *grpc_call_create(const grpc_call_create_args *args,
+grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
+ const grpc_call_create_args *args,
grpc_call **out_call) {
size_t i, j;
grpc_channel_stack *channel_stack =
grpc_channel_get_channel_stack(args->channel);
- grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_call *call;
GPR_TIMER_BEGIN("grpc_call_create", 0);
call = gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size);
@@ -245,14 +246,16 @@ grpc_error *grpc_call_create(const grpc_call_create_args *args,
/* Always support no compression */
GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE);
call->is_client = args->server_transport_data == NULL;
- grpc_mdstr *path = NULL;
+ grpc_slice path = grpc_empty_slice();
if (call->is_client) {
GPR_ASSERT(args->add_initial_metadata_count <
MAX_SEND_EXTRA_METADATA_COUNT);
for (i = 0; i < args->add_initial_metadata_count; i++) {
call->send_extra_metadata[i].md = args->add_initial_metadata[i];
- if (args->add_initial_metadata[i]->key == GRPC_MDSTR_PATH) {
- path = GRPC_MDSTR_REF(args->add_initial_metadata[i]->value);
+ if (grpc_slice_cmp(GRPC_MDKEY(args->add_initial_metadata[i]),
+ GRPC_MDSTR_PATH) == 0) {
+ path = grpc_slice_ref_internal(
+ GRPC_MDVALUE(args->add_initial_metadata[i]));
}
}
call->send_extra_metadata_count = (int)args->add_initial_metadata_count;
@@ -315,14 +318,14 @@ grpc_error *grpc_call_create(const grpc_call_create_args *args,
GRPC_CHANNEL_INTERNAL_REF(args->channel, "call");
/* initial refcount dropped by grpc_call_destroy */
grpc_error *error = grpc_call_stack_init(
- &exec_ctx, channel_stack, 1, destroy_call, call, call->context,
+ exec_ctx, channel_stack, 1, destroy_call, call, call->context,
args->server_transport_data, path, call->start_time, send_deadline,
CALL_STACK_FROM_CALL(call));
if (error != GRPC_ERROR_NONE) {
grpc_status_code status;
const char *error_str;
grpc_error_get_status(error, &status, &error_str);
- close_with_status(&exec_ctx, call, status, error_str);
+ close_with_status(exec_ctx, call, status, error_str);
}
if (args->cq != NULL) {
GPR_ASSERT(
@@ -338,12 +341,11 @@ grpc_error *grpc_call_create(const grpc_call_create_args *args,
}
if (!grpc_polling_entity_is_empty(&call->pollent)) {
grpc_call_stack_set_pollset_or_pollset_set(
- &exec_ctx, CALL_STACK_FROM_CALL(call), &call->pollent);
+ exec_ctx, CALL_STACK_FROM_CALL(call), &call->pollent);
}
- if (path != NULL) GRPC_MDSTR_UNREF(path);
+ grpc_slice_unref_internal(exec_ctx, path);
- grpc_exec_ctx_finish(&exec_ctx);
GPR_TIMER_END("grpc_call_create", 0);
return error;
}
@@ -383,7 +385,7 @@ static void get_final_status(grpc_call *call,
void *set_value_user_data) {
int i;
for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
- if (call->status[i].is_set) {
+ if (call->status[i].is_code_set) {
set_value(call->status[i].code, set_value_user_data);
return;
}
@@ -404,19 +406,19 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
GPR_TIMER_BEGIN("destroy_call", 0);
for (i = 0; i < 2; i++) {
grpc_metadata_batch_destroy(
- &c->metadata_batch[1 /* is_receiving */][i /* is_initial */]);
+ exec_ctx, &c->metadata_batch[1 /* is_receiving */][i /* is_initial */]);
}
if (c->receiving_stream != NULL) {
grpc_byte_stream_destroy(exec_ctx, c->receiving_stream);
}
gpr_mu_destroy(&c->mu);
for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
- if (c->status[i].details) {
- GRPC_MDSTR_UNREF(c->status[i].details);
+ if (c->status[i].is_details_set) {
+ grpc_slice_unref_internal(exec_ctx, c->status[i].details);
}
}
for (ii = 0; ii < c->send_extra_metadata_count; ii++) {
- GRPC_MDELEM_UNREF(c->send_extra_metadata[ii].md);
+ GRPC_MDELEM_UNREF(exec_ctx, c->send_extra_metadata[ii].md);
}
for (i = 0; i < GRPC_CONTEXT_COUNT; i++) {
if (c->context[i].destroy) {
@@ -440,28 +442,30 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
static void set_status_code(grpc_call *call, status_source source,
uint32_t status) {
- if (call->status[source].is_set) return;
+ if (call->status[source].is_code_set) return;
- call->status[source].is_set = 1;
+ call->status[source].is_code_set = true;
call->status[source].code = (grpc_status_code)status;
}
-static void set_status_details(grpc_call *call, status_source source,
- grpc_mdstr *status) {
- if (call->status[source].details != NULL) {
- GRPC_MDSTR_UNREF(status);
+static void set_status_details(grpc_exec_ctx *exec_ctx, grpc_call *call,
+ status_source source, grpc_slice status) {
+ if (call->status[source].is_details_set) {
+ grpc_slice_unref_internal(exec_ctx, status);
} else {
call->status[source].details = status;
+ call->status[source].is_details_set = true;
}
}
-static void set_status_from_error(grpc_call *call, status_source source,
- grpc_error *error) {
+static void set_status_from_error(grpc_exec_ctx *exec_ctx, grpc_call *call,
+ status_source source, grpc_error *error) {
grpc_status_code status;
const char *msg;
grpc_error_get_status(error, &status, &msg);
set_status_code(call, source, (uint32_t)status);
- set_status_details(call, source, grpc_mdstr_from_string(msg));
+ set_status_details(exec_ctx, call, source,
+ grpc_slice_from_copied_string(msg));
}
static void set_incoming_compression_algorithm(
@@ -495,7 +499,8 @@ uint32_t grpc_call_test_only_get_message_flags(grpc_call *call) {
static void destroy_encodings_accepted_by_peer(void *p) { return; }
-static void set_encodings_accepted_by_peer(grpc_call *call, grpc_mdelem *mdel) {
+static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx,
+ grpc_call *call, grpc_mdelem mdel) {
size_t i;
grpc_compression_algorithm algorithm;
grpc_slice_buffer accept_encoding_parts;
@@ -510,7 +515,7 @@ static void set_encodings_accepted_by_peer(grpc_call *call, grpc_mdelem *mdel) {
return;
}
- accept_encoding_slice = mdel->value->slice;
+ accept_encoding_slice = GRPC_MDVALUE(mdel);
grpc_slice_buffer_init(&accept_encoding_parts);
grpc_slice_split(accept_encoding_slice, ",", &accept_encoding_parts);
@@ -519,15 +524,13 @@ static void set_encodings_accepted_by_peer(grpc_call *call, grpc_mdelem *mdel) {
/* Always support no compression */
GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE);
for (i = 0; i < accept_encoding_parts.count; i++) {
- const grpc_slice *accept_encoding_entry_slice =
- &accept_encoding_parts.slices[i];
- if (grpc_compression_algorithm_parse(
- (const char *)GRPC_SLICE_START_PTR(*accept_encoding_entry_slice),
- GRPC_SLICE_LENGTH(*accept_encoding_entry_slice), &algorithm)) {
+ grpc_slice accept_encoding_entry_slice = accept_encoding_parts.slices[i];
+ if (grpc_compression_algorithm_parse(accept_encoding_entry_slice,
+ &algorithm)) {
GPR_BITSET(&call->encodings_accepted_by_peer, algorithm);
} else {
char *accept_encoding_entry_str =
- grpc_dump_slice(*accept_encoding_entry_slice, GPR_DUMP_ASCII);
+ grpc_dump_slice(accept_encoding_entry_slice, GPR_DUMP_ASCII);
gpr_log(GPR_ERROR,
"Invalid entry in accept encoding metadata: '%s'. Ignoring.",
accept_encoding_entry_str);
@@ -535,7 +538,7 @@ static void set_encodings_accepted_by_peer(grpc_call *call, grpc_mdelem *mdel) {
}
}
- grpc_slice_buffer_destroy(&accept_encoding_parts);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &accept_encoding_parts);
grpc_mdelem_set_user_data(
mdel, destroy_encodings_accepted_by_peer,
@@ -550,21 +553,12 @@ uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) {
return encodings_accepted_by_peer;
}
-static void get_final_details(grpc_call *call, char **out_details,
- size_t *out_details_capacity) {
+static void get_final_details(grpc_call *call, grpc_slice *out_details) {
int i;
for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
- if (call->status[i].is_set) {
- if (call->status[i].details) {
- grpc_slice details = call->status[i].details->slice;
- size_t len = GRPC_SLICE_LENGTH(details);
- if (len + 1 > *out_details_capacity) {
- *out_details_capacity =
- GPR_MAX(len + 1, *out_details_capacity * 3 / 2);
- *out_details = gpr_realloc(*out_details, *out_details_capacity);
- }
- memcpy(*out_details, GRPC_SLICE_START_PTR(details), len);
- (*out_details)[len] = 0;
+ if (call->status[i].is_code_set) {
+ if (call->status[i].is_details_set) {
+ *out_details = grpc_slice_ref(call->status[i].details);
} else {
goto no_details;
}
@@ -573,11 +567,7 @@ static void get_final_details(grpc_call *call, char **out_details,
}
no_details:
- if (0 == *out_details_capacity) {
- *out_details_capacity = 8;
- *out_details = gpr_malloc(*out_details_capacity);
- }
- **out_details = 0;
+ *out_details = grpc_empty_slice();
}
static grpc_linked_mdelem *linked_from_md(grpc_metadata *md) {
@@ -593,12 +583,10 @@ static grpc_metadata *get_md_elem(grpc_metadata *metadata,
return res;
}
-static int prepare_application_metadata(grpc_call *call, int count,
- grpc_metadata *metadata,
- int is_trailing,
- int prepend_extra_metadata,
- grpc_metadata *additional_metadata,
- int additional_metadata_count) {
+static int prepare_application_metadata(
+ grpc_exec_ctx *exec_ctx, grpc_call *call, int count,
+ grpc_metadata *metadata, int is_trailing, int prepend_extra_metadata,
+ grpc_metadata *additional_metadata, int additional_metadata_count) {
int total_count = count + additional_metadata_count;
int i;
grpc_metadata_batch *batch =
@@ -608,28 +596,26 @@ static int prepare_application_metadata(grpc_call *call, int count,
get_md_elem(metadata, additional_metadata, i, count);
grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data));
- l->md = grpc_mdelem_from_string_and_buffer(
- md->key, (const uint8_t *)md->value, md->value_length);
- if (!grpc_header_key_is_legal(grpc_mdstr_as_c_string(l->md->key),
- GRPC_MDSTR_LENGTH(l->md->key))) {
- gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s",
- grpc_mdstr_as_c_string(l->md->key));
+ if (!grpc_header_key_is_legal(md->key)) {
+ char *str = grpc_dump_slice(md->key, GPR_DUMP_ASCII);
+ gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s", str);
+ gpr_free(str);
break;
- } else if (!grpc_is_binary_header(grpc_mdstr_as_c_string(l->md->key),
- GRPC_MDSTR_LENGTH(l->md->key)) &&
- !grpc_header_nonbin_value_is_legal(
- grpc_mdstr_as_c_string(l->md->value),
- GRPC_MDSTR_LENGTH(l->md->value))) {
- gpr_log(GPR_ERROR, "attempt to send invalid metadata value");
+ } else if (!grpc_is_binary_header(md->key) &&
+ !grpc_header_nonbin_value_is_legal(md->value)) {
+ char *str = grpc_dump_slice(md->value, GPR_DUMP_HEX | GPR_DUMP_ASCII);
+ gpr_log(GPR_ERROR, "attempt to send invalid metadata value: %s", str);
+ gpr_free(str);
break;
}
+ l->md = grpc_mdelem_from_grpc_metadata(exec_ctx, (grpc_metadata *)md);
}
if (i != total_count) {
- for (int j = 0; j <= i; j++) {
+ for (int j = 0; j < i; j++) {
const grpc_metadata *md =
get_md_elem(metadata, additional_metadata, j, count);
grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
- GRPC_MDELEM_UNREF(l->md);
+ GRPC_MDELEM_UNREF(exec_ctx, l->md);
}
return 0;
}
@@ -811,7 +797,8 @@ static void send_close(grpc_exec_ctx *exec_ctx, void *tcp, grpc_error *error) {
static grpc_call_error terminate_with_status(grpc_exec_ctx *exec_ctx,
termination_closure *tc) {
- set_status_from_error(tc->call, STATUS_FROM_API_OVERRIDE, tc->error);
+ set_status_from_error(exec_ctx, tc->call, STATUS_FROM_API_OVERRIDE,
+ tc->error);
if (tc->type == TC_CANCEL) {
grpc_closure_init(&tc->closure, send_cancel, tc);
@@ -893,19 +880,17 @@ grpc_call *grpc_call_from_top_element(grpc_call_element *elem) {
#define STATUS_OFFSET 1
static void destroy_status(void *ignored) {}
-static uint32_t decode_status(grpc_mdelem *md) {
+static uint32_t decode_status(grpc_mdelem md) {
uint32_t status;
void *user_data;
- if (md == GRPC_MDELEM_GRPC_STATUS_0) return 0;
- if (md == GRPC_MDELEM_GRPC_STATUS_1) return 1;
- if (md == GRPC_MDELEM_GRPC_STATUS_2) return 2;
+ if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) return 0;
+ if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_1)) return 1;
+ if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_2)) return 2;
user_data = grpc_mdelem_get_user_data(md, destroy_status);
if (user_data != NULL) {
status = ((uint32_t)(intptr_t)user_data) - STATUS_OFFSET;
} else {
- if (!gpr_parse_bytes_to_uint32(grpc_mdstr_as_c_string(md->value),
- GRPC_SLICE_LENGTH(md->value->slice),
- &status)) {
+ if (!grpc_parse_slice_to_uint32(GRPC_MDVALUE(md), &status)) {
status = GRPC_STATUS_UNKNOWN; /* could not parse status code */
}
grpc_mdelem_set_user_data(md, destroy_status,
@@ -914,37 +899,40 @@ static uint32_t decode_status(grpc_mdelem *md) {
return status;
}
-static grpc_compression_algorithm decode_compression(grpc_mdelem *md) {
+static grpc_compression_algorithm decode_compression(grpc_mdelem md) {
grpc_compression_algorithm algorithm =
- grpc_compression_algorithm_from_mdstr(md->value);
+ grpc_compression_algorithm_from_slice(GRPC_MDVALUE(md));
if (algorithm == GRPC_COMPRESS_ALGORITHMS_COUNT) {
- const char *md_c_str = grpc_mdstr_as_c_string(md->value);
+ char *md_c_str = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_ASCII);
gpr_log(GPR_ERROR,
"Invalid incoming compression algorithm: '%s'. Interpreting "
"incoming data as uncompressed.",
md_c_str);
+ gpr_free(md_c_str);
return GRPC_COMPRESS_NONE;
}
return algorithm;
}
-static grpc_mdelem *recv_common_filter(grpc_call *call, grpc_mdelem *elem) {
- if (elem->key == GRPC_MDSTR_GRPC_STATUS) {
+static grpc_mdelem recv_common_filter(grpc_exec_ctx *exec_ctx, grpc_call *call,
+ grpc_mdelem elem) {
+ if (grpc_slice_cmp(GRPC_MDKEY(elem), GRPC_MDSTR_GRPC_STATUS) == 0) {
GPR_TIMER_BEGIN("status", 0);
set_status_code(call, STATUS_FROM_WIRE, decode_status(elem));
GPR_TIMER_END("status", 0);
- return NULL;
- } else if (elem->key == GRPC_MDSTR_GRPC_MESSAGE) {
+ return GRPC_MDNULL;
+ } else if (grpc_slice_cmp(GRPC_MDKEY(elem), GRPC_MDSTR_GRPC_MESSAGE) == 0) {
GPR_TIMER_BEGIN("status-details", 0);
- set_status_details(call, STATUS_FROM_WIRE, GRPC_MDSTR_REF(elem->value));
+ set_status_details(exec_ctx, call, STATUS_FROM_WIRE,
+ grpc_slice_ref_internal(GRPC_MDVALUE(elem)));
GPR_TIMER_END("status-details", 0);
- return NULL;
+ return GRPC_MDNULL;
}
return elem;
}
-static grpc_mdelem *publish_app_metadata(grpc_call *call, grpc_mdelem *elem,
- int is_trailing) {
+static grpc_mdelem publish_app_metadata(grpc_call *call, grpc_mdelem elem,
+ int is_trailing) {
grpc_metadata_array *dest;
grpc_metadata *mdusr;
GPR_TIMER_BEGIN("publish_app_metadata", 0);
@@ -955,38 +943,40 @@ static grpc_mdelem *publish_app_metadata(grpc_call *call, grpc_mdelem *elem,
gpr_realloc(dest->metadata, sizeof(grpc_metadata) * dest->capacity);
}
mdusr = &dest->metadata[dest->count++];
- mdusr->key = grpc_mdstr_as_c_string(elem->key);
- mdusr->value = grpc_mdstr_as_c_string(elem->value);
- mdusr->value_length = GRPC_SLICE_LENGTH(elem->value->slice);
+ mdusr->key = grpc_slice_ref(GRPC_MDKEY(elem));
+ mdusr->value = grpc_slice_ref(GRPC_MDVALUE(elem));
GPR_TIMER_END("publish_app_metadata", 0);
return elem;
}
-static grpc_mdelem *recv_initial_filter(void *callp, grpc_mdelem *elem) {
- grpc_call *call = callp;
- elem = recv_common_filter(call, elem);
- if (elem == NULL) {
- return NULL;
- } else if (elem->key == GRPC_MDSTR_GRPC_ENCODING) {
+static grpc_mdelem recv_initial_filter(grpc_exec_ctx *exec_ctx, void *args,
+ grpc_mdelem elem) {
+ grpc_call *call = args;
+ elem = recv_common_filter(exec_ctx, call, elem);
+ if (GRPC_MDISNULL(elem)) {
+ return GRPC_MDNULL;
+ } else if (grpc_slice_cmp(GRPC_MDKEY(elem), GRPC_MDSTR_GRPC_ENCODING) == 0) {
GPR_TIMER_BEGIN("incoming_compression_algorithm", 0);
set_incoming_compression_algorithm(call, decode_compression(elem));
GPR_TIMER_END("incoming_compression_algorithm", 0);
- return NULL;
- } else if (elem->key == GRPC_MDSTR_GRPC_ACCEPT_ENCODING) {
+ return GRPC_MDNULL;
+ } else if (grpc_slice_cmp(GRPC_MDKEY(elem),
+ GRPC_MDSTR_GRPC_ACCEPT_ENCODING) == 0) {
GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0);
- set_encodings_accepted_by_peer(call, elem);
+ set_encodings_accepted_by_peer(exec_ctx, call, elem);
GPR_TIMER_END("encodings_accepted_by_peer", 0);
- return NULL;
+ return GRPC_MDNULL;
} else {
return publish_app_metadata(call, elem, 0);
}
}
-static grpc_mdelem *recv_trailing_filter(void *callp, grpc_mdelem *elem) {
- grpc_call *call = callp;
- elem = recv_common_filter(call, elem);
- if (elem == NULL) {
- return NULL;
+static grpc_mdelem recv_trailing_filter(grpc_exec_ctx *exec_ctx, void *args,
+ grpc_mdelem elem) {
+ grpc_call *call = args;
+ elem = recv_common_filter(exec_ctx, call, elem);
+ if (GRPC_MDISNULL(elem)) {
+ return GRPC_MDNULL;
} else {
return publish_app_metadata(call, elem, 1);
}
@@ -1234,7 +1224,7 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx,
if (error == GRPC_ERROR_NONE) {
grpc_metadata_batch *md =
&call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */];
- grpc_metadata_batch_filter(md, recv_initial_filter, call);
+ grpc_metadata_batch_filter(exec_ctx, md, recv_initial_filter, call);
GPR_TIMER_BEGIN("validate_filtered_metadata", 0);
validate_filtered_metadata(exec_ctx, bctl);
@@ -1278,14 +1268,15 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp,
intptr_t status;
if (error != GRPC_ERROR_NONE &&
grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &status)) {
- set_status_from_error(call, STATUS_FROM_CORE, error);
+ set_status_from_error(exec_ctx, call, STATUS_FROM_CORE, error);
}
if (bctl->send_initial_metadata) {
if (error != GRPC_ERROR_NONE) {
- set_status_from_error(call, STATUS_FROM_CORE, error);
+ set_status_from_error(exec_ctx, call, STATUS_FROM_CORE, error);
}
grpc_metadata_batch_destroy(
+ exec_ctx,
&call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */]);
}
if (bctl->send_message) {
@@ -1293,12 +1284,13 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp,
}
if (bctl->send_final_op) {
grpc_metadata_batch_destroy(
+ exec_ctx,
&call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */]);
}
if (bctl->recv_final_op) {
grpc_metadata_batch *md =
&call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
- grpc_metadata_batch_filter(md, recv_trailing_filter, call);
+ grpc_metadata_batch_filter(exec_ctx, md, recv_trailing_filter, call);
call->received_final_op = true;
/* propagate cancellation to any interested children */
@@ -1318,8 +1310,7 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp,
if (call->is_client) {
get_final_status(call, set_status_value_directly,
call->final_op.client.status);
- get_final_details(call, call->final_op.client.status_details,
- call->final_op.client.status_details_capacity);
+ get_final_details(call, call->final_op.client.status_details);
} else {
get_final_status(call, set_cancelled_value,
call->final_op.server.cancelled);
@@ -1417,13 +1408,10 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
const grpc_compression_algorithm calgo =
compression_algorithm_for_level_locked(
call, effective_compression_level);
- char *calgo_name = NULL;
- grpc_compression_algorithm_name(calgo, &calgo_name);
// the following will be picked up by the compress filter and used as
// the call's compression algorithm.
- compression_md.key = GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY;
- compression_md.value = calgo_name;
- compression_md.value_length = strlen(calgo_name);
+ compression_md.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST;
+ compression_md.value = grpc_compression_algorithm_slice(calgo);
additional_metadata_count++;
}
@@ -1435,7 +1423,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
bctl->send_initial_metadata = 1;
call->sent_initial_metadata = 1;
if (!prepare_application_metadata(
- call, (int)op->data.send_initial_metadata.count,
+ exec_ctx, call, (int)op->data.send_initial_metadata.count,
op->data.send_initial_metadata.metadata, 0, call->is_client,
&compression_md, (int)additional_metadata_count)) {
error = GRPC_CALL_ERROR_INVALID_METADATA;
@@ -1515,23 +1503,23 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
call->sent_final_op = 1;
call->send_extra_metadata_count = 1;
call->send_extra_metadata[0].md = grpc_channel_get_reffed_status_elem(
- call->channel, op->data.send_status_from_server.status);
+ exec_ctx, call->channel, op->data.send_status_from_server.status);
if (op->data.send_status_from_server.status_details != NULL) {
- call->send_extra_metadata[1].md = grpc_mdelem_from_metadata_strings(
- GRPC_MDSTR_GRPC_MESSAGE,
- grpc_mdstr_from_string(
- op->data.send_status_from_server.status_details));
+ call->send_extra_metadata[1].md = grpc_mdelem_from_slices(
+ exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
+ grpc_slice_ref_internal(
+ *op->data.send_status_from_server.status_details));
call->send_extra_metadata_count++;
- set_status_details(
- call, STATUS_FROM_API_OVERRIDE,
- GRPC_MDSTR_REF(call->send_extra_metadata[1].md->value));
+ set_status_details(exec_ctx, call, STATUS_FROM_API_OVERRIDE,
+ grpc_slice_ref_internal(GRPC_MDVALUE(
+ call->send_extra_metadata[1].md)));
}
if (op->data.send_status_from_server.status != GRPC_STATUS_OK) {
set_status_code(call, STATUS_FROM_API_OVERRIDE,
(uint32_t)op->data.send_status_from_server.status);
}
if (!prepare_application_metadata(
- call,
+ exec_ctx, call,
(int)op->data.send_status_from_server.trailing_metadata_count,
op->data.send_status_from_server.trailing_metadata, 1, 1, NULL,
0)) {
@@ -1601,8 +1589,6 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
call->final_op.client.status = op->data.recv_status_on_client.status;
call->final_op.client.status_details =
op->data.recv_status_on_client.status_details;
- call->final_op.client.status_details_capacity =
- op->data.recv_status_on_client.status_details_capacity;
bctl->recv_final_op = 1;
stream_op->recv_trailing_metadata =
&call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
@@ -1656,7 +1642,7 @@ done_with_error:
/* reverse any mutations that occured */
if (bctl->send_initial_metadata) {
call->sent_initial_metadata = 0;
- grpc_metadata_batch_clear(&call->metadata_batch[0][0]);
+ grpc_metadata_batch_clear(exec_ctx, &call->metadata_batch[0][0]);
}
if (bctl->send_message) {
call->sending_message = 0;
@@ -1664,7 +1650,7 @@ done_with_error:
}
if (bctl->send_final_op) {
call->sent_final_op = 0;
- grpc_metadata_batch_clear(&call->metadata_batch[0][1]);
+ grpc_metadata_batch_clear(exec_ctx, &call->metadata_batch[0][1]);
}
if (bctl->recv_initial_metadata) {
call->received_initial_metadata = 0;
diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h
index 18af41b7fb..8c46a83d42 100644
--- a/src/core/lib/surface/call.h
+++ b/src/core/lib/surface/call.h
@@ -61,7 +61,7 @@ typedef struct grpc_call_create_args {
const void *server_transport_data;
- grpc_mdelem **add_initial_metadata;
+ grpc_mdelem *add_initial_metadata;
size_t add_initial_metadata_count;
gpr_timespec send_deadline;
@@ -70,7 +70,8 @@ typedef struct grpc_call_create_args {
/* Create a new call based on \a args.
Regardless of success or failure, always returns a valid new call into *call
*/
-grpc_error *grpc_call_create(const grpc_call_create_args *args,
+grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
+ const grpc_call_create_args *args,
grpc_call **call);
void grpc_call_set_completion_queue(grpc_exec_ctx *exec_ctx, grpc_call *call,
diff --git a/src/core/lib/surface/call_details.c b/src/core/lib/surface/call_details.c
index fe73da3f55..5efa3b0141 100644
--- a/src/core/lib/surface/call_details.c
+++ b/src/core/lib/surface/call_details.c
@@ -41,10 +41,12 @@
void grpc_call_details_init(grpc_call_details* cd) {
GRPC_API_TRACE("grpc_call_details_init(cd=%p)", 1, (cd));
memset(cd, 0, sizeof(*cd));
+ cd->method = grpc_empty_slice();
+ cd->host = grpc_empty_slice();
}
void grpc_call_details_destroy(grpc_call_details* cd) {
GRPC_API_TRACE("grpc_call_details_destroy(cd=%p)", 1, (cd));
- gpr_free(cd->method);
- gpr_free(cd->host);
+ grpc_slice_unref(cd->method);
+ grpc_slice_unref(cd->host);
}
diff --git a/src/core/lib/surface/call_log_batch.c b/src/core/lib/surface/call_log_batch.c
index 31c074f15d..8f6438bc3b 100644
--- a/src/core/lib/surface/call_log_batch.c
+++ b/src/core/lib/surface/call_log_batch.c
@@ -35,17 +35,18 @@
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
+#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
static void add_metadata(gpr_strvec *b, const grpc_metadata *md, size_t count) {
size_t i;
for (i = 0; i < count; i++) {
gpr_strvec_add(b, gpr_strdup("\nkey="));
- gpr_strvec_add(b, gpr_strdup(md[i].key));
+ gpr_strvec_add(b, grpc_dump_slice(md[i].key, GPR_DUMP_ASCII));
gpr_strvec_add(b, gpr_strdup(" value="));
- gpr_strvec_add(b, gpr_dump(md[i].value, md[i].value_length,
- GPR_DUMP_HEX | GPR_DUMP_ASCII));
+ gpr_strvec_add(b,
+ grpc_dump_slice(md[i].value, GPR_DUMP_HEX | GPR_DUMP_ASCII));
}
}
@@ -70,10 +71,16 @@ char *grpc_op_string(const grpc_op *op) {
gpr_strvec_add(&b, gpr_strdup("SEND_CLOSE_FROM_CLIENT"));
break;
case GRPC_OP_SEND_STATUS_FROM_SERVER:
- gpr_asprintf(&tmp, "SEND_STATUS_FROM_SERVER status=%d details=%s",
- op->data.send_status_from_server.status,
- op->data.send_status_from_server.status_details);
+ gpr_asprintf(&tmp, "SEND_STATUS_FROM_SERVER status=%d details=",
+ op->data.send_status_from_server.status);
gpr_strvec_add(&b, tmp);
+ if (op->data.send_status_from_server.status_details != NULL) {
+ gpr_strvec_add(&b, grpc_dump_slice(
+ *op->data.send_status_from_server.status_details,
+ GPR_DUMP_ASCII));
+ } else {
+ gpr_strvec_add(&b, gpr_strdup("(null)"));
+ }
add_metadata(&b, op->data.send_status_from_server.trailing_metadata,
op->data.send_status_from_server.trailing_metadata_count);
break;
diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c
index 1389df6886..501545b5c0 100644
--- a/src/core/lib/surface/channel.c
+++ b/src/core/lib/surface/channel.c
@@ -57,15 +57,15 @@
#define NUM_CACHED_STATUS_ELEMS 3
typedef struct registered_call {
- grpc_mdelem *path;
- grpc_mdelem *authority;
+ grpc_mdelem path;
+ grpc_mdelem authority;
struct registered_call *next;
} registered_call;
struct grpc_channel {
int is_client;
grpc_compression_options compression_options;
- grpc_mdelem *default_authority;
+ grpc_mdelem default_authority;
gpr_mu registered_call_mu;
registered_call *registered_calls;
@@ -89,13 +89,14 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
bool is_client = grpc_channel_stack_type_is_client(channel_stack_type);
grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create();
- grpc_channel_stack_builder_set_channel_arguments(builder, input_args);
+ grpc_channel_stack_builder_set_channel_arguments(exec_ctx, builder,
+ input_args);
grpc_channel_stack_builder_set_target(builder, target);
grpc_channel_stack_builder_set_transport(builder, optional_transport);
grpc_channel *channel;
grpc_channel_args *args;
if (!grpc_channel_init_create_stack(exec_ctx, builder, channel_stack_type)) {
- grpc_channel_stack_builder_destroy(builder);
+ grpc_channel_stack_builder_destroy(exec_ctx, builder);
return NULL;
} else {
args = grpc_channel_args_copy(
@@ -118,12 +119,13 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
gpr_log(GPR_ERROR, "%s ignored: it must be a string",
GRPC_ARG_DEFAULT_AUTHORITY);
} else {
- if (channel->default_authority) {
+ if (!GRPC_MDISNULL(channel->default_authority)) {
/* setting this takes precedence over anything else */
- GRPC_MDELEM_UNREF(channel->default_authority);
+ GRPC_MDELEM_UNREF(exec_ctx, channel->default_authority);
}
- channel->default_authority = grpc_mdelem_from_strings(
- ":authority", args->args[i].value.string);
+ channel->default_authority = grpc_mdelem_from_slices(
+ exec_ctx, GRPC_MDSTR_AUTHORITY,
+ grpc_slice_from_copied_string(args->args[i].value.string));
}
} else if (0 ==
strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
@@ -131,14 +133,15 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
gpr_log(GPR_ERROR, "%s ignored: it must be a string",
GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
} else {
- if (channel->default_authority) {
+ if (!GRPC_MDISNULL(channel->default_authority)) {
/* other ways of setting this (notably ssl) take precedence */
gpr_log(GPR_ERROR,
"%s ignored: default host already set some other way",
GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
} else {
- channel->default_authority = grpc_mdelem_from_strings(
- ":authority", args->args[i].value.string);
+ channel->default_authority = grpc_mdelem_from_slices(
+ exec_ctx, GRPC_MDSTR_AUTHORITY,
+ grpc_slice_from_copied_string(args->args[i].value.string));
}
}
} else if (0 == strcmp(args->args[i].key,
@@ -164,7 +167,7 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
0x1; /* always support no compression */
}
}
- grpc_channel_args_destroy(args);
+ grpc_channel_args_destroy(exec_ctx, args);
}
return channel;
@@ -185,20 +188,20 @@ void grpc_channel_get_info(grpc_channel *channel,
}
static grpc_call *grpc_channel_create_call_internal(
- grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
- grpc_completion_queue *cq, grpc_pollset_set *pollset_set_alternative,
- grpc_mdelem *path_mdelem, grpc_mdelem *authority_mdelem,
- gpr_timespec deadline) {
- grpc_mdelem *send_metadata[2];
+ grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
+ uint32_t propagation_mask, grpc_completion_queue *cq,
+ grpc_pollset_set *pollset_set_alternative, grpc_mdelem path_mdelem,
+ grpc_mdelem authority_mdelem, gpr_timespec deadline) {
+ grpc_mdelem send_metadata[2];
size_t num_metadata = 0;
GPR_ASSERT(channel->is_client);
GPR_ASSERT(!(cq != NULL && pollset_set_alternative != NULL));
send_metadata[num_metadata++] = path_mdelem;
- if (authority_mdelem != NULL) {
+ if (!GRPC_MDISNULL(authority_mdelem)) {
send_metadata[num_metadata++] = authority_mdelem;
- } else if (channel->default_authority != NULL) {
+ } else if (!GRPC_MDISNULL(channel->default_authority)) {
send_metadata[num_metadata++] = GRPC_MDELEM_REF(channel->default_authority);
}
@@ -215,7 +218,7 @@ static grpc_call *grpc_channel_create_call_internal(
args.send_deadline = deadline;
grpc_call *call;
- GRPC_LOG_IF_ERROR("call_create", grpc_call_create(&args, &call));
+ GRPC_LOG_IF_ERROR("call_create", grpc_call_create(exec_ctx, &args, &call));
return call;
}
@@ -223,41 +226,34 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
grpc_call *parent_call,
uint32_t propagation_mask,
grpc_completion_queue *cq,
- const char *method, const char *host,
+ grpc_slice method, const grpc_slice *host,
gpr_timespec deadline, void *reserved) {
- GRPC_API_TRACE(
- "grpc_channel_create_call("
- "channel=%p, parent_call=%p, propagation_mask=%x, cq=%p, method=%s, "
- "host=%s, "
- "deadline=gpr_timespec { tv_sec: %" PRId64
- ", tv_nsec: %d, clock_type: %d }, "
- "reserved=%p)",
- 10,
- (channel, parent_call, (unsigned)propagation_mask, cq, method, host,
- deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type, reserved));
GPR_ASSERT(!reserved);
- return grpc_channel_create_call_internal(
- channel, parent_call, propagation_mask, cq, NULL,
- grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
- grpc_mdstr_from_string(method)),
- host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY,
- grpc_mdstr_from_string(host))
- : NULL,
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_call *call = grpc_channel_create_call_internal(
+ &exec_ctx, channel, parent_call, propagation_mask, cq, NULL,
+ grpc_mdelem_from_slices(&exec_ctx, GRPC_MDSTR_PATH,
+ grpc_slice_ref(method)),
+ host != NULL ? grpc_mdelem_from_slices(&exec_ctx, GRPC_MDSTR_AUTHORITY,
+ grpc_slice_ref(*host))
+ : GRPC_MDNULL,
deadline);
+ grpc_exec_ctx_finish(&exec_ctx);
+ return call;
}
grpc_call *grpc_channel_create_pollset_set_call(
- grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
- grpc_pollset_set *pollset_set, const char *method, const char *host,
- gpr_timespec deadline, void *reserved) {
+ grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
+ uint32_t propagation_mask, grpc_pollset_set *pollset_set, grpc_slice method,
+ const grpc_slice *host, gpr_timespec deadline, void *reserved) {
GPR_ASSERT(!reserved);
return grpc_channel_create_call_internal(
- channel, parent_call, propagation_mask, NULL, pollset_set,
- grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
- grpc_mdstr_from_string(method)),
- host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY,
- grpc_mdstr_from_string(host))
- : NULL,
+ exec_ctx, channel, parent_call, propagation_mask, NULL, pollset_set,
+ grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_PATH,
+ grpc_slice_ref(method)),
+ host != NULL ? grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_AUTHORITY,
+ grpc_slice_ref(*host))
+ : GRPC_MDNULL,
deadline);
}
@@ -268,15 +264,21 @@ void *grpc_channel_register_call(grpc_channel *channel, const char *method,
"grpc_channel_register_call(channel=%p, method=%s, host=%s, reserved=%p)",
4, (channel, method, host, reserved));
GPR_ASSERT(!reserved);
- rc->path = grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
- grpc_mdstr_from_string(method));
- rc->authority = host ? grpc_mdelem_from_metadata_strings(
- GRPC_MDSTR_AUTHORITY, grpc_mdstr_from_string(host))
- : NULL;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
+ rc->path = grpc_mdelem_from_slices(
+ &exec_ctx, GRPC_MDSTR_PATH,
+ grpc_slice_intern(grpc_slice_from_copied_string(method)));
+ rc->authority =
+ host ? grpc_mdelem_from_slices(
+ &exec_ctx, GRPC_MDSTR_AUTHORITY,
+ grpc_slice_intern(grpc_slice_from_copied_string(host)))
+ : GRPC_MDNULL;
gpr_mu_lock(&channel->registered_call_mu);
rc->next = channel->registered_calls;
channel->registered_calls = rc;
gpr_mu_unlock(&channel->registered_call_mu);
+ grpc_exec_ctx_finish(&exec_ctx);
return rc;
}
@@ -296,10 +298,12 @@ grpc_call *grpc_channel_create_registered_call(
registered_call_handle, deadline.tv_sec, deadline.tv_nsec,
(int)deadline.clock_type, reserved));
GPR_ASSERT(!reserved);
- return grpc_channel_create_call_internal(
- channel, parent_call, propagation_mask, completion_queue, NULL,
- GRPC_MDELEM_REF(rc->path),
- rc->authority ? GRPC_MDELEM_REF(rc->authority) : NULL, deadline);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_call *call = grpc_channel_create_call_internal(
+ &exec_ctx, channel, parent_call, propagation_mask, completion_queue, NULL,
+ GRPC_MDELEM_REF(rc->path), GRPC_MDELEM_REF(rc->authority), deadline);
+ grpc_exec_ctx_finish(&exec_ctx);
+ return call;
}
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
@@ -325,15 +329,11 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, void *arg,
while (channel->registered_calls) {
registered_call *rc = channel->registered_calls;
channel->registered_calls = rc->next;
- GRPC_MDELEM_UNREF(rc->path);
- if (rc->authority) {
- GRPC_MDELEM_UNREF(rc->authority);
- }
+ GRPC_MDELEM_UNREF(exec_ctx, rc->path);
+ GRPC_MDELEM_UNREF(exec_ctx, rc->authority);
gpr_free(rc);
}
- if (channel->default_authority != NULL) {
- GRPC_MDELEM_UNREF(channel->default_authority);
- }
+ GRPC_MDELEM_UNREF(exec_ctx, channel->default_authority);
gpr_mu_destroy(&channel->registered_call_mu);
gpr_free(channel->target);
gpr_free(channel);
@@ -362,7 +362,8 @@ grpc_compression_options grpc_channel_compression_options(
return channel->compression_options;
}
-grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) {
+grpc_mdelem grpc_channel_get_reffed_status_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel *channel, int i) {
char tmp[GPR_LTOA_MIN_BUFSIZE];
switch (i) {
case 0:
@@ -373,6 +374,6 @@ grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) {
return GRPC_MDELEM_GRPC_STATUS_2;
}
gpr_ltoa(i, tmp);
- return grpc_mdelem_from_metadata_strings(GRPC_MDSTR_GRPC_STATUS,
- grpc_mdstr_from_string(tmp));
+ return grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_STATUS,
+ grpc_slice_from_copied_string(tmp));
}
diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h
index 23cc8656ca..0ac04b6b58 100644
--- a/src/core/lib/surface/channel.h
+++ b/src/core/lib/surface/channel.h
@@ -51,9 +51,9 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
properties from the server call to this new client call, depending on the
value of \a propagation_mask (see propagation_bits.h for possible values) */
grpc_call *grpc_channel_create_pollset_set_call(
- grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
- grpc_pollset_set *pollset_set, const char *method, const char *host,
- gpr_timespec deadline, void *reserved);
+ grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
+ uint32_t propagation_mask, grpc_pollset_set *pollset_set, grpc_slice method,
+ const grpc_slice *host, gpr_timespec deadline, void *reserved);
/** Get a (borrowed) pointer to this channels underlying channel stack */
grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel);
@@ -62,7 +62,8 @@ grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel);
status_code.
The returned elem is owned by the caller. */
-grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel,
+grpc_mdelem grpc_channel_get_reffed_status_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel *channel,
int status_code);
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
diff --git a/src/core/lib/surface/channel_init.c b/src/core/lib/surface/channel_init.c
index 0627b34479..7acb444d9b 100644
--- a/src/core/lib/surface/channel_init.c
+++ b/src/core/lib/surface/channel_init.c
@@ -131,7 +131,7 @@ bool grpc_channel_init_create_stack(grpc_exec_ctx *exec_ctx,
for (size_t i = 0; i < g_slots[type].num_slots; i++) {
const stage_slot *slot = &g_slots[type].slots[i];
- if (!slot->fn(builder, slot->arg)) {
+ if (!slot->fn(exec_ctx, builder, slot->arg)) {
return false;
}
}
diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h
index b53f2aefb9..411f5eae18 100644
--- a/src/core/lib/surface/channel_init.h
+++ b/src/core/lib/surface/channel_init.h
@@ -51,7 +51,8 @@ extern "C" {
/// One stage of mutation: call functions against \a builder to influence the
/// finally constructed channel stack
-typedef bool (*grpc_channel_init_stage)(grpc_channel_stack_builder *builder,
+typedef bool (*grpc_channel_init_stage)(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder,
void *arg);
/// Global initialization of the system
diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c
index 7903f57a68..91b8f2b068 100644
--- a/src/core/lib/surface/init.c
+++ b/src/core/lib/surface/init.c
@@ -54,6 +54,7 @@
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/resource_quota.h"
#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/channel_init.h"
@@ -80,17 +81,20 @@ static void do_basic_init(void) {
g_initializations = 0;
}
-static bool append_filter(grpc_channel_stack_builder *builder, void *arg) {
+static bool append_filter(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder, void *arg) {
return grpc_channel_stack_builder_append_filter(
builder, (const grpc_channel_filter *)arg, NULL, NULL);
}
-static bool prepend_filter(grpc_channel_stack_builder *builder, void *arg) {
+static bool prepend_filter(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder, void *arg) {
return grpc_channel_stack_builder_prepend_filter(
builder, (const grpc_channel_filter *)arg, NULL, NULL);
}
-static bool maybe_add_http_filter(grpc_channel_stack_builder *builder,
+static bool maybe_add_http_filter(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder,
void *arg) {
grpc_transport *t = grpc_channel_stack_builder_get_transport(builder);
if (t && strstr(t->vtable->name, "http")) {
@@ -174,6 +178,7 @@ void grpc_init(void) {
gpr_mu_lock(&g_init_mu);
if (++g_initializations == 1) {
gpr_time_init();
+ grpc_slice_intern_init();
grpc_mdctx_global_init();
grpc_channel_init_init();
grpc_register_tracer("api", &grpc_api_trace);
@@ -221,11 +226,12 @@ void grpc_init(void) {
void grpc_shutdown(void) {
int i;
GRPC_API_TRACE("grpc_shutdown(void)", 0, ());
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_mu_lock(&g_init_mu);
if (--g_initializations == 0) {
- grpc_executor_shutdown();
+ grpc_executor_shutdown(&exec_ctx);
grpc_cq_global_shutdown();
- grpc_iomgr_shutdown();
+ grpc_iomgr_shutdown(&exec_ctx);
gpr_timers_global_destroy();
grpc_tracer_shutdown();
for (i = g_number_of_plugins; i >= 0; i--) {
@@ -233,9 +239,11 @@ void grpc_shutdown(void) {
g_all_of_the_plugins[i].destroy();
}
}
- grpc_mdctx_global_shutdown();
+ grpc_mdctx_global_shutdown(&exec_ctx);
+ grpc_slice_intern_shutdown();
}
gpr_mu_unlock(&g_init_mu);
+ grpc_exec_ctx_finish(&exec_ctx);
}
int grpc_is_initialized(void) {
diff --git a/src/core/lib/surface/init_secure.c b/src/core/lib/surface/init_secure.c
index 7ee7b51568..520a8aa84f 100644
--- a/src/core/lib/surface/init_secure.c
+++ b/src/core/lib/surface/init_secure.c
@@ -50,7 +50,7 @@ void grpc_security_pre_init(void) {
}
static bool maybe_prepend_client_auth_filter(
- grpc_channel_stack_builder *builder, void *arg) {
+ grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder, void *arg) {
const grpc_channel_args *args =
grpc_channel_stack_builder_get_channel_arguments(builder);
if (args) {
@@ -65,7 +65,7 @@ static bool maybe_prepend_client_auth_filter(
}
static bool maybe_prepend_server_auth_filter(
- grpc_channel_stack_builder *builder, void *arg) {
+ grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder, void *arg) {
const grpc_channel_args *args =
grpc_channel_stack_builder_get_channel_arguments(builder);
if (args) {
diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c
index d0df8e7e17..a43969be57 100644
--- a/src/core/lib/surface/lame_client.c
+++ b/src/core/lib/surface/lame_client.c
@@ -44,6 +44,7 @@
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/channel.h"
+#include "src/core/lib/transport/static_metadata.h"
typedef struct {
grpc_linked_mdelem status;
@@ -55,14 +56,17 @@ typedef struct {
const char *error_message;
} channel_data;
-static void fill_metadata(grpc_call_element *elem, grpc_metadata_batch *mdb) {
+static void fill_metadata(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+ grpc_metadata_batch *mdb) {
call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data;
char tmp[GPR_LTOA_MIN_BUFSIZE];
gpr_ltoa(chand->error_code, tmp);
- calld->status.md = grpc_mdelem_from_strings("grpc-status", tmp);
- calld->details.md =
- grpc_mdelem_from_strings("grpc-message", chand->error_message);
+ calld->status.md = grpc_mdelem_from_slices(
+ exec_ctx, GRPC_MDSTR_GRPC_STATUS, grpc_slice_from_copied_string(tmp));
+ calld->details.md = grpc_mdelem_from_slices(
+ exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
+ grpc_slice_from_copied_string(chand->error_message));
calld->status.prev = calld->details.next = NULL;
calld->status.next = &calld->details;
calld->details.prev = &calld->status;
@@ -76,9 +80,9 @@ static void lame_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
grpc_transport_stream_op *op) {
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
if (op->recv_initial_metadata != NULL) {
- fill_metadata(elem, op->recv_initial_metadata);
+ fill_metadata(exec_ctx, elem, op->recv_initial_metadata);
} else if (op->recv_trailing_metadata != NULL) {
- fill_metadata(elem, op->recv_trailing_metadata);
+ fill_metadata(exec_ctx, elem, op->recv_trailing_metadata);
}
grpc_transport_stream_op_finish_with_failure(
exec_ctx, op, GRPC_ERROR_CREATE("lame client channel"));
diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c
index fe73aa375c..b21e1d8113 100644
--- a/src/core/lib/surface/server.c
+++ b/src/core/lib/surface/server.c
@@ -45,6 +45,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/iomgr/iomgr.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/support/stack_lockfree.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/surface/api_trace.h"
@@ -97,8 +98,9 @@ typedef struct requested_call {
typedef struct channel_registered_method {
registered_method *server_registered_method;
uint32_t flags;
- grpc_mdstr *method;
- grpc_mdstr *host;
+ bool has_host;
+ grpc_slice method;
+ grpc_slice host;
} channel_registered_method;
struct channel_data {
@@ -143,8 +145,10 @@ struct call_data {
/** the current state of a call - see call_state */
call_state state;
- grpc_mdstr *path;
- grpc_mdstr *host;
+ bool path_set;
+ bool host_set;
+ grpc_slice path;
+ grpc_slice host;
gpr_timespec deadline;
grpc_completion_queue *cq_new;
@@ -271,7 +275,7 @@ struct shutdown_cleanup_args {
static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
struct shutdown_cleanup_args *a = arg;
- grpc_slice_unref(a->slice);
+ grpc_slice_unref_internal(exec_ctx, a->slice);
gpr_free(a);
}
@@ -379,7 +383,7 @@ static void server_ref(grpc_server *server) {
static void server_delete(grpc_exec_ctx *exec_ctx, grpc_server *server) {
registered_method *rm;
size_t i;
- grpc_channel_args_destroy(server->channel_args);
+ grpc_channel_args_destroy(exec_ctx, server->channel_args);
gpr_mu_destroy(&server->mu_global);
gpr_mu_destroy(&server->mu_call);
while ((rm = server->registered_methods) != NULL) {
@@ -459,17 +463,6 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand,
op);
}
-static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) {
- grpc_slice slice = value->slice;
- size_t len = GRPC_SLICE_LENGTH(slice);
-
- if (len + 1 > *capacity) {
- *capacity = GPR_MAX(len + 1, *capacity * 2);
- *dest = gpr_realloc(*dest, *capacity);
- }
- memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1);
-}
-
static void done_request_event(grpc_exec_ctx *exec_ctx, void *req,
grpc_cq_completion *c) {
requested_call *rc = req;
@@ -498,12 +491,10 @@ static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata);
switch (rc->type) {
case BATCH_CALL:
- GPR_ASSERT(calld->host != NULL);
- GPR_ASSERT(calld->path != NULL);
- cpstr(&rc->data.batch.details->host,
- &rc->data.batch.details->host_capacity, calld->host);
- cpstr(&rc->data.batch.details->method,
- &rc->data.batch.details->method_capacity, calld->path);
+ GPR_ASSERT(calld->host_set);
+ GPR_ASSERT(calld->path_set);
+ rc->data.batch.details->host = grpc_slice_ref_internal(calld->host);
+ rc->data.batch.details->method = grpc_slice_ref_internal(calld->path);
rc->data.batch.details->deadline = calld->deadline;
rc->data.batch.details->flags =
(calld->recv_idempotent_request
@@ -623,35 +614,39 @@ static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
uint32_t hash;
channel_registered_method *rm;
- if (chand->registered_methods && calld->path && calld->host) {
+ if (chand->registered_methods && calld->path_set && calld->host_set) {
/* TODO(ctiller): unify these two searches */
/* check for an exact match with host */
- hash = GRPC_MDSTR_KV_HASH(calld->host->hash, calld->path->hash);
+ hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(calld->host),
+ grpc_slice_hash(calld->path));
for (i = 0; i <= chand->registered_method_max_probes; i++) {
rm = &chand->registered_methods[(hash + i) %
chand->registered_method_slots];
if (!rm) break;
- if (rm->host != calld->host) continue;
- if (rm->method != calld->path) continue;
+ if (!rm->has_host) continue;
+ if (grpc_slice_cmp(rm->host, calld->host) != 0) continue;
+ if (grpc_slice_cmp(rm->method, calld->path) != 0) continue;
if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) &&
- !calld->recv_idempotent_request)
+ !calld->recv_idempotent_request) {
continue;
+ }
finish_start_new_rpc(exec_ctx, server, elem,
&rm->server_registered_method->request_matcher,
rm->server_registered_method->payload_handling);
return;
}
/* check for a wildcard method definition (no host set) */
- hash = GRPC_MDSTR_KV_HASH(0, calld->path->hash);
+ hash = GRPC_MDSTR_KV_HASH(0, grpc_slice_hash(calld->path));
for (i = 0; i <= chand->registered_method_max_probes; i++) {
rm = &chand->registered_methods[(hash + i) %
chand->registered_method_slots];
if (!rm) break;
- if (rm->host != NULL) continue;
- if (rm->method != calld->path) continue;
+ if (rm->has_host) continue;
+ if (grpc_slice_cmp(rm->method, calld->path) != 0) continue;
if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) &&
- !calld->recv_idempotent_request)
+ !calld->recv_idempotent_request) {
continue;
+ }
finish_start_new_rpc(exec_ctx, server, elem,
&rm->server_registered_method->request_matcher,
rm->server_registered_method->payload_handling);
@@ -740,19 +735,22 @@ static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
}
}
-static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
+static grpc_mdelem server_filter(grpc_exec_ctx *exec_ctx, void *user_data,
+ grpc_mdelem md) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
- if (md->key == GRPC_MDSTR_PATH) {
- if (calld->path == NULL) {
- calld->path = GRPC_MDSTR_REF(md->value);
+ if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_PATH) == 0) {
+ if (!calld->path_set) {
+ calld->path = grpc_slice_ref(GRPC_MDVALUE(md));
+ calld->path_set = true;
}
- return NULL;
- } else if (md->key == GRPC_MDSTR_AUTHORITY) {
- if (calld->host == NULL) {
- calld->host = GRPC_MDSTR_REF(md->value);
+ return GRPC_MDNULL;
+ } else if (grpc_slice_cmp(GRPC_MDKEY(md), GRPC_MDSTR_AUTHORITY) == 0) {
+ if (!calld->host_set) {
+ calld->host = grpc_slice_ref(GRPC_MDVALUE(md));
+ calld->host_set = true;
}
- return NULL;
+ return GRPC_MDNULL;
}
return md;
}
@@ -764,12 +762,13 @@ static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
gpr_timespec op_deadline;
GRPC_ERROR_REF(error);
- grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, elem);
+ grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata,
+ server_filter, elem);
op_deadline = calld->recv_initial_metadata->deadline;
if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) {
calld->deadline = op_deadline;
}
- if (calld->host && calld->path) {
+ if (calld->host_set && calld->path_set) {
/* do nothing */
} else {
GRPC_ERROR_UNREF(error);
@@ -838,7 +837,7 @@ static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd,
args.server_transport_data = transport_server_data;
args.send_deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
grpc_call *call;
- grpc_error *error = grpc_call_create(&args, &call);
+ grpc_error *error = grpc_call_create(exec_ctx, &args, &call);
grpc_call_element *elem =
grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
if (error != GRPC_ERROR_NONE) {
@@ -901,11 +900,11 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
GPR_ASSERT(calld->state != PENDING);
- if (calld->host) {
- GRPC_MDSTR_UNREF(calld->host);
+ if (calld->host_set) {
+ grpc_slice_unref_internal(exec_ctx, calld->host);
}
- if (calld->path) {
- GRPC_MDSTR_UNREF(calld->path);
+ if (calld->path_set) {
+ grpc_slice_unref_internal(exec_ctx, calld->path);
}
grpc_metadata_array_destroy(&calld->initial_metadata);
@@ -935,11 +934,9 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
channel_data *chand = elem->channel_data;
if (chand->registered_methods) {
for (i = 0; i < chand->registered_method_slots; i++) {
- if (chand->registered_methods[i].method) {
- GRPC_MDSTR_UNREF(chand->registered_methods[i].method);
- }
- if (chand->registered_methods[i].host) {
- GRPC_MDSTR_UNREF(chand->registered_methods[i].host);
+ grpc_slice_unref_internal(exec_ctx, chand->registered_methods[i].method);
+ if (chand->registered_methods[i].has_host) {
+ grpc_slice_unref_internal(exec_ctx, chand->registered_methods[i].host);
}
}
gpr_free(chand->registered_methods);
@@ -1137,8 +1134,6 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
channel_registered_method *crm;
grpc_channel *channel;
channel_data *chand;
- grpc_mdstr *host;
- grpc_mdstr *method;
uint32_t hash;
size_t slots;
uint32_t probes;
@@ -1177,9 +1172,18 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
chand->registered_methods = gpr_malloc(alloc);
memset(chand->registered_methods, 0, alloc);
for (rm = s->registered_methods; rm; rm = rm->next) {
- host = rm->host ? grpc_mdstr_from_string(rm->host) : NULL;
- method = grpc_mdstr_from_string(rm->method);
- hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
+ grpc_slice host;
+ bool has_host;
+ grpc_slice method;
+ if (rm->host != NULL) {
+ host = grpc_slice_intern(grpc_slice_from_copied_string(rm->host));
+ has_host = true;
+ } else {
+ has_host = false;
+ }
+ method = grpc_slice_intern(grpc_slice_from_copied_string(rm->method));
+ hash = GRPC_MDSTR_KV_HASH(has_host ? grpc_slice_hash(host) : 0,
+ grpc_slice_hash(method));
for (probes = 0; chand->registered_methods[(hash + probes) % slots]
.server_registered_method != NULL;
probes++)
diff --git a/src/core/lib/surface/validate_metadata.c b/src/core/lib/surface/validate_metadata.c
index 84f0a083bc..c9ff30bf8a 100644
--- a/src/core/lib/surface/validate_metadata.c
+++ b/src/core/lib/surface/validate_metadata.c
@@ -34,13 +34,14 @@
#include <stdlib.h>
#include <string.h>
+#include <grpc/grpc.h>
#include <grpc/support/port_platform.h>
-static int conforms_to(const char *s, size_t len, const uint8_t *legal_bits) {
- const char *p = s;
- const char *e = s + len;
+static int conforms_to(grpc_slice slice, const uint8_t *legal_bits) {
+ const uint8_t *p = GRPC_SLICE_START_PTR(slice);
+ const uint8_t *e = GRPC_SLICE_END_PTR(slice);
for (; p != e; p++) {
- int idx = (uint8_t)*p;
+ int idx = *p;
int byte = idx / 8;
int bit = idx % 8;
if ((legal_bits[byte] & (1 << bit)) == 0) return 0;
@@ -48,26 +49,23 @@ static int conforms_to(const char *s, size_t len, const uint8_t *legal_bits) {
return 1;
}
-int grpc_header_key_is_legal(const char *key, size_t length) {
+int grpc_header_key_is_legal(grpc_slice slice) {
static const uint8_t legal_header_bits[256 / 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0x00, 0x00, 0x00,
0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- if (length == 0) {
- return 0;
- }
- return conforms_to(key, length, legal_header_bits);
+ return GRPC_SLICE_LENGTH(slice) != 0 && conforms_to(slice, legal_header_bits);
}
-int grpc_header_nonbin_value_is_legal(const char *value, size_t length) {
+int grpc_header_nonbin_value_is_legal(grpc_slice slice) {
static const uint8_t legal_header_bits[256 / 8] = {
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- return conforms_to(value, length, legal_header_bits);
+ return conforms_to(slice, legal_header_bits);
}
-int grpc_is_binary_header(const char *key, size_t length) {
- if (length < 5) return 0;
- return 0 == memcmp(key + length - 4, "-bin", 4);
+int grpc_is_binary_header(grpc_slice slice) {
+ if (GRPC_SLICE_LENGTH(slice) < 5) return 0;
+ return 0 == memcmp(GRPC_SLICE_END_PTR(slice) - 4, "-bin", 4);
}
diff --git a/src/core/lib/transport/byte_stream.c b/src/core/lib/transport/byte_stream.c
index 2f1d7b7c60..4d4206189e 100644
--- a/src/core/lib/transport/byte_stream.c
+++ b/src/core/lib/transport/byte_stream.c
@@ -37,6 +37,8 @@
#include <grpc/support/log.h>
+#include "src/core/lib/slice/slice_internal.h"
+
int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx,
grpc_byte_stream *byte_stream, grpc_slice *slice,
size_t max_size_hint, grpc_closure *on_complete) {
@@ -57,7 +59,8 @@ static int slice_buffer_stream_next(grpc_exec_ctx *exec_ctx,
grpc_closure *on_complete) {
grpc_slice_buffer_stream *stream = (grpc_slice_buffer_stream *)byte_stream;
GPR_ASSERT(stream->cursor < stream->backing_buffer->count);
- *slice = grpc_slice_ref(stream->backing_buffer->slices[stream->cursor]);
+ *slice =
+ grpc_slice_ref_internal(stream->backing_buffer->slices[stream->cursor]);
stream->cursor++;
return 1;
}
diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c
index fac19b91d9..2082d1bac2 100644
--- a/src/core/lib/transport/metadata.c
+++ b/src/core/lib/transport/metadata.c
@@ -47,12 +47,11 @@
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/support/murmur_hash.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/transport/static_metadata.h"
-grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(grpc_slice input);
-
/* There are two kinds of mdelem and mdstr instances.
* Static instances are declared in static_metadata.{h,c} and
* are initialized by grpc_mdctx_global_init().
@@ -62,9 +61,6 @@ grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(grpc_slice input);
* used to determine which kind of element a pointer refers to.
*/
-#define INITIAL_STRTAB_CAPACITY 4
-#define INITIAL_MDTAB_CAPACITY 4
-
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
#define DEBUG_ARGS , const char *file, int line
#define FWD_DEBUG_ARGS , file, line
@@ -75,37 +71,20 @@ grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(grpc_slice input);
#define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s))
#endif
-#define TABLE_IDX(hash, log2_shards, capacity) \
- (((hash) >> (log2_shards)) % (capacity))
-#define SHARD_IDX(hash, log2_shards) ((hash) & ((1 << (log2_shards)) - 1))
-
-typedef void (*destroy_user_data_func)(void *user_data);
-
-#define SIZE_IN_DECODER_TABLE_NOT_SET -1
-/* Shadow structure for grpc_mdstr for non-static values */
-typedef struct internal_string {
- /* must be byte compatible with grpc_mdstr */
- grpc_slice slice;
- uint32_t hash;
-
- /* private only data */
- gpr_atm refcnt;
-
- uint8_t has_base64_and_huffman_encoded;
- grpc_slice_refcount refcount;
+#define INITIAL_SHARD_CAPACITY 8
+#define LOG2_SHARD_COUNT 4
+#define SHARD_COUNT ((size_t)(1 << LOG2_SHARD_COUNT))
- grpc_slice base64_and_huffman;
+#define TABLE_IDX(hash, capacity) (((hash) >> (LOG2_SHARD_COUNT)) % (capacity))
+#define SHARD_IDX(hash) ((hash) & ((1 << (LOG2_SHARD_COUNT)) - 1))
- gpr_atm size_in_decoder_table;
-
- struct internal_string *bucket_next;
-} internal_string;
+typedef void (*destroy_user_data_func)(void *user_data);
-/* Shadow structure for grpc_mdelem for non-static elements */
-typedef struct internal_metadata {
- /* must be byte compatible with grpc_mdelem */
- internal_string *key;
- internal_string *value;
+/* Shadow structure for grpc_mdelem_data for interned elements */
+typedef struct interned_metadata {
+ /* must be byte compatible with grpc_mdelem_data */
+ grpc_slice key;
+ grpc_slice value;
/* private only data */
gpr_atm refcnt;
@@ -114,19 +93,22 @@ typedef struct internal_metadata {
gpr_atm destroy_user_data;
gpr_atm user_data;
- struct internal_metadata *bucket_next;
-} internal_metadata;
+ struct interned_metadata *bucket_next;
+} interned_metadata;
-typedef struct strtab_shard {
- gpr_mu mu;
- internal_string **strs;
- size_t count;
- size_t capacity;
-} strtab_shard;
+/* Shadow structure for grpc_mdelem_data for allocated elements */
+typedef struct allocated_metadata {
+ /* must be byte compatible with grpc_mdelem_data */
+ grpc_slice key;
+ grpc_slice value;
+
+ /* private only data */
+ gpr_atm refcnt;
+} allocated_metadata;
typedef struct mdtab_shard {
gpr_mu mu;
- internal_metadata **elems;
+ interned_metadata **elems;
size_t count;
size_t capacity;
/** Estimate of the number of unreferenced mdelems in the hash table.
@@ -135,104 +117,28 @@ typedef struct mdtab_shard {
gpr_atm free_estimate;
} mdtab_shard;
-#define LOG2_STRTAB_SHARD_COUNT 5
-#define LOG2_MDTAB_SHARD_COUNT 4
-#define STRTAB_SHARD_COUNT ((size_t)(1 << LOG2_STRTAB_SHARD_COUNT))
-#define MDTAB_SHARD_COUNT ((size_t)(1 << LOG2_MDTAB_SHARD_COUNT))
-
-/* hash seed: decided at initialization time */
-static uint32_t g_hash_seed;
-static int g_forced_hash_seed = 0;
+static mdtab_shard g_shards[SHARD_COUNT];
-/* linearly probed hash tables for static element lookup */
-static grpc_mdstr *g_static_strtab[GRPC_STATIC_MDSTR_COUNT * 2];
-static grpc_mdelem *g_static_mdtab[GRPC_STATIC_MDELEM_COUNT * 2];
-static size_t g_static_strtab_maxprobe;
-static size_t g_static_mdtab_maxprobe;
-
-static strtab_shard g_strtab_shard[STRTAB_SHARD_COUNT];
-static mdtab_shard g_mdtab_shard[MDTAB_SHARD_COUNT];
-
-static void gc_mdtab(mdtab_shard *shard);
-
-void grpc_test_only_set_metadata_hash_seed(uint32_t seed) {
- g_hash_seed = seed;
- g_forced_hash_seed = 1;
-}
+static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard);
void grpc_mdctx_global_init(void) {
- size_t i, j;
- if (!g_forced_hash_seed) {
- g_hash_seed = (uint32_t)gpr_now(GPR_CLOCK_REALTIME).tv_nsec;
- }
- g_static_strtab_maxprobe = 0;
- g_static_mdtab_maxprobe = 0;
- /* build static tables */
- memset(g_static_mdtab, 0, sizeof(g_static_mdtab));
- memset(g_static_strtab, 0, sizeof(g_static_strtab));
- for (i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) {
- grpc_mdstr *elem = &grpc_static_mdstr_table[i];
- const char *str = grpc_static_metadata_strings[i];
- uint32_t hash = gpr_murmur_hash3(str, strlen(str), g_hash_seed);
- *(grpc_slice *)&elem->slice = grpc_slice_from_static_string(str);
- *(uint32_t *)&elem->hash = hash;
- for (j = 0;; j++) {
- size_t idx = (hash + j) % GPR_ARRAY_SIZE(g_static_strtab);
- if (g_static_strtab[idx] == NULL) {
- g_static_strtab[idx] = &grpc_static_mdstr_table[i];
- break;
- }
- }
- if (j > g_static_strtab_maxprobe) {
- g_static_strtab_maxprobe = j;
- }
- }
- for (i = 0; i < GRPC_STATIC_MDELEM_COUNT; i++) {
- grpc_mdelem *elem = &grpc_static_mdelem_table[i];
- grpc_mdstr *key =
- &grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 0]];
- grpc_mdstr *value =
- &grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 1]];
- uint32_t hash = GRPC_MDSTR_KV_HASH(key->hash, value->hash);
- *(grpc_mdstr **)&elem->key = key;
- *(grpc_mdstr **)&elem->value = value;
- for (j = 0;; j++) {
- size_t idx = (hash + j) % GPR_ARRAY_SIZE(g_static_mdtab);
- if (g_static_mdtab[idx] == NULL) {
- g_static_mdtab[idx] = elem;
- break;
- }
- }
- if (j > g_static_mdtab_maxprobe) {
- g_static_mdtab_maxprobe = j;
- }
- }
/* initialize shards */
- for (i = 0; i < STRTAB_SHARD_COUNT; i++) {
- strtab_shard *shard = &g_strtab_shard[i];
- gpr_mu_init(&shard->mu);
- shard->count = 0;
- shard->capacity = INITIAL_STRTAB_CAPACITY;
- shard->strs = gpr_malloc(sizeof(*shard->strs) * shard->capacity);
- memset(shard->strs, 0, sizeof(*shard->strs) * shard->capacity);
- }
- for (i = 0; i < MDTAB_SHARD_COUNT; i++) {
- mdtab_shard *shard = &g_mdtab_shard[i];
+ for (size_t i = 0; i < SHARD_COUNT; i++) {
+ mdtab_shard *shard = &g_shards[i];
gpr_mu_init(&shard->mu);
shard->count = 0;
gpr_atm_no_barrier_store(&shard->free_estimate, 0);
- shard->capacity = INITIAL_MDTAB_CAPACITY;
+ shard->capacity = INITIAL_SHARD_CAPACITY;
shard->elems = gpr_malloc(sizeof(*shard->elems) * shard->capacity);
memset(shard->elems, 0, sizeof(*shard->elems) * shard->capacity);
}
}
-void grpc_mdctx_global_shutdown(void) {
- size_t i;
- for (i = 0; i < MDTAB_SHARD_COUNT; i++) {
- mdtab_shard *shard = &g_mdtab_shard[i];
+void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx) {
+ for (size_t i = 0; i < SHARD_COUNT; i++) {
+ mdtab_shard *shard = &g_shards[i];
gpr_mu_destroy(&shard->mu);
- gc_mdtab(shard);
+ gc_mdtab(exec_ctx, shard);
/* TODO(ctiller): GPR_ASSERT(shard->count == 0); */
if (shard->count != 0) {
gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata elements were leaked",
@@ -243,211 +149,33 @@ void grpc_mdctx_global_shutdown(void) {
}
gpr_free(shard->elems);
}
- for (i = 0; i < STRTAB_SHARD_COUNT; i++) {
- strtab_shard *shard = &g_strtab_shard[i];
- gpr_mu_destroy(&shard->mu);
- /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */
- if (shard->count != 0) {
- gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata strings were leaked",
- shard->count);
- for (size_t j = 0; j < shard->capacity; j++) {
- for (internal_string *s = shard->strs[j]; s; s = s->bucket_next) {
- gpr_log(GPR_DEBUG, "LEAKED: %s",
- grpc_mdstr_as_c_string((grpc_mdstr *)s));
- }
- }
- if (grpc_iomgr_abort_on_leaks()) {
- abort();
- }
- }
- gpr_free(shard->strs);
- }
}
-static int is_mdstr_static(grpc_mdstr *s) {
- return s >= &grpc_static_mdstr_table[0] &&
- s < &grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
-}
-
-static int is_mdelem_static(grpc_mdelem *e) {
- return e >= &grpc_static_mdelem_table[0] &&
- e < &grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
+static int is_mdelem_static(grpc_mdelem e) {
+ return GRPC_MDELEM_DATA(e) >= &grpc_static_mdelem_table[0] &&
+ GRPC_MDELEM_DATA(e) <
+ &grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
}
static void ref_md_locked(mdtab_shard *shard,
- internal_metadata *md DEBUG_ARGS) {
+ interned_metadata *md DEBUG_ARGS) {
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"ELM REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
gpr_atm_no_barrier_load(&md->refcnt),
gpr_atm_no_barrier_load(&md->refcnt) + 1,
- grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
- grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
+ grpc_mdstr_as_c_string((grpc_slice)md->key),
+ grpc_mdstr_as_c_string((grpc_slice)md->value));
#endif
if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 1)) {
gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -1);
}
}
-static void grow_strtab(strtab_shard *shard) {
- size_t capacity = shard->capacity * 2;
- size_t i;
- internal_string **strtab;
- internal_string *s, *next;
-
- GPR_TIMER_BEGIN("grow_strtab", 0);
-
- strtab = gpr_malloc(sizeof(internal_string *) * capacity);
- memset(strtab, 0, sizeof(internal_string *) * capacity);
-
- for (i = 0; i < shard->capacity; i++) {
- for (s = shard->strs[i]; s; s = next) {
- size_t idx = TABLE_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT, capacity);
- next = s->bucket_next;
- s->bucket_next = strtab[idx];
- strtab[idx] = s;
- }
- }
-
- gpr_free(shard->strs);
- shard->strs = strtab;
- shard->capacity = capacity;
-
- GPR_TIMER_END("grow_strtab", 0);
-}
-
-static void internal_destroy_string(strtab_shard *shard, internal_string *is) {
- internal_string **prev_next;
- internal_string *cur;
- GPR_TIMER_BEGIN("internal_destroy_string", 0);
- if (is->has_base64_and_huffman_encoded) {
- grpc_slice_unref(is->base64_and_huffman);
- }
- for (prev_next = &shard->strs[TABLE_IDX(is->hash, LOG2_STRTAB_SHARD_COUNT,
- shard->capacity)],
- cur = *prev_next;
- cur != is; prev_next = &cur->bucket_next, cur = cur->bucket_next)
- ;
- *prev_next = cur->bucket_next;
- shard->count--;
- gpr_free(is);
- GPR_TIMER_END("internal_destroy_string", 0);
-}
-
-static void slice_ref(void *p) {
- internal_string *is =
- (internal_string *)((char *)p - offsetof(internal_string, refcount));
- GRPC_MDSTR_REF((grpc_mdstr *)(is));
-}
-
-static void slice_unref(void *p) {
- internal_string *is =
- (internal_string *)((char *)p - offsetof(internal_string, refcount));
- GRPC_MDSTR_UNREF((grpc_mdstr *)(is));
-}
-
-grpc_mdstr *grpc_mdstr_from_string(const char *str) {
- return grpc_mdstr_from_buffer((const uint8_t *)str, strlen(str));
-}
-
-grpc_mdstr *grpc_mdstr_from_slice(grpc_slice slice) {
- grpc_mdstr *result = grpc_mdstr_from_buffer(GRPC_SLICE_START_PTR(slice),
- GRPC_SLICE_LENGTH(slice));
- grpc_slice_unref(slice);
- return result;
-}
-
-grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *buf, size_t length) {
- uint32_t hash = gpr_murmur_hash3(buf, length, g_hash_seed);
- internal_string *s;
- strtab_shard *shard =
- &g_strtab_shard[SHARD_IDX(hash, LOG2_STRTAB_SHARD_COUNT)];
- size_t i;
- size_t idx;
-
- GPR_TIMER_BEGIN("grpc_mdstr_from_buffer", 0);
-
- /* search for a static string */
- for (i = 0; i <= g_static_strtab_maxprobe; i++) {
- grpc_mdstr *ss;
- idx = (hash + i) % GPR_ARRAY_SIZE(g_static_strtab);
- ss = g_static_strtab[idx];
- if (ss == NULL) break;
- if (ss->hash == hash && GRPC_SLICE_LENGTH(ss->slice) == length &&
- (length == 0 ||
- 0 == memcmp(buf, GRPC_SLICE_START_PTR(ss->slice), length))) {
- GPR_TIMER_END("grpc_mdstr_from_buffer", 0);
- return ss;
- }
- }
-
- gpr_mu_lock(&shard->mu);
-
- /* search for an existing string */
- idx = TABLE_IDX(hash, LOG2_STRTAB_SHARD_COUNT, shard->capacity);
- for (s = shard->strs[idx]; s; s = s->bucket_next) {
- if (s->hash == hash && GRPC_SLICE_LENGTH(s->slice) == length &&
- 0 == memcmp(buf, GRPC_SLICE_START_PTR(s->slice), length)) {
- if (gpr_atm_full_fetch_add(&s->refcnt, 1) == 0) {
- /* If we get here, we've added a ref to something that was about to
- * die - drop it immediately.
- * The *only* possible path here (given the shard mutex) should be to
- * drop from one ref back to zero - assert that with a CAS */
- GPR_ASSERT(gpr_atm_rel_cas(&s->refcnt, 1, 0));
- /* and treat this as if we were never here... sshhh */
- } else {
- gpr_mu_unlock(&shard->mu);
- GPR_TIMER_END("grpc_mdstr_from_buffer", 0);
- return (grpc_mdstr *)s;
- }
- }
- }
-
- /* not found: create a new string */
- if (length + 1 < GRPC_SLICE_INLINED_SIZE) {
- /* string data goes directly into the slice */
- s = gpr_malloc(sizeof(internal_string));
- gpr_atm_rel_store(&s->refcnt, 1);
- s->slice.refcount = NULL;
- memcpy(s->slice.data.inlined.bytes, buf, length);
- s->slice.data.inlined.bytes[length] = 0;
- s->slice.data.inlined.length = (uint8_t)length;
- } else {
- /* string data goes after the internal_string header, and we +1 for null
- terminator */
- s = gpr_malloc(sizeof(internal_string) + length + 1);
- gpr_atm_rel_store(&s->refcnt, 1);
- s->refcount.ref = slice_ref;
- s->refcount.unref = slice_unref;
- s->slice.refcount = &s->refcount;
- s->slice.data.refcounted.bytes = (uint8_t *)(s + 1);
- s->slice.data.refcounted.length = length;
- memcpy(s->slice.data.refcounted.bytes, buf, length);
- /* add a null terminator for cheap c string conversion when desired */
- s->slice.data.refcounted.bytes[length] = 0;
- }
- s->has_base64_and_huffman_encoded = 0;
- s->hash = hash;
- s->size_in_decoder_table = SIZE_IN_DECODER_TABLE_NOT_SET;
- s->bucket_next = shard->strs[idx];
- shard->strs[idx] = s;
-
- shard->count++;
-
- if (shard->count > shard->capacity * 2) {
- grow_strtab(shard);
- }
-
- gpr_mu_unlock(&shard->mu);
- GPR_TIMER_END("grpc_mdstr_from_buffer", 0);
-
- return (grpc_mdstr *)s;
-}
-
-static void gc_mdtab(mdtab_shard *shard) {
+static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) {
size_t i;
- internal_metadata **prev_next;
- internal_metadata *md, *next;
+ interned_metadata **prev_next;
+ interned_metadata *md, *next;
gpr_atm num_freed = 0;
GPR_TIMER_BEGIN("gc_mdtab", 0);
@@ -457,8 +185,8 @@ static void gc_mdtab(mdtab_shard *shard) {
void *user_data = (void *)gpr_atm_no_barrier_load(&md->user_data);
next = md->bucket_next;
if (gpr_atm_acq_load(&md->refcnt) == 0) {
- GRPC_MDSTR_UNREF((grpc_mdstr *)md->key);
- GRPC_MDSTR_UNREF((grpc_mdstr *)md->value);
+ grpc_slice_unref_internal(exec_ctx, md->key);
+ grpc_slice_unref_internal(exec_ctx, md->value);
if (md->user_data) {
((destroy_user_data_func)gpr_atm_no_barrier_load(
&md->destroy_user_data))(user_data);
@@ -479,21 +207,22 @@ static void gc_mdtab(mdtab_shard *shard) {
static void grow_mdtab(mdtab_shard *shard) {
size_t capacity = shard->capacity * 2;
size_t i;
- internal_metadata **mdtab;
- internal_metadata *md, *next;
+ interned_metadata **mdtab;
+ interned_metadata *md, *next;
uint32_t hash;
GPR_TIMER_BEGIN("grow_mdtab", 0);
- mdtab = gpr_malloc(sizeof(internal_metadata *) * capacity);
- memset(mdtab, 0, sizeof(internal_metadata *) * capacity);
+ mdtab = gpr_malloc(sizeof(interned_metadata *) * capacity);
+ memset(mdtab, 0, sizeof(interned_metadata *) * capacity);
for (i = 0; i < shard->capacity; i++) {
for (md = shard->elems[i]; md; md = next) {
size_t idx;
- hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash);
+ hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(md->key),
+ grpc_slice_hash(md->value));
next = md->bucket_next;
- idx = TABLE_IDX(hash, LOG2_MDTAB_SHARD_COUNT, capacity);
+ idx = TABLE_IDX(hash, capacity);
md->bucket_next = mdtab[idx];
mdtab[idx] = md;
}
@@ -506,60 +235,64 @@ static void grow_mdtab(mdtab_shard *shard) {
GPR_TIMER_END("grow_mdtab", 0);
}
-static void rehash_mdtab(mdtab_shard *shard) {
+static void rehash_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) {
if (gpr_atm_no_barrier_load(&shard->free_estimate) >
(gpr_atm)(shard->capacity / 4)) {
- gc_mdtab(shard);
+ gc_mdtab(exec_ctx, shard);
} else {
grow_mdtab(shard);
}
}
-grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *mkey,
- grpc_mdstr *mvalue) {
- internal_string *key = (internal_string *)mkey;
- internal_string *value = (internal_string *)mvalue;
- uint32_t hash = GRPC_MDSTR_KV_HASH(mkey->hash, mvalue->hash);
- internal_metadata *md;
- mdtab_shard *shard = &g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)];
- size_t i;
- size_t idx;
+grpc_mdelem grpc_mdelem_create(
+ grpc_exec_ctx *exec_ctx, grpc_slice key, grpc_slice value,
+ grpc_mdelem_data *compatible_external_backing_store) {
+ if (!grpc_slice_is_interned(key) || !grpc_slice_is_interned(value)) {
+ if (compatible_external_backing_store != NULL) {
+ return GRPC_MAKE_MDELEM(compatible_external_backing_store,
+ GRPC_MDELEM_STORAGE_EXTERNAL);
+ }
- GPR_TIMER_BEGIN("grpc_mdelem_from_metadata_strings", 0);
+ allocated_metadata *allocated = gpr_malloc(sizeof(*allocated));
+ allocated->key = grpc_slice_ref_internal(key);
+ allocated->value = grpc_slice_ref_internal(value);
+ gpr_atm_rel_store(&allocated->refcnt, 1);
+ return GRPC_MAKE_MDELEM(allocated, GRPC_MDELEM_STORAGE_ALLOCATED);
+ }
- if (is_mdstr_static(mkey) && is_mdstr_static(mvalue)) {
- for (i = 0; i <= g_static_mdtab_maxprobe; i++) {
- grpc_mdelem *smd;
- idx = (hash + i) % GPR_ARRAY_SIZE(g_static_mdtab);
- smd = g_static_mdtab[idx];
- if (smd == NULL) break;
- if (smd->key == mkey && smd->value == mvalue) {
- GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0);
- return smd;
- }
- }
+ grpc_mdelem static_elem = grpc_static_mdelem_for_static_strings(
+ grpc_static_metadata_index(key), grpc_static_metadata_index(value));
+ if (!GRPC_MDISNULL(static_elem)) {
+ return static_elem;
}
+ uint32_t hash =
+ GRPC_MDSTR_KV_HASH(grpc_slice_hash(key), grpc_slice_hash(value));
+ interned_metadata *md;
+ mdtab_shard *shard = &g_shards[SHARD_IDX(hash)];
+ size_t idx;
+
+ GPR_TIMER_BEGIN("grpc_mdelem_from_metadata_strings", 0);
+
gpr_mu_lock(&shard->mu);
- idx = TABLE_IDX(hash, LOG2_MDTAB_SHARD_COUNT, shard->capacity);
+ idx = TABLE_IDX(hash, shard->capacity);
/* search for an existing pair */
for (md = shard->elems[idx]; md; md = md->bucket_next) {
- if (md->key == key && md->value == value) {
+ if (grpc_slice_cmp(key, md->key) == 0 &&
+ grpc_slice_cmp(value, md->value) == 0) {
REF_MD_LOCKED(shard, md);
- GRPC_MDSTR_UNREF((grpc_mdstr *)key);
- GRPC_MDSTR_UNREF((grpc_mdstr *)value);
gpr_mu_unlock(&shard->mu);
GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0);
- return (grpc_mdelem *)md;
+ return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED);
}
}
/* not found: create a new pair */
- md = gpr_malloc(sizeof(internal_metadata));
+ md = gpr_malloc(sizeof(interned_metadata));
gpr_atm_rel_store(&md->refcnt, 1);
- md->key = key;
- md->value = value;
+ md->key = grpc_slice_ref_internal(key);
+ md->value = grpc_slice_ref_internal(value);
md->user_data = 0;
md->destroy_user_data = 0;
md->bucket_next = shard->elems[idx];
@@ -568,37 +301,34 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *mkey,
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
gpr_log(GPR_DEBUG, "ELM NEW:%p:%zu: '%s' = '%s'", (void *)md,
gpr_atm_no_barrier_load(&md->refcnt),
- grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
- grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
+ grpc_mdstr_as_c_string((grpc_slice)md->key),
+ grpc_mdstr_as_c_string((grpc_slice)md->value));
#endif
shard->count++;
if (shard->count > shard->capacity * 2) {
- rehash_mdtab(shard);
+ rehash_mdtab(exec_ctx, shard);
}
gpr_mu_unlock(&shard->mu);
GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0);
- return (grpc_mdelem *)md;
-}
-
-grpc_mdelem *grpc_mdelem_from_strings(const char *key, const char *value) {
- return grpc_mdelem_from_metadata_strings(grpc_mdstr_from_string(key),
- grpc_mdstr_from_string(value));
+ return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED);
}
-grpc_mdelem *grpc_mdelem_from_slices(grpc_slice key, grpc_slice value) {
- return grpc_mdelem_from_metadata_strings(grpc_mdstr_from_slice(key),
- grpc_mdstr_from_slice(value));
+grpc_mdelem grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key,
+ grpc_slice value) {
+ grpc_mdelem out = grpc_mdelem_create(exec_ctx, key, value, NULL);
+ grpc_slice_unref_internal(exec_ctx, key);
+ grpc_slice_unref_internal(exec_ctx, value);
+ return out;
}
-grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key,
- const uint8_t *value,
- size_t value_length) {
- return grpc_mdelem_from_metadata_strings(
- grpc_mdstr_from_string(key), grpc_mdstr_from_buffer(value, value_length));
+grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_exec_ctx *exec_ctx,
+ grpc_metadata *metadata) {
+ return grpc_mdelem_create(exec_ctx, metadata->key, metadata->value,
+ (grpc_mdelem_data *)metadata);
}
static size_t get_base64_encoded_size(size_t raw_length) {
@@ -606,160 +336,167 @@ static size_t get_base64_encoded_size(size_t raw_length) {
return raw_length / 3 * 4 + tail_xtra[raw_length % 3];
}
-size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem *elem) {
- size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(elem->key->slice);
- size_t value_len = GRPC_SLICE_LENGTH(elem->value->slice);
- if (is_mdstr_static(elem->value)) {
- if (grpc_is_binary_header(
- (const char *)GRPC_SLICE_START_PTR(elem->key->slice),
- GRPC_SLICE_LENGTH(elem->key->slice))) {
- return overhead_and_key + get_base64_encoded_size(value_len);
- } else {
- return overhead_and_key + value_len;
- }
+size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem) {
+ size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
+ size_t value_len = GRPC_SLICE_LENGTH(GRPC_MDVALUE(elem));
+ if (grpc_is_binary_header(GRPC_MDKEY(elem))) {
+ return overhead_and_key + get_base64_encoded_size(value_len);
} else {
- internal_string *is = (internal_string *)elem->value;
- gpr_atm current_size = gpr_atm_acq_load(&is->size_in_decoder_table);
- if (current_size == SIZE_IN_DECODER_TABLE_NOT_SET) {
- if (grpc_is_binary_header(
- (const char *)GRPC_SLICE_START_PTR(elem->key->slice),
- GRPC_SLICE_LENGTH(elem->key->slice))) {
- current_size = (gpr_atm)get_base64_encoded_size(value_len);
- } else {
- current_size = (gpr_atm)value_len;
- }
- gpr_atm_rel_store(&is->size_in_decoder_table, current_size);
- }
- return overhead_and_key + (size_t)current_size;
+ return overhead_and_key + value_len;
}
}
-grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *gmd DEBUG_ARGS) {
- internal_metadata *md = (internal_metadata *)gmd;
- if (is_mdelem_static(gmd)) return gmd;
+grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd DEBUG_ARGS) {
+ switch (GRPC_MDELEM_STORAGE(gmd)) {
+ case GRPC_MDELEM_STORAGE_EXTERNAL:
+ case GRPC_MDELEM_STORAGE_STATIC:
+ break;
+ case GRPC_MDELEM_STORAGE_INTERNED: {
+ interned_metadata *md = (interned_metadata *)GRPC_MDELEM_DATA(gmd);
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
- "ELM REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
- gpr_atm_no_barrier_load(&md->refcnt),
- gpr_atm_no_barrier_load(&md->refcnt) + 1,
- grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
- grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
+ "ELM REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
+ gpr_atm_no_barrier_load(&md->refcnt),
+ gpr_atm_no_barrier_load(&md->refcnt) + 1,
+ grpc_mdstr_as_c_string((grpc_slice)md->key),
+ grpc_mdstr_as_c_string((grpc_slice)md->value));
#endif
- /* we can assume the ref count is >= 1 as the application is calling
- this function - meaning that no adjustment to mdtab_free is necessary,
- simplifying the logic here to be just an atomic increment */
- /* use C assert to have this removed in opt builds */
- GPR_ASSERT(gpr_atm_no_barrier_load(&md->refcnt) >= 1);
- gpr_atm_no_barrier_fetch_add(&md->refcnt, 1);
- return gmd;
-}
-
-void grpc_mdelem_unref(grpc_mdelem *gmd DEBUG_ARGS) {
- internal_metadata *md = (internal_metadata *)gmd;
- if (!md) return;
- if (is_mdelem_static(gmd)) return;
+ /* we can assume the ref count is >= 1 as the application is calling
+ this function - meaning that no adjustment to mdtab_free is necessary,
+ simplifying the logic here to be just an atomic increment */
+ /* use C assert to have this removed in opt builds */
+ GPR_ASSERT(gpr_atm_no_barrier_load(&md->refcnt) >= 1);
+ gpr_atm_no_barrier_fetch_add(&md->refcnt, 1);
+ break;
+ }
+ case GRPC_MDELEM_STORAGE_ALLOCATED: {
+ allocated_metadata *md = (allocated_metadata *)GRPC_MDELEM_DATA(gmd);
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
- "ELM UNREF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
- gpr_atm_no_barrier_load(&md->refcnt),
- gpr_atm_no_barrier_load(&md->refcnt) - 1,
- grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
- grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
+ "ELM REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
+ gpr_atm_no_barrier_load(&md->refcnt),
+ gpr_atm_no_barrier_load(&md->refcnt) + 1,
+ grpc_mdstr_as_c_string((grpc_slice)md->key),
+ grpc_mdstr_as_c_string((grpc_slice)md->value));
#endif
- uint32_t hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash);
- const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1);
- GPR_ASSERT(prev_refcount >= 1);
- if (1 == prev_refcount) {
- /* once the refcount hits zero, some other thread can come along and
- free md at any time: it's unsafe from this point on to access it */
- mdtab_shard *shard =
- &g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)];
- gpr_atm_no_barrier_fetch_add(&shard->free_estimate, 1);
+ /* we can assume the ref count is >= 1 as the application is calling
+ this function - meaning that no adjustment to mdtab_free is necessary,
+ simplifying the logic here to be just an atomic increment */
+ /* use C assert to have this removed in opt builds */
+ gpr_atm_no_barrier_fetch_add(&md->refcnt, 1);
+ break;
+ }
}
+ return gmd;
}
-const char *grpc_mdstr_as_c_string(const grpc_mdstr *s) {
- return (const char *)GRPC_SLICE_START_PTR(s->slice);
-}
-
-size_t grpc_mdstr_length(const grpc_mdstr *s) { return GRPC_MDSTR_LENGTH(s); }
-
-grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *gs DEBUG_ARGS) {
- internal_string *s = (internal_string *)gs;
- if (is_mdstr_static(gs)) return gs;
+void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem gmd DEBUG_ARGS) {
+ switch (GRPC_MDELEM_STORAGE(gmd)) {
+ case GRPC_MDELEM_STORAGE_EXTERNAL:
+ case GRPC_MDELEM_STORAGE_STATIC:
+ break;
+ case GRPC_MDELEM_STORAGE_INTERNED: {
+ interned_metadata *md = (interned_metadata *)GRPC_MDELEM_DATA(gmd);
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "STR REF:%p:%zu->%zu: '%s'",
- (void *)s, gpr_atm_no_barrier_load(&s->refcnt),
- gpr_atm_no_barrier_load(&s->refcnt) + 1, grpc_mdstr_as_c_string(gs));
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
+ "ELM UNREF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
+ gpr_atm_no_barrier_load(&md->refcnt),
+ gpr_atm_no_barrier_load(&md->refcnt) - 1,
+ grpc_mdstr_as_c_string((grpc_slice)md->key),
+ grpc_mdstr_as_c_string((grpc_slice)md->value));
#endif
- GPR_ASSERT(gpr_atm_full_fetch_add(&s->refcnt, 1) > 0);
- return gs;
-}
-
-void grpc_mdstr_unref(grpc_mdstr *gs DEBUG_ARGS) {
- internal_string *s = (internal_string *)gs;
- if (is_mdstr_static(gs)) return;
+ uint32_t hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(md->key),
+ grpc_slice_hash(md->value));
+ const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1);
+ GPR_ASSERT(prev_refcount >= 1);
+ if (1 == prev_refcount) {
+ /* once the refcount hits zero, some other thread can come along and
+ free md at any time: it's unsafe from this point on to access it */
+ mdtab_shard *shard = &g_shards[SHARD_IDX(hash)];
+ gpr_atm_no_barrier_fetch_add(&shard->free_estimate, 1);
+ }
+ break;
+ }
+ case GRPC_MDELEM_STORAGE_ALLOCATED: {
+ allocated_metadata *md = (allocated_metadata *)GRPC_MDELEM_DATA(gmd);
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "STR UNREF:%p:%zu->%zu: '%s'",
- (void *)s, gpr_atm_no_barrier_load(&s->refcnt),
- gpr_atm_no_barrier_load(&s->refcnt) - 1, grpc_mdstr_as_c_string(gs));
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
+ "ELM UNREF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
+ gpr_atm_no_barrier_load(&md->refcnt),
+ gpr_atm_no_barrier_load(&md->refcnt) - 1,
+ grpc_mdstr_as_c_string((grpc_slice)md->key),
+ grpc_mdstr_as_c_string((grpc_slice)md->value));
#endif
- if (1 == gpr_atm_full_fetch_add(&s->refcnt, -1)) {
- strtab_shard *shard =
- &g_strtab_shard[SHARD_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT)];
- gpr_mu_lock(&shard->mu);
- GPR_ASSERT(0 == gpr_atm_no_barrier_load(&s->refcnt));
- internal_destroy_string(shard, s);
- gpr_mu_unlock(&shard->mu);
+ const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1);
+ GPR_ASSERT(prev_refcount >= 1);
+ if (1 == prev_refcount) {
+ grpc_slice_unref_internal(exec_ctx, md->key);
+ grpc_slice_unref_internal(exec_ctx, md->value);
+ gpr_free(md);
+ }
+ break;
+ }
}
}
-void *grpc_mdelem_get_user_data(grpc_mdelem *md, void (*destroy_func)(void *)) {
- internal_metadata *im = (internal_metadata *)md;
- void *result;
- if (is_mdelem_static(md)) {
- return (void *)grpc_static_mdelem_user_data[md - grpc_static_mdelem_table];
- }
- if (gpr_atm_acq_load(&im->destroy_user_data) == (gpr_atm)destroy_func) {
- return (void *)gpr_atm_no_barrier_load(&im->user_data);
- } else {
- return NULL;
+void *grpc_mdelem_get_user_data(grpc_mdelem md, void (*destroy_func)(void *)) {
+ switch (GRPC_MDELEM_STORAGE(md)) {
+ case GRPC_MDELEM_STORAGE_EXTERNAL:
+ case GRPC_MDELEM_STORAGE_ALLOCATED:
+ return NULL;
+ case GRPC_MDELEM_STORAGE_STATIC:
+ return (void *)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) -
+ grpc_static_mdelem_table];
+ case GRPC_MDELEM_STORAGE_INTERNED: {
+ interned_metadata *im = (interned_metadata *)GRPC_MDELEM_DATA(md);
+ void *result;
+ if (gpr_atm_acq_load(&im->destroy_user_data) == (gpr_atm)destroy_func) {
+ return (void *)gpr_atm_no_barrier_load(&im->user_data);
+ } else {
+ return NULL;
+ }
+ return result;
+ }
}
- return result;
+ GPR_UNREACHABLE_CODE(return NULL);
}
-void *grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
+void *grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void *),
void *user_data) {
- internal_metadata *im = (internal_metadata *)md;
- GPR_ASSERT(!is_mdelem_static(md));
- GPR_ASSERT((user_data == NULL) == (destroy_func == NULL));
- gpr_mu_lock(&im->mu_user_data);
- if (gpr_atm_no_barrier_load(&im->destroy_user_data)) {
- /* user data can only be set once */
- gpr_mu_unlock(&im->mu_user_data);
- if (destroy_func != NULL) {
+ switch (GRPC_MDELEM_STORAGE(md)) {
+ case GRPC_MDELEM_STORAGE_EXTERNAL:
+ case GRPC_MDELEM_STORAGE_ALLOCATED:
destroy_func(user_data);
+ return NULL;
+ case GRPC_MDELEM_STORAGE_STATIC:
+ destroy_func(user_data);
+ return (void *)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) -
+ grpc_static_mdelem_table];
+ case GRPC_MDELEM_STORAGE_INTERNED: {
+ interned_metadata *im = (interned_metadata *)GRPC_MDELEM_DATA(md);
+ GPR_ASSERT(!is_mdelem_static(md));
+ GPR_ASSERT((user_data == NULL) == (destroy_func == NULL));
+ gpr_mu_lock(&im->mu_user_data);
+ if (gpr_atm_no_barrier_load(&im->destroy_user_data)) {
+ /* user data can only be set once */
+ gpr_mu_unlock(&im->mu_user_data);
+ if (destroy_func != NULL) {
+ destroy_func(user_data);
+ }
+ return (void *)gpr_atm_no_barrier_load(&im->user_data);
+ }
+ gpr_atm_no_barrier_store(&im->user_data, (gpr_atm)user_data);
+ gpr_atm_rel_store(&im->destroy_user_data, (gpr_atm)destroy_func);
+ gpr_mu_unlock(&im->mu_user_data);
+ return user_data;
}
- return (void *)gpr_atm_no_barrier_load(&im->user_data);
}
- gpr_atm_no_barrier_store(&im->user_data, (gpr_atm)user_data);
- gpr_atm_rel_store(&im->destroy_user_data, (gpr_atm)destroy_func);
- gpr_mu_unlock(&im->mu_user_data);
- return user_data;
+ GPR_UNREACHABLE_CODE(return NULL);
}
-grpc_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *gs) {
- internal_string *s = (internal_string *)gs;
- grpc_slice slice;
- strtab_shard *shard =
- &g_strtab_shard[SHARD_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT)];
- gpr_mu_lock(&shard->mu);
- if (!s->has_base64_and_huffman_encoded) {
- s->base64_and_huffman =
- grpc_chttp2_base64_encode_and_huffman_compress(s->slice);
- s->has_base64_and_huffman_encoded = 1;
- }
- slice = s->base64_and_huffman;
- gpr_mu_unlock(&shard->mu);
- return slice;
+bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b) {
+ if (a.payload == b.payload) return true;
+ if (GRPC_MDISNULL(a) || GRPC_MDISNULL(b)) return false;
+ return 0 == grpc_slice_cmp(GRPC_MDKEY(a), GRPC_MDKEY(b)) &&
+ 0 == grpc_slice_cmp(GRPC_MDVALUE(a), GRPC_MDVALUE(b));
}
diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h
index a4955a1ea7..6d0afbe789 100644
--- a/src/core/lib/transport/metadata.h
+++ b/src/core/lib/transport/metadata.h
@@ -34,9 +34,12 @@
#ifndef GRPC_CORE_LIB_TRANSPORT_METADATA_H
#define GRPC_CORE_LIB_TRANSPORT_METADATA_H
+#include <grpc/grpc.h>
#include <grpc/slice.h>
#include <grpc/support/useful.h>
+#include "src/core/lib/iomgr/exec_ctx.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -72,101 +75,102 @@ extern "C" {
declared here - in which case those functions are effectively no-ops. */
/* Forward declarations */
-typedef struct grpc_mdstr grpc_mdstr;
typedef struct grpc_mdelem grpc_mdelem;
-/* if changing this, make identical changes in internal_string in metadata.c */
-struct grpc_mdstr {
- const grpc_slice slice;
- const uint32_t hash;
+/* if changing this, make identical changes in:
+ - interned_metadata, allocated_metadata in metadata.c
+ - grpc_metadata in grpc_types.h */
+typedef struct grpc_mdelem_data {
+ const grpc_slice key;
+ const grpc_slice value;
/* there is a private part to this in metadata.c */
-};
+} grpc_mdelem_data;
+
+typedef enum {
+ /* memory pointed to by grpc_mdelem::payload is owned by an external system */
+ GRPC_MDELEM_STORAGE_EXTERNAL = 0,
+ /* memory pointed to by grpc_mdelem::payload is interned by the metadata
+ system */
+ GRPC_MDELEM_STORAGE_INTERNED = 1,
+ /* memory pointed to by grpc_mdelem::payload is allocated by the metadata
+ system */
+ GRPC_MDELEM_STORAGE_ALLOCATED = 2,
+ /* memory is in the static metadata table */
+ GRPC_MDELEM_STORAGE_STATIC = 3,
+} grpc_mdelem_data_storage;
-/* if changing this, make identical changes in internal_metadata in
- metadata.c */
struct grpc_mdelem {
- grpc_mdstr *const key;
- grpc_mdstr *const value;
- /* there is a private part to this in metadata.c */
+ /* a grpc_mdelem_data* generally, with the two lower bits signalling memory
+ ownership as per grpc_mdelem_data_storage */
+ uintptr_t payload;
};
-void grpc_test_only_set_metadata_hash_seed(uint32_t seed);
+#define GRPC_MDELEM_DATA(md) \
+ ((grpc_mdelem_data *)((md).payload & ~(uintptr_t)3))
+#define GRPC_MDELEM_STORAGE(md) \
+ ((grpc_mdelem_data_storage)((md).payload & (uintptr_t)3))
+#define GRPC_MAKE_MDELEM(data, storage) \
+ ((grpc_mdelem){((uintptr_t)(data)) | ((uintptr_t)storage)})
+
+/* Unrefs the slices. */
+grpc_mdelem grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key,
+ grpc_slice value);
-/* Constructors for grpc_mdstr instances; take a variety of data types that
- clients may have handy */
-grpc_mdstr *grpc_mdstr_from_string(const char *str);
-/* Unrefs the slice. */
-grpc_mdstr *grpc_mdstr_from_slice(grpc_slice slice);
-grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *str, size_t length);
+/* Cheaply convert a grpc_metadata to a grpc_mdelem; may use the grpc_metadata
+ object as backing storage (so lifetimes should align) */
+grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_exec_ctx *exec_ctx,
+ grpc_metadata *metadata);
-/* Returns a borrowed slice from the mdstr with its contents base64 encoded
- and huffman compressed */
-grpc_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *str);
+/* Does not unref the slices; if a new non-interned mdelem is needed, allocates
+ one if compatible_external_backing_store is NULL, or uses
+ compatible_external_backing_store if it is non-NULL (in which case it's the
+ users responsibility to ensure that it outlives usage) */
+grpc_mdelem grpc_mdelem_create(
+ grpc_exec_ctx *exec_ctx, grpc_slice key, grpc_slice value,
+ grpc_mdelem_data *compatible_external_backing_store);
-/* Constructors for grpc_mdelem instances; take a variety of data types that
- clients may have handy */
-grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *key,
- grpc_mdstr *value);
-grpc_mdelem *grpc_mdelem_from_strings(const char *key, const char *value);
-/* Unrefs the slices. */
-grpc_mdelem *grpc_mdelem_from_slices(grpc_slice key, grpc_slice value);
-grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key,
- const uint8_t *value,
- size_t value_length);
+bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b);
-size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem *elem);
+size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem);
/* Mutator and accessor for grpc_mdelem user data. The destructor function
is used as a type tag and is checked during user_data fetch. */
-void *grpc_mdelem_get_user_data(grpc_mdelem *md,
+void *grpc_mdelem_get_user_data(grpc_mdelem md,
void (*if_destroy_func)(void *));
-void *grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
+void *grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void *),
void *user_data);
/* Reference counting */
//#define GRPC_METADATA_REFCOUNT_DEBUG
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
-#define GRPC_MDSTR_REF(s) grpc_mdstr_ref((s), __FILE__, __LINE__)
-#define GRPC_MDSTR_UNREF(s) grpc_mdstr_unref((s), __FILE__, __LINE__)
#define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s), __FILE__, __LINE__)
-#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s), __FILE__, __LINE__)
-grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *s, const char *file, int line);
-void grpc_mdstr_unref(grpc_mdstr *s, const char *file, int line);
-grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md, const char *file, int line);
-void grpc_mdelem_unref(grpc_mdelem *md, const char *file, int line);
+#define GRPC_MDELEM_UNREF(exec_ctx, s) \
+ grpc_mdelem_unref((exec_ctx), (s), __FILE__, __LINE__)
+grpc_mdelem grpc_mdelem_ref(grpc_mdelem md, const char *file, int line);
+void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem md,
+ const char *file, int line);
#else
-#define GRPC_MDSTR_REF(s) grpc_mdstr_ref((s))
-#define GRPC_MDSTR_UNREF(s) grpc_mdstr_unref((s))
#define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s))
-#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s))
-grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *s);
-void grpc_mdstr_unref(grpc_mdstr *s);
-grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md);
-void grpc_mdelem_unref(grpc_mdelem *md);
+#define GRPC_MDELEM_UNREF(exec_ctx, s) grpc_mdelem_unref((exec_ctx), (s))
+grpc_mdelem grpc_mdelem_ref(grpc_mdelem md);
+void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem md);
#endif
-/* Recover a char* from a grpc_mdstr. The returned string is null terminated.
- Does not promise that the returned string has no embedded nulls however. */
-const char *grpc_mdstr_as_c_string(const grpc_mdstr *s);
+#define GRPC_MDKEY(md) (GRPC_MDELEM_DATA(md)->key)
+#define GRPC_MDVALUE(md) (GRPC_MDELEM_DATA(md)->value)
-#define GRPC_MDSTR_LENGTH(s) (GRPC_SLICE_LENGTH(s->slice))
+#define GRPC_MDNULL GRPC_MAKE_MDELEM(NULL, GRPC_MDELEM_STORAGE_EXTERNAL)
+#define GRPC_MDISNULL(md) (GRPC_MDELEM_DATA(md) == NULL)
/* We add 32 bytes of padding as per RFC-7540 section 6.5.2. */
-#define GRPC_MDELEM_LENGTH(e) \
- (GRPC_MDSTR_LENGTH((e)->key) + GRPC_MDSTR_LENGTH((e)->value) + 32)
-
-int grpc_mdstr_is_legal_header(grpc_mdstr *s);
-int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s);
-int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s);
+#define GRPC_MDELEM_LENGTH(e) \
+ (GRPC_SLICE_LENGTH(GRPC_MDKEY((e))) + GRPC_SLICE_LENGTH(GRPC_MDVALUE((e))) + \
+ 32)
#define GRPC_MDSTR_KV_HASH(k_hash, v_hash) (GPR_ROTL((k_hash), 2) ^ (v_hash))
void grpc_mdctx_global_init(void);
-void grpc_mdctx_global_shutdown(void);
-
-/* Implementation provided by chttp2_transport */
-extern grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(
- grpc_slice input);
+void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx);
#ifdef __cplusplus
}
diff --git a/src/core/lib/transport/metadata_batch.c b/src/core/lib/transport/metadata_batch.c
index 84b5a74d51..9e0a8fbbe1 100644
--- a/src/core/lib/transport/metadata_batch.c
+++ b/src/core/lib/transport/metadata_batch.c
@@ -52,7 +52,7 @@ static void assert_valid_list(grpc_mdelem_list *list) {
GPR_ASSERT((list->head == list->tail) == (list->head->next == NULL));
for (l = list->head; l; l = l->next) {
- GPR_ASSERT(l->md);
+ GPR_ASSERT(!GRPC_MDISNULL(l->md));
GPR_ASSERT((l->prev == NULL) == (l == list->head));
GPR_ASSERT((l->next == NULL) == (l == list->tail));
if (l->next) GPR_ASSERT(l->next->prev == l);
@@ -72,24 +72,25 @@ void grpc_metadata_batch_init(grpc_metadata_batch *batch) {
batch->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
}
-void grpc_metadata_batch_destroy(grpc_metadata_batch *batch) {
+void grpc_metadata_batch_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_metadata_batch *batch) {
grpc_linked_mdelem *l;
for (l = batch->list.head; l; l = l->next) {
- GRPC_MDELEM_UNREF(l->md);
+ GRPC_MDELEM_UNREF(exec_ctx, l->md);
}
}
void grpc_metadata_batch_add_head(grpc_metadata_batch *batch,
grpc_linked_mdelem *storage,
- grpc_mdelem *elem_to_add) {
- GPR_ASSERT(elem_to_add);
+ grpc_mdelem elem_to_add) {
+ GPR_ASSERT(!GRPC_MDISNULL(elem_to_add));
storage->md = elem_to_add;
grpc_metadata_batch_link_head(batch, storage);
}
static void link_head(grpc_mdelem_list *list, grpc_linked_mdelem *storage) {
assert_valid_list(list);
- GPR_ASSERT(storage->md);
+ GPR_ASSERT(!GRPC_MDISNULL(storage->md));
storage->prev = NULL;
storage->next = list->head;
if (list->head != NULL) {
@@ -108,15 +109,15 @@ void grpc_metadata_batch_link_head(grpc_metadata_batch *batch,
void grpc_metadata_batch_add_tail(grpc_metadata_batch *batch,
grpc_linked_mdelem *storage,
- grpc_mdelem *elem_to_add) {
- GPR_ASSERT(elem_to_add);
+ grpc_mdelem elem_to_add) {
+ GPR_ASSERT(!GRPC_MDISNULL(elem_to_add));
storage->md = elem_to_add;
grpc_metadata_batch_link_tail(batch, storage);
}
static void link_tail(grpc_mdelem_list *list, grpc_linked_mdelem *storage) {
assert_valid_list(list);
- GPR_ASSERT(storage->md);
+ GPR_ASSERT(!GRPC_MDISNULL(storage->md));
storage->prev = list->tail;
storage->next = NULL;
storage->reserved = NULL;
@@ -140,9 +141,11 @@ void grpc_metadata_batch_move(grpc_metadata_batch *dst,
memset(src, 0, sizeof(grpc_metadata_batch));
}
-void grpc_metadata_batch_filter(grpc_metadata_batch *batch,
- grpc_mdelem *(*filter)(void *user_data,
- grpc_mdelem *elem),
+void grpc_metadata_batch_filter(grpc_exec_ctx *exec_ctx,
+ grpc_metadata_batch *batch,
+ grpc_mdelem (*filter)(grpc_exec_ctx *exec_ctx,
+ void *user_data,
+ grpc_mdelem elem),
void *user_data) {
grpc_linked_mdelem *l;
grpc_linked_mdelem *next;
@@ -151,10 +154,10 @@ void grpc_metadata_batch_filter(grpc_metadata_batch *batch,
assert_valid_list(&batch->list);
for (l = batch->list.head; l; l = next) {
- grpc_mdelem *orig = l->md;
- grpc_mdelem *filt = filter(user_data, orig);
+ grpc_mdelem orig = l->md;
+ grpc_mdelem filt = filter(exec_ctx, user_data, orig);
next = l->next;
- if (filt == NULL) {
+ if (GRPC_MDISNULL(filt)) {
if (l->prev) {
l->prev->next = l->next;
}
@@ -168,9 +171,9 @@ void grpc_metadata_batch_filter(grpc_metadata_batch *batch,
batch->list.tail = l->prev;
}
assert_valid_list(&batch->list);
- GRPC_MDELEM_UNREF(l->md);
- } else if (filt != orig) {
- GRPC_MDELEM_UNREF(orig);
+ GRPC_MDELEM_UNREF(exec_ctx, l->md);
+ } else if (!grpc_mdelem_eq(filt, orig)) {
+ GRPC_MDELEM_UNREF(exec_ctx, orig);
l->md = filt;
}
}
@@ -179,13 +182,15 @@ void grpc_metadata_batch_filter(grpc_metadata_batch *batch,
GPR_TIMER_END("grpc_metadata_batch_filter", 0);
}
-static grpc_mdelem *no_metadata_for_you(void *user_data, grpc_mdelem *elem) {
- return NULL;
+static grpc_mdelem no_metadata_for_you(grpc_exec_ctx *exec_ctx, void *user_data,
+ grpc_mdelem elem) {
+ return GRPC_MDNULL;
}
-void grpc_metadata_batch_clear(grpc_metadata_batch *batch) {
+void grpc_metadata_batch_clear(grpc_exec_ctx *exec_ctx,
+ grpc_metadata_batch *batch) {
batch->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
- grpc_metadata_batch_filter(batch, no_metadata_for_you, NULL);
+ grpc_metadata_batch_filter(exec_ctx, batch, no_metadata_for_you, NULL);
}
bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) {
diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h
index 7a9ccb4bc8..2c82ed6983 100644
--- a/src/core/lib/transport/metadata_batch.h
+++ b/src/core/lib/transport/metadata_batch.h
@@ -47,7 +47,7 @@ extern "C" {
#endif
typedef struct grpc_linked_mdelem {
- grpc_mdelem *md;
+ grpc_mdelem md;
struct grpc_linked_mdelem *next;
struct grpc_linked_mdelem *prev;
void *reserved;
@@ -68,8 +68,10 @@ typedef struct grpc_metadata_batch {
} grpc_metadata_batch;
void grpc_metadata_batch_init(grpc_metadata_batch *batch);
-void grpc_metadata_batch_destroy(grpc_metadata_batch *batch);
-void grpc_metadata_batch_clear(grpc_metadata_batch *batch);
+void grpc_metadata_batch_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_metadata_batch *batch);
+void grpc_metadata_batch_clear(grpc_exec_ctx *exec_ctx,
+ grpc_metadata_batch *batch);
bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch);
/* Returns the transport size of the batch. */
@@ -103,7 +105,7 @@ void grpc_metadata_batch_link_tail(grpc_metadata_batch *batch,
Takes ownership of \a elem_to_add */
void grpc_metadata_batch_add_head(grpc_metadata_batch *batch,
grpc_linked_mdelem *storage,
- grpc_mdelem *elem_to_add);
+ grpc_mdelem elem_to_add);
/** Add \a elem_to_add as the last element in \a batch, using
\a storage as backing storage for the linked list element.
\a storage is owned by the caller and must survive for the
@@ -112,15 +114,17 @@ void grpc_metadata_batch_add_head(grpc_metadata_batch *batch,
Takes ownership of \a elem_to_add */
void grpc_metadata_batch_add_tail(grpc_metadata_batch *batch,
grpc_linked_mdelem *storage,
- grpc_mdelem *elem_to_add);
+ grpc_mdelem elem_to_add);
/** For each element in \a batch, execute \a filter.
The return value from \a filter will be substituted for the
grpc_mdelem passed to \a filter. If \a filter returns NULL,
the element will be moved to the garbage list. */
-void grpc_metadata_batch_filter(grpc_metadata_batch *batch,
- grpc_mdelem *(*filter)(void *user_data,
- grpc_mdelem *elem),
+void grpc_metadata_batch_filter(grpc_exec_ctx *exec_ctx,
+ grpc_metadata_batch *batch,
+ grpc_mdelem (*filter)(grpc_exec_ctx *exec_ctx,
+ void *user_data,
+ grpc_mdelem elem),
void *user_data);
#ifndef NDEBUG
diff --git a/src/core/lib/transport/method_config.c b/src/core/lib/transport/method_config.c
new file mode 100644
index 0000000000..75317d426d
--- /dev/null
+++ b/src/core/lib/transport/method_config.c
@@ -0,0 +1,321 @@
+//
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include "src/core/lib/transport/method_config.h"
+
+#include <string.h>
+
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/slice/slice_hash_table.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/transport/metadata.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+//
+// grpc_method_config
+//
+
+// bool vtable
+
+static void *bool_copy(void *valuep) {
+ bool value = *(bool *)valuep;
+ bool *new_value = gpr_malloc(sizeof(bool));
+ *new_value = value;
+ return new_value;
+}
+
+static int bool_cmp(void *v1, void *v2) {
+ bool b1 = *(bool *)v1;
+ bool b2 = *(bool *)v2;
+ if (!b1 && b2) return -1;
+ if (b1 && !b2) return 1;
+ return 0;
+}
+
+static void free_mem(grpc_exec_ctx *exec_ctx, void *p) { gpr_free(p); }
+
+static grpc_slice_hash_table_vtable bool_vtable = {free_mem, bool_copy,
+ bool_cmp};
+
+// timespec vtable
+
+static void *timespec_copy(void *valuep) {
+ gpr_timespec value = *(gpr_timespec *)valuep;
+ gpr_timespec *new_value = gpr_malloc(sizeof(gpr_timespec));
+ *new_value = value;
+ return new_value;
+}
+
+static int timespec_cmp(void *v1, void *v2) {
+ return gpr_time_cmp(*(gpr_timespec *)v1, *(gpr_timespec *)v2);
+}
+
+static grpc_slice_hash_table_vtable timespec_vtable = {free_mem, timespec_copy,
+ timespec_cmp};
+
+// int32 vtable
+
+static void *int32_copy(void *valuep) {
+ int32_t value = *(int32_t *)valuep;
+ int32_t *new_value = gpr_malloc(sizeof(int32_t));
+ *new_value = value;
+ return new_value;
+}
+
+static int int32_cmp(void *v1, void *v2) {
+ int32_t i1 = *(int32_t *)v1;
+ int32_t i2 = *(int32_t *)v2;
+ if (i1 < i2) return -1;
+ if (i1 > i2) return 1;
+ return 0;
+}
+
+static grpc_slice_hash_table_vtable int32_vtable = {free_mem, int32_copy,
+ int32_cmp};
+
+struct grpc_method_config {
+ grpc_slice_hash_table *table;
+};
+
+grpc_method_config *grpc_method_config_create(
+ bool *wait_for_ready, gpr_timespec *timeout,
+ int32_t *max_request_message_bytes, int32_t *max_response_message_bytes) {
+ grpc_method_config *method_config = gpr_malloc(sizeof(grpc_method_config));
+ memset(method_config, 0, sizeof(grpc_method_config));
+ grpc_slice_hash_table_entry entries[4];
+ size_t num_entries = 0;
+ if (wait_for_ready != NULL) {
+ entries[num_entries].key = GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY;
+ entries[num_entries].value = wait_for_ready;
+ entries[num_entries].vtable = &bool_vtable;
+ ++num_entries;
+ }
+ if (timeout != NULL) {
+ entries[num_entries].key = GRPC_MDSTR_GRPC_DOT_TIMEOUT;
+ entries[num_entries].value = timeout;
+ entries[num_entries].vtable = &timespec_vtable;
+ ++num_entries;
+ }
+ if (max_request_message_bytes != NULL) {
+ entries[num_entries].key = GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES;
+ entries[num_entries].value = max_request_message_bytes;
+ entries[num_entries].vtable = &int32_vtable;
+ ++num_entries;
+ }
+ if (max_response_message_bytes != NULL) {
+ entries[num_entries].key = GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES;
+ entries[num_entries].value = max_response_message_bytes;
+ entries[num_entries].vtable = &int32_vtable;
+ ++num_entries;
+ }
+ method_config->table = grpc_slice_hash_table_create(num_entries, entries);
+ return method_config;
+}
+
+grpc_method_config *grpc_method_config_ref(grpc_method_config *method_config) {
+ grpc_slice_hash_table_ref(method_config->table);
+ return method_config;
+}
+
+void grpc_method_config_unref(grpc_exec_ctx *exec_ctx,
+ grpc_method_config *method_config) {
+ if (grpc_slice_hash_table_unref(exec_ctx, method_config->table)) {
+ gpr_free(method_config);
+ }
+}
+
+int grpc_method_config_cmp(const grpc_method_config *method_config1,
+ const grpc_method_config *method_config2) {
+ return grpc_slice_hash_table_cmp(method_config1->table,
+ method_config2->table);
+}
+
+const bool *grpc_method_config_get_wait_for_ready(
+ const grpc_method_config *method_config) {
+ return grpc_slice_hash_table_get(method_config->table,
+ GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY);
+}
+
+const gpr_timespec *grpc_method_config_get_timeout(
+ const grpc_method_config *method_config) {
+ return grpc_slice_hash_table_get(method_config->table,
+ GRPC_MDSTR_GRPC_DOT_TIMEOUT);
+}
+
+const int32_t *grpc_method_config_get_max_request_message_bytes(
+ const grpc_method_config *method_config) {
+ return grpc_slice_hash_table_get(
+ method_config->table, GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES);
+}
+
+const int32_t *grpc_method_config_get_max_response_message_bytes(
+ const grpc_method_config *method_config) {
+ return grpc_slice_hash_table_get(
+ method_config->table, GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES);
+}
+
+//
+// grpc_method_config_table
+//
+
+static void method_config_unref(grpc_exec_ctx *exec_ctx, void *valuep) {
+ grpc_method_config_unref(exec_ctx, valuep);
+}
+
+static void *method_config_ref(void *valuep) {
+ return grpc_method_config_ref(valuep);
+}
+
+static int method_config_cmp(void *valuep1, void *valuep2) {
+ return grpc_method_config_cmp(valuep1, valuep2);
+}
+
+static const grpc_slice_hash_table_vtable method_config_table_vtable = {
+ method_config_unref, method_config_ref, method_config_cmp};
+
+grpc_method_config_table *grpc_method_config_table_create(
+ size_t num_entries, grpc_method_config_table_entry *entries) {
+ grpc_slice_hash_table_entry *hash_table_entries =
+ gpr_malloc(sizeof(grpc_slice_hash_table_entry) * num_entries);
+ for (size_t i = 0; i < num_entries; ++i) {
+ hash_table_entries[i].key = entries[i].method_name;
+ hash_table_entries[i].value = entries[i].method_config;
+ hash_table_entries[i].vtable = &method_config_table_vtable;
+ }
+ grpc_method_config_table *method_config_table =
+ grpc_slice_hash_table_create(num_entries, hash_table_entries);
+ gpr_free(hash_table_entries);
+ return method_config_table;
+}
+
+grpc_method_config_table *grpc_method_config_table_ref(
+ grpc_method_config_table *table) {
+ return grpc_slice_hash_table_ref(table);
+}
+
+void grpc_method_config_table_unref(grpc_exec_ctx *exec_ctx,
+ grpc_method_config_table *table) {
+ grpc_slice_hash_table_unref(exec_ctx, table);
+}
+
+int grpc_method_config_table_cmp(const grpc_method_config_table *table1,
+ const grpc_method_config_table *table2) {
+ return grpc_slice_hash_table_cmp(table1, table2);
+}
+
+void *grpc_method_config_table_get(grpc_exec_ctx *exec_ctx,
+ const grpc_slice_hash_table *table,
+ const grpc_slice path) {
+ void *value = grpc_slice_hash_table_get(table, path);
+ // If we didn't find a match for the path, try looking for a wildcard
+ // entry (i.e., change "/service/method" to "/service/*").
+ if (value == NULL) {
+ int sep_pos = grpc_slice_rchr(path, '/') + 1;
+ grpc_slice search = grpc_slice_malloc((size_t)(sep_pos + 1));
+ memcpy(GRPC_SLICE_START_PTR(search), GRPC_SLICE_START_PTR(path),
+ (size_t)sep_pos);
+ GRPC_SLICE_START_PTR(search)[sep_pos] = '*';
+ value = grpc_slice_hash_table_get(table, search);
+ grpc_slice_unref_internal(exec_ctx, search);
+ }
+ return value;
+}
+
+static void *copy_arg(void *p) { return grpc_method_config_table_ref(p); }
+
+static void destroy_arg(grpc_exec_ctx *exec_ctx, void *p) {
+ grpc_method_config_table_unref(exec_ctx, p);
+}
+
+static int cmp_arg(void *p1, void *p2) {
+ return grpc_method_config_table_cmp(p1, p2);
+}
+
+static grpc_arg_pointer_vtable arg_vtable = {copy_arg, destroy_arg, cmp_arg};
+
+grpc_arg grpc_method_config_table_create_channel_arg(
+ grpc_method_config_table *table) {
+ grpc_arg arg;
+ arg.type = GRPC_ARG_POINTER;
+ arg.key = GRPC_ARG_SERVICE_CONFIG;
+ arg.value.pointer.p = table;
+ arg.value.pointer.vtable = &arg_vtable;
+ return arg;
+}
+
+// State used by convert_entry() below.
+typedef struct conversion_state {
+ void *(*convert_value)(const grpc_method_config *method_config);
+ const grpc_slice_hash_table_vtable *vtable;
+ size_t num_entries;
+ grpc_slice_hash_table_entry *entries;
+} conversion_state;
+
+// A function to be passed to grpc_slice_hash_table_iterate() to create
+// a copy of the entries.
+static void convert_entry(const grpc_slice_hash_table_entry *entry,
+ void *user_data) {
+ conversion_state *state = user_data;
+ state->entries[state->num_entries].key = grpc_slice_ref_internal(entry->key);
+ state->entries[state->num_entries].value = state->convert_value(entry->value);
+ state->entries[state->num_entries].vtable = state->vtable;
+ ++state->num_entries;
+}
+
+grpc_slice_hash_table *grpc_method_config_table_convert(
+ grpc_exec_ctx *exec_ctx, const grpc_method_config_table *table,
+ void *(*convert_value)(const grpc_method_config *method_config),
+ const grpc_slice_hash_table_vtable *vtable) {
+ // Create an array of the entries in the table with converted values.
+ conversion_state state;
+ state.convert_value = convert_value;
+ state.vtable = vtable;
+ state.num_entries = 0;
+ state.entries = gpr_malloc(sizeof(grpc_slice_hash_table_entry) *
+ grpc_slice_hash_table_num_entries(table));
+ grpc_slice_hash_table_iterate(table, convert_entry, &state);
+ // Create a new table based on the array we just constructed.
+ grpc_slice_hash_table *new_table =
+ grpc_slice_hash_table_create(state.num_entries, state.entries);
+ // Clean up the array.
+ for (size_t i = 0; i < state.num_entries; ++i) {
+ grpc_slice_unref_internal(exec_ctx, state.entries[i].key);
+ vtable->destroy_value(exec_ctx, state.entries[i].value);
+ }
+ gpr_free(state.entries);
+ // Return the new table.
+ return new_table;
+}
diff --git a/src/core/lib/transport/method_config.h b/src/core/lib/transport/method_config.h
new file mode 100644
index 0000000000..3e266a6ecd
--- /dev/null
+++ b/src/core/lib/transport/method_config.h
@@ -0,0 +1,139 @@
+//
+// Copyright 2016, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#ifndef GRPC_CORE_LIB_TRANSPORT_METHOD_CONFIG_H
+#define GRPC_CORE_LIB_TRANSPORT_METHOD_CONFIG_H
+
+#include <stdbool.h>
+
+#include <grpc/impl/codegen/gpr_types.h>
+#include <grpc/impl/codegen/grpc_types.h>
+
+#include "src/core/lib/slice/slice_hash_table.h"
+#include "src/core/lib/transport/metadata.h"
+
+/// Per-method configuration.
+typedef struct grpc_method_config grpc_method_config;
+
+/// Creates a grpc_method_config with the specified parameters.
+/// Any parameter may be NULL to indicate that the value is unset.
+///
+/// \a wait_for_ready indicates whether the client should wait until the
+/// request deadline for the channel to become ready, even if there is a
+/// temporary failure before the deadline while attempting to connect.
+///
+/// \a timeout indicates the timeout for calls.
+///
+/// \a max_request_message_bytes and \a max_response_message_bytes
+/// indicate the maximum sizes of the request (checked when sending) and
+/// response (checked when receiving) messages.
+grpc_method_config *grpc_method_config_create(
+ bool *wait_for_ready, gpr_timespec *timeout,
+ int32_t *max_request_message_bytes, int32_t *max_response_message_bytes);
+
+grpc_method_config *grpc_method_config_ref(grpc_method_config *method_config);
+void grpc_method_config_unref(grpc_exec_ctx *exec_ctx,
+ grpc_method_config *method_config);
+
+/// Compares two grpc_method_configs.
+/// The sort order is stable but undefined.
+int grpc_method_config_cmp(const grpc_method_config *method_config1,
+ const grpc_method_config *method_config2);
+
+/// These methods return NULL if the requested field is unset.
+/// The caller does NOT take ownership of the result.
+const bool *grpc_method_config_get_wait_for_ready(
+ const grpc_method_config *method_config);
+const gpr_timespec *grpc_method_config_get_timeout(
+ const grpc_method_config *method_config);
+const int32_t *grpc_method_config_get_max_request_message_bytes(
+ const grpc_method_config *method_config);
+const int32_t *grpc_method_config_get_max_response_message_bytes(
+ const grpc_method_config *method_config);
+
+/// A table of method configs.
+typedef grpc_slice_hash_table grpc_method_config_table;
+
+typedef struct grpc_method_config_table_entry {
+ /// The name is of one of the following forms:
+ /// service/method -- specifies exact service and method name
+ /// service/* -- matches all methods for the specified service
+ grpc_slice method_name;
+ grpc_method_config *method_config;
+} grpc_method_config_table_entry;
+
+/// Takes new references to all keys and values in \a entries.
+grpc_method_config_table *grpc_method_config_table_create(
+ size_t num_entries, grpc_method_config_table_entry *entries);
+
+grpc_method_config_table *grpc_method_config_table_ref(
+ grpc_method_config_table *table);
+void grpc_method_config_table_unref(grpc_exec_ctx *exec_ctx,
+ grpc_method_config_table *table);
+
+/// Compares two grpc_method_config_tables.
+/// The sort order is stable but undefined.
+int grpc_method_config_table_cmp(const grpc_method_config_table *table1,
+ const grpc_method_config_table *table2);
+
+/// Gets the method config for the specified \a path, which should be of
+/// the form "/service/method".
+/// Returns NULL if the method has no config.
+/// Caller does NOT own a reference to the result.
+///
+/// Note: This returns a void *instead of a grpc_method_config *so that
+/// it can also be used for tables constructed via
+/// grpc_method_config_table_convert().
+void *grpc_method_config_table_get(grpc_exec_ctx *exec_ctx,
+ const grpc_slice_hash_table *table,
+ const grpc_slice path);
+
+/// Returns a channel arg containing \a table.
+grpc_arg grpc_method_config_table_create_channel_arg(
+ grpc_method_config_table *table);
+
+/// Generates a new table from \a table whose values are converted to a
+/// new form via the \a convert_value function. The new table will use
+/// \a vtable for its values.
+///
+/// This is generally used to convert the table's value type from
+/// grpc_method_config to a simple struct containing only the parameters
+/// relevant to a particular filter, thus avoiding the need for a hash
+/// table lookup on the fast path. In that scenario, \a convert_value
+/// will return a new instance of the struct containing the values from
+/// the grpc_method_config, and \a vtable provides the methods for
+/// operating on the struct type.
+grpc_slice_hash_table *grpc_method_config_table_convert(
+ grpc_exec_ctx *exec_ctx, const grpc_method_config_table *table,
+ void *(*convert_value)(const grpc_method_config *method_config),
+ const grpc_slice_hash_table_vtable *vtable);
+
+#endif /* GRPC_CORE_LIB_TRANSPORT_METHOD_CONFIG_H */
diff --git a/src/core/lib/transport/pid_controller.h b/src/core/lib/transport/pid_controller.h
index 059b5b0834..83c82d6471 100644
--- a/src/core/lib/transport/pid_controller.h
+++ b/src/core/lib/transport/pid_controller.h
@@ -61,4 +61,4 @@ void grpc_pid_controller_reset(grpc_pid_controller *pid_controller);
double grpc_pid_controller_update(grpc_pid_controller *pid_controller,
double error, double dt);
-#endif
+#endif /* GRPC_CORE_LIB_TRANSPORT_PID_CONTROLLER_H */
diff --git a/src/core/lib/transport/service_config.c b/src/core/lib/transport/service_config.c
index 2e2b59e3f7..8073a46105 100644
--- a/src/core/lib/transport/service_config.c
+++ b/src/core/lib/transport/service_config.c
@@ -39,8 +39,10 @@
#include <grpc/support/string_util.h>
#include "src/core/lib/json/json.h"
+#include "src/core/lib/slice/slice_hash_table.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
-#include "src/core/lib/transport/mdstr_hash_table.h"
// The main purpose of the code here is to parse the service config in
// JSON form, which will look like this:
@@ -146,9 +148,10 @@ static char* parse_json_method_name(grpc_json* json) {
// each name found, incrementing \a idx for each entry added.
// Returns false on error.
static bool parse_json_method_config(
- grpc_json* json, void* (*create_value)(const grpc_json* method_config_json),
- const grpc_mdstr_hash_table_vtable* vtable,
- grpc_mdstr_hash_table_entry* entries, size_t* idx) {
+ grpc_exec_ctx* exec_ctx, grpc_json* json,
+ void* (*create_value)(const grpc_json* method_config_json),
+ const grpc_slice_hash_table_vtable* vtable,
+ grpc_slice_hash_table_entry* entries, size_t* idx) {
// Construct value.
void* method_config = create_value(json);
if (method_config == NULL) return false;
@@ -169,27 +172,27 @@ static bool parse_json_method_config(
if (paths.count == 0) goto done; // No names specified.
// Add entry for each path.
for (size_t i = 0; i < paths.count; ++i) {
- entries[*idx].key = grpc_mdstr_from_string(paths.strs[i]);
+ entries[*idx].key = grpc_slice_from_copied_string(paths.strs[i]);
entries[*idx].value = vtable->copy_value(method_config);
entries[*idx].vtable = vtable;
++*idx;
}
success = true;
done:
- vtable->destroy_value(method_config);
+ vtable->destroy_value(exec_ctx, method_config);
gpr_strvec_destroy(&paths);
return success;
}
-grpc_mdstr_hash_table* grpc_service_config_create_method_config_table(
- const grpc_service_config* service_config,
+grpc_slice_hash_table* grpc_service_config_create_method_config_table(
+ grpc_exec_ctx* exec_ctx, const grpc_service_config* service_config,
void* (*create_value)(const grpc_json* method_config_json),
- const grpc_mdstr_hash_table_vtable* vtable) {
+ const grpc_slice_hash_table_vtable* vtable) {
const grpc_json* json = service_config->json_tree;
// Traverse parsed JSON tree.
if (json->type != GRPC_JSON_OBJECT || json->key != NULL) return NULL;
size_t num_entries = 0;
- grpc_mdstr_hash_table_entry* entries = NULL;
+ grpc_slice_hash_table_entry* entries = NULL;
for (grpc_json* field = json->child; field != NULL; field = field->next) {
if (field->key == NULL) return NULL;
if (strcmp(field->key, "methodConfig") == 0) {
@@ -201,12 +204,12 @@ grpc_mdstr_hash_table* grpc_service_config_create_method_config_table(
num_entries += count_names_in_method_config_json(method);
}
// Populate method config table entries.
- entries = gpr_malloc(num_entries * sizeof(grpc_mdstr_hash_table_entry));
+ entries = gpr_malloc(num_entries * sizeof(grpc_slice_hash_table_entry));
size_t idx = 0;
for (grpc_json* method = field->child; method != NULL;
method = method->next) {
- if (!parse_json_method_config(method, create_value, vtable, entries,
- &idx)) {
+ if (!parse_json_method_config(exec_ctx, method, create_value, vtable,
+ entries, &idx)) {
return NULL;
}
}
@@ -214,36 +217,38 @@ grpc_mdstr_hash_table* grpc_service_config_create_method_config_table(
}
}
// Instantiate method config table.
- grpc_mdstr_hash_table* method_config_table = NULL;
+ grpc_slice_hash_table* method_config_table = NULL;
if (entries != NULL) {
- method_config_table = grpc_mdstr_hash_table_create(num_entries, entries);
+ method_config_table = grpc_slice_hash_table_create(num_entries, entries);
// Clean up.
for (size_t i = 0; i < num_entries; ++i) {
- GRPC_MDSTR_UNREF(entries[i].key);
- vtable->destroy_value(entries[i].value);
+ grpc_slice_unref_internal(exec_ctx, entries[i].key);
+ vtable->destroy_value(exec_ctx, entries[i].value);
}
gpr_free(entries);
}
return method_config_table;
}
-void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table,
- const grpc_mdstr* path) {
- void* value = grpc_mdstr_hash_table_get(table, path);
+void* grpc_method_config_table_get(grpc_exec_ctx* exec_ctx,
+ const grpc_slice_hash_table* table,
+ grpc_slice path) {
+ void* value = grpc_slice_hash_table_get(table, path);
// If we didn't find a match for the path, try looking for a wildcard
// entry (i.e., change "/service/method" to "/service/*").
if (value == NULL) {
- const char* path_str = grpc_mdstr_as_c_string(path);
+ char* path_str = grpc_dump_slice(path, GPR_DUMP_ASCII);
const char* sep = strrchr(path_str, '/') + 1;
const size_t len = (size_t)(sep - path_str);
char* buf = gpr_malloc(len + 2); // '*' and NUL
memcpy(buf, path_str, len);
buf[len] = '*';
buf[len + 1] = '\0';
- grpc_mdstr* wildcard_path = grpc_mdstr_from_string(buf);
+ grpc_slice wildcard_path = grpc_slice_from_copied_string(buf);
gpr_free(buf);
- value = grpc_mdstr_hash_table_get(table, wildcard_path);
- GRPC_MDSTR_UNREF(wildcard_path);
+ value = grpc_slice_hash_table_get(table, wildcard_path);
+ grpc_slice_unref_internal(exec_ctx, wildcard_path);
+ gpr_free(path_str);
}
return value;
}
diff --git a/src/core/lib/transport/service_config.h b/src/core/lib/transport/service_config.h
index 2ffe475193..ab964b3bae 100644
--- a/src/core/lib/transport/service_config.h
+++ b/src/core/lib/transport/service_config.h
@@ -35,7 +35,7 @@
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/lib/json/json.h"
-#include "src/core/lib/transport/mdstr_hash_table.h"
+#include "src/core/lib/slice/slice_hash_table.h"
typedef struct grpc_service_config grpc_service_config;
@@ -53,10 +53,10 @@ const char* grpc_service_config_get_lb_policy_name(
/// returned by \a create_value(), based on data parsed from the JSON tree.
/// \a vtable provides methods used to manage the values.
/// Returns NULL on error.
-grpc_mdstr_hash_table* grpc_service_config_create_method_config_table(
- const grpc_service_config* service_config,
+grpc_slice_hash_table* grpc_service_config_create_method_config_table(
+ grpc_exec_ctx* exec_ctx, const grpc_service_config* service_config,
void* (*create_value)(const grpc_json* method_config_json),
- const grpc_mdstr_hash_table_vtable* vtable);
+ const grpc_slice_hash_table_vtable* vtable);
/// A helper function for looking up values in the table returned by
/// \a grpc_service_config_create_method_config_table().
@@ -64,7 +64,8 @@ grpc_mdstr_hash_table* grpc_service_config_create_method_config_table(
/// the form "/service/method".
/// Returns NULL if the method has no config.
/// Caller does NOT own a reference to the result.
-void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table,
- const grpc_mdstr* path);
+void* grpc_method_config_table_get(grpc_exec_ctx* exec_ctx,
+ const grpc_slice_hash_table* table,
+ const grpc_slice path);
#endif /* GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H */
diff --git a/src/core/lib/transport/static_metadata.c b/src/core/lib/transport/static_metadata.c
index 8b22592b45..575f442a9b 100644
--- a/src/core/lib/transport/static_metadata.c
+++ b/src/core/lib/transport/static_metadata.c
@@ -41,120 +41,754 @@
#include "src/core/lib/transport/static_metadata.h"
-grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
+#include "src/core/lib/slice/slice_internal.h"
+
+static uint8_t g_raw_bytes[] = {
+ 48, 49, 50, 50, 48, 48, 50, 48, 52, 50, 48, 54, 51, 48, 52,
+ 52, 48, 48, 52, 48, 52, 53, 48, 48, 97, 99, 99, 101, 112, 116,
+ 97, 99, 99, 101, 112, 116, 45, 99, 104, 97, 114, 115, 101, 116, 97,
+ 99, 99, 101, 112, 116, 45, 101, 110, 99, 111, 100, 105, 110, 103, 97,
+ 99, 99, 101, 112, 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, 97,
+ 99, 99, 101, 112, 116, 45, 114, 97, 110, 103, 101, 115, 97, 99, 99,
+ 101, 115, 115, 45, 99, 111, 110, 116, 114, 111, 108, 45, 97, 108, 108,
+ 111, 119, 45, 111, 114, 105, 103, 105, 110, 97, 103, 101, 97, 108, 108,
+ 111, 119, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 103,
+ 114, 112, 99, 58, 97, 117, 116, 104, 111, 114, 105, 116, 121, 97, 117,
+ 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, 99, 97, 99, 104,
+ 101, 45, 99, 111, 110, 116, 114, 111, 108, 99, 111, 110, 116, 101, 110,
+ 116, 45, 100, 105, 115, 112, 111, 115, 105, 116, 105, 111, 110, 99, 111,
+ 110, 116, 101, 110, 116, 45, 101, 110, 99, 111, 100, 105, 110, 103, 99,
+ 111, 110, 116, 101, 110, 116, 45, 108, 97, 110, 103, 117, 97, 103, 101,
+ 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103, 116, 104, 99,
+ 111, 110, 116, 101, 110, 116, 45, 108, 111, 99, 97, 116, 105, 111, 110,
+ 99, 111, 110, 116, 101, 110, 116, 45, 114, 97, 110, 103, 101, 99, 111,
+ 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 99, 111, 111, 107, 105,
+ 101, 100, 97, 116, 101, 100, 101, 102, 108, 97, 116, 101, 100, 101, 102,
+ 108, 97, 116, 101, 44, 103, 122, 105, 112, 101, 116, 97, 103, 101, 120,
+ 112, 101, 99, 116, 101, 120, 112, 105, 114, 101, 115, 102, 114, 111, 109,
+ 71, 69, 84, 103, 114, 112, 99, 103, 114, 112, 99, 45, 97, 99, 99,
+ 101, 112, 116, 45, 101, 110, 99, 111, 100, 105, 110, 103, 103, 114, 112,
+ 99, 46, 109, 97, 120, 95, 114, 101, 113, 117, 101, 115, 116, 95, 109,
+ 101, 115, 115, 97, 103, 101, 95, 98, 121, 116, 101, 115, 103, 114, 112,
+ 99, 46, 109, 97, 120, 95, 114, 101, 115, 112, 111, 110, 115, 101, 95,
+ 109, 101, 115, 115, 97, 103, 101, 95, 98, 121, 116, 101, 115, 103, 114,
+ 112, 99, 46, 116, 105, 109, 101, 111, 117, 116, 103, 114, 112, 99, 46,
+ 119, 97, 105, 116, 95, 102, 111, 114, 95, 114, 101, 97, 100, 121, 103,
+ 114, 112, 99, 45, 101, 110, 99, 111, 100, 105, 110, 103, 103, 114, 112,
+ 99, 45, 105, 110, 116, 101, 114, 110, 97, 108, 45, 101, 110, 99, 111,
+ 100, 105, 110, 103, 45, 114, 101, 113, 117, 101, 115, 116, 103, 114, 112,
+ 99, 45, 109, 101, 115, 115, 97, 103, 101, 103, 114, 112, 99, 45, 112,
+ 97, 121, 108, 111, 97, 100, 45, 98, 105, 110, 103, 114, 112, 99, 45,
+ 115, 116, 97, 116, 115, 45, 98, 105, 110, 103, 114, 112, 99, 45, 115,
+ 116, 97, 116, 117, 115, 103, 114, 112, 99, 45, 116, 105, 109, 101, 111,
+ 117, 116, 103, 114, 112, 99, 45, 116, 114, 97, 99, 105, 110, 103, 45,
+ 98, 105, 110, 103, 122, 105, 112, 103, 122, 105, 112, 44, 32, 100, 101,
+ 102, 108, 97, 116, 101, 104, 111, 115, 116, 104, 116, 116, 112, 104, 116,
+ 116, 112, 115, 105, 100, 101, 110, 116, 105, 116, 121, 105, 100, 101, 110,
+ 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101, 105, 100, 101,
+ 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101, 44, 103,
+ 122, 105, 112, 105, 100, 101, 110, 116, 105, 116, 121, 44, 103, 122, 105,
+ 112, 105, 102, 45, 109, 97, 116, 99, 104, 105, 102, 45, 109, 111, 100,
+ 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 105, 102, 45, 110,
+ 111, 110, 101, 45, 109, 97, 116, 99, 104, 105, 102, 45, 114, 97, 110,
+ 103, 101, 105, 102, 45, 117, 110, 109, 111, 100, 105, 102, 105, 101, 100,
+ 45, 115, 105, 110, 99, 101, 108, 97, 115, 116, 45, 109, 111, 100, 105,
+ 102, 105, 101, 100, 108, 98, 45, 99, 111, 115, 116, 45, 98, 105, 110,
+ 108, 98, 45, 116, 111, 107, 101, 110, 108, 105, 110, 107, 108, 111, 99,
+ 97, 116, 105, 111, 110, 109, 97, 120, 45, 102, 111, 114, 119, 97, 114,
+ 100, 115, 58, 109, 101, 116, 104, 111, 100, 58, 112, 97, 116, 104, 80,
+ 79, 83, 84, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 101, 110,
+ 116, 105, 99, 97, 116, 101, 112, 114, 111, 120, 121, 45, 97, 117, 116,
+ 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, 80, 85, 84, 114, 97,
+ 110, 103, 101, 114, 101, 102, 101, 114, 101, 114, 114, 101, 102, 114, 101,
+ 115, 104, 114, 101, 116, 114, 121, 45, 97, 102, 116, 101, 114, 58, 115,
+ 99, 104, 101, 109, 101, 115, 101, 114, 118, 101, 114, 115, 101, 116, 45,
+ 99, 111, 111, 107, 105, 101, 47, 47, 103, 114, 112, 99, 46, 108, 98,
+ 46, 118, 49, 46, 76, 111, 97, 100, 66, 97, 108, 97, 110, 99, 101,
+ 114, 47, 66, 97, 108, 97, 110, 99, 101, 76, 111, 97, 100, 47, 105,
+ 110, 100, 101, 120, 46, 104, 116, 109, 108, 58, 115, 116, 97, 116, 117,
+ 115, 115, 116, 114, 105, 99, 116, 45, 116, 114, 97, 110, 115, 112, 111,
+ 114, 116, 45, 115, 101, 99, 117, 114, 105, 116, 121, 116, 101, 116, 114,
+ 97, 105, 108, 101, 114, 115, 116, 114, 97, 110, 115, 102, 101, 114, 45,
+ 101, 110, 99, 111, 100, 105, 110, 103, 117, 115, 101, 114, 45, 97, 103,
+ 101, 110, 116, 118, 97, 114, 121, 118, 105, 97, 119, 119, 119, 45, 97,
+ 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 101};
+
+static void static_ref(void *unused) {}
+static void static_unref(grpc_exec_ctx *exec_ctx, void *unused) {}
+static const grpc_slice_refcount_vtable static_vtable = {
+ static_ref, static_unref, grpc_static_slice_hash};
+static grpc_slice_refcount g_refcnt = {&static_vtable};
+
+bool grpc_is_static_metadata_string(grpc_slice slice) {
+ return slice.refcount != NULL && slice.refcount->vtable == &static_vtable;
+}
+
+const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 0, .length = 1}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 1, .length = 1}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 2, .length = 1}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 3, .length = 3}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 6, .length = 3}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 9, .length = 3}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 12, .length = 3}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 15, .length = 3}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 18, .length = 3}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 21, .length = 3}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 24, .length = 6}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 30, .length = 14}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 44, .length = 15}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 59, .length = 15}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 74, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 87, .length = 27}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 114, .length = 3}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 117, .length = 5}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 122, .length = 16}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 138, .length = 10}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 148, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 161, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 174, .length = 19}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 193, .length = 16}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 209, .length = 16}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 225, .length = 14}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 239, .length = 16}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 255, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 268, .length = 12}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 280, .length = 6}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 286, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 290, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 297, .length = 12}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 313, .length = 6}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 319, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 326, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 330, .length = 3}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 333, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 337, .length = 20}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 357, .length = 30}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 387, .length = 31}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 418, .length = 12}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 430, .length = 19}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 449, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 462, .length = 30}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 492, .length = 12}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 504, .length = 16}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 520, .length = 14}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 534, .length = 11}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 545, .length = 12}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 557, .length = 16}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 573, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 577, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 590, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 594, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 598, .length = 5}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 603, .length = 8}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 611, .length = 16}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 627, .length = 21}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 648, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 661, .length = 8}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 669, .length = 17}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 686, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 699, .length = 8}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 707, .length = 19}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 726, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 739, .length = 11}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 750, .length = 8}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 758, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 762, .length = 8}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 770, .length = 12}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 782, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 789, .length = 5}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 794, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 798, .length = 18}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 816, .length = 19}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 835, .length = 3}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 838, .length = 5}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 843, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 850, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 857, .length = 11}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 868, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 875, .length = 6}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 881, .length = 10}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 891, .length = 1}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 892, .length = 36}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 928, .length = 11}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 939, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 946, .length = 25}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 971, .length = 2}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 973, .length = 8}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 981, .length = 17}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 998, .length = 10}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 1008, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 1012, .length = 3}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 1015, .length = 16}},
+};
+
+static const uint8_t g_revmap[] = {
+ 0, 1, 2, 3, 255, 255, 4, 255, 255, 5, 255, 255, 6, 255, 255,
+ 7, 255, 255, 8, 255, 255, 9, 255, 255, 10, 255, 255, 255, 255, 255,
+ 11, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 13,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 14,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 15, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 16, 255, 255, 17, 255, 255,
+ 255, 255, 18, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 19, 255, 255, 255, 255, 255, 255, 255, 255, 255, 20, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 21, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 23, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 24,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 25, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 26,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 27, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 28, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 29, 255, 255, 255, 255,
+ 255, 30, 255, 255, 255, 31, 255, 255, 255, 255, 255, 255, 32, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 34, 255, 255, 255, 35, 255,
+ 255, 255, 255, 255, 36, 255, 255, 255, 255, 255, 255, 37, 255, 255, 255,
+ 38, 255, 255, 39, 255, 255, 255, 40, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 41, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 42, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 43, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 44, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 45,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 46, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 47, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 48, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 49, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 50, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 52, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 53, 255, 255, 255, 54, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 55, 255, 255, 255, 56, 255, 255, 255, 57, 255,
+ 255, 255, 255, 58, 255, 255, 255, 255, 255, 255, 255, 59, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 60, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 61, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 62, 255, 255, 255, 255, 255, 255, 255, 63, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 64, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 65, 255, 255, 255, 255, 255,
+ 255, 255, 66, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 67, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 68, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 69, 255, 255, 255, 255, 255, 255, 255, 70, 255, 255, 255, 71, 255, 255,
+ 255, 255, 255, 255, 255, 72, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 73, 255, 255, 255, 255, 255, 255, 74, 255, 255, 255, 255, 75,
+ 255, 255, 255, 76, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 77, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 78, 255, 255, 79, 255,
+ 255, 255, 255, 80, 255, 255, 255, 255, 255, 255, 81, 255, 255, 255, 255,
+ 255, 255, 82, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 83, 255,
+ 255, 255, 255, 255, 255, 84, 255, 255, 255, 255, 255, 85, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 86, 87, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 88, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 89, 255, 255, 255, 255, 255,
+ 255, 90, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 91, 255, 92, 255,
+ 255, 255, 255, 255, 255, 255, 93, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 94, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 95, 255, 255, 255, 96, 255, 255, 97, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255};
+
+int grpc_static_metadata_index(grpc_slice slice) {
+ if (GRPC_SLICE_LENGTH(slice) == 0) return 33;
+ if (slice.refcount != &g_refcnt) return -1;
+ size_t ofs = (size_t)(slice.data.refcounted.bytes - g_raw_bytes);
+ if (ofs > sizeof(g_revmap)) return -1;
+ uint8_t id = g_revmap[ofs];
+ return id == 255 ? -1 : (grpc_static_slice_table[id].data.refcounted.length ==
+ slice.data.refcounted.length
+ ? id
+ : -1);
+}
-grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 4, 8, 6, 2, 4, 8, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2] =
- {11, 33, 10, 33, 12, 33, 12, 50, 13, 33, 14, 33, 15, 33, 16, 33, 17, 33,
- 19, 33, 20, 33, 21, 33, 22, 33, 23, 33, 24, 33, 25, 33, 26, 33, 27, 33,
- 28, 18, 28, 33, 29, 33, 30, 33, 34, 33, 35, 33, 36, 33, 37, 33, 40, 31,
- 40, 32, 40, 49, 40, 54, 40, 55, 40, 56, 40, 57, 41, 31, 41, 49, 41, 54,
- 46, 0, 46, 1, 46, 2, 51, 33, 58, 33, 59, 33, 60, 33, 61, 33, 62, 33,
- 63, 33, 64, 33, 65, 33, 66, 33, 67, 33, 68, 33, 69, 38, 69, 71, 69, 74,
- 70, 82, 70, 83, 72, 33, 73, 33, 75, 33, 76, 33, 77, 33, 78, 33, 79, 39,
- 79, 52, 79, 53, 80, 33, 81, 33, 84, 3, 84, 4, 84, 5, 84, 6, 84, 7,
- 84, 8, 84, 9, 85, 33, 86, 87, 88, 33, 89, 33, 90, 33, 91, 33, 92, 33};
-
-const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = {
- "0",
- "1",
- "2",
- "200",
- "204",
- "206",
- "304",
- "400",
- "404",
- "500",
- "accept",
- "accept-charset",
- "accept-encoding",
- "accept-language",
- "accept-ranges",
- "access-control-allow-origin",
- "age",
- "allow",
- "application/grpc",
- ":authority",
- "authorization",
- "cache-control",
- "content-disposition",
- "content-encoding",
- "content-language",
- "content-length",
- "content-location",
- "content-range",
- "content-type",
- "cookie",
- "date",
- "deflate",
- "deflate,gzip",
- "",
- "etag",
- "expect",
- "expires",
- "from",
- "GET",
- "grpc",
- "grpc-accept-encoding",
- "grpc-encoding",
- "grpc-internal-encoding-request",
- "grpc-message",
- "grpc-payload-bin",
- "grpc-stats-bin",
- "grpc-status",
- "grpc-timeout",
- "grpc-tracing-bin",
- "gzip",
- "gzip, deflate",
- "host",
- "http",
- "https",
- "identity",
- "identity,deflate",
- "identity,deflate,gzip",
- "identity,gzip",
- "if-match",
- "if-modified-since",
- "if-none-match",
- "if-range",
- "if-unmodified-since",
- "last-modified",
- "lb-cost-bin",
- "lb-token",
- "link",
- "location",
- "max-forwards",
- ":method",
- ":path",
- "POST",
- "proxy-authenticate",
- "proxy-authorization",
- "PUT",
- "range",
- "referer",
- "refresh",
- "retry-after",
- ":scheme",
- "server",
- "set-cookie",
- "/",
- "/index.html",
- ":status",
- "strict-transport-security",
- "te",
- "trailers",
- "transfer-encoding",
- "user-agent",
- "vary",
- "via",
- "www-authenticate"};
+#define ELEMS_PHASHLEN 0x40
+#define ELEMS_PHASHNKEYS 81
+#define ELEMS_PHASHRANGE 128
+#define ELEMS_PHASHSALT 0x9e3779b9
+
+static const uint8_t elems_tab[] = {
+ 0, 17, 61, 28, 4, 12, 47, 0, 0, 0, 61, 0, 47, 0, 61, 76,
+ 61, 70, 76, 0, 0, 10, 4, 60, 0, 0, 0, 16, 88, 47, 1, 76,
+ 76, 0, 76, 0, 61, 0, 23, 0, 0, 51, 1, 92, 32, 0, 25, 0,
+ 34, 0, 37, 0, 76, 76, 32, 38, 70, 79, 81, 0, 64, 0, 0, 0,
+};
+
+static uint32_t elems_phash(uint32_t val) {
+ val -= 917;
+
+ uint32_t a, b, rsl;
+
+ b = (val & 0x3f);
+ a = ((val << 18) >> 26);
+ rsl = (a ^ elems_tab[b]);
+ return rsl;
+}
+
+static const uint16_t elem_keys[] = {
+ 2091, 1405, 8728, 2777, 7192, 2287, 2581, 2483, 2973, 4441, 3561, 3951,
+ 6403, 4463, 9441, 8726, 2875, 5423, 8730, 7338, 6109, 6207, 6697, 6893,
+ 7229, 8363, 8729, 3952, 8173, 8191, 8725, 8853, 9245, 9343, 1601, 8727,
+ 7481, 7340, 7971, 7775, 6501, 3973, 3659, 3979, 3463, 3980, 1307, 8190,
+ 9010, 8731, 4901, 6599, 3365, 7579, 6795, 9147, 9539, 8069, 6305, 7873,
+ 1209, 1111, 1699, 1503, 7089, 4468, 2189, 4900, 7232, 2385, 6991, 3978,
+ 1993, 4902, 2679, 2762, 1013, 3981, 1230, 1895, 8265, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0};
+static const uint8_t elem_idxs[] = {
+ 11, 5, 70, 19, 51, 13, 16, 15, 21, 33, 24, 26, 43, 34, 79, 68, 20,
+ 39, 72, 54, 40, 41, 46, 48, 52, 66, 71, 27, 62, 64, 67, 74, 77, 78,
+ 7, 69, 56, 55, 60, 58, 44, 28, 25, 30, 23, 31, 4, 63, 75, 73, 37,
+ 45, 22, 57, 47, 76, 80, 61, 42, 59, 2, 0, 8, 6, 50, 35, 12, 36,
+ 53, 14, 49, 29, 10, 38, 17, 18, 1, 32, 3, 9, 65};
+
+grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {
+ if (a == -1 || b == -1) return GRPC_MDNULL;
+ uint32_t k = (uint32_t)(a * 98 + b);
+ uint32_t h = elems_phash(k);
+ return elem_keys[h] == k
+ ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]],
+ GRPC_MDELEM_STORAGE_STATIC)
+ : GRPC_MDNULL;
+}
+grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 30, .length = 14}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 24, .length = 6}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 44, .length = 15}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 44, .length = 15}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 577, .length = 13}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 59, .length = 15}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 74, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 87, .length = 27}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 114, .length = 3}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 117, .length = 5}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 138, .length = 10}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 148, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 161, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 174, .length = 19}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 193, .length = 16}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 209, .length = 16}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 225, .length = 14}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 239, .length = 16}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 255, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 268, .length = 12}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 122, .length = 16}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 268, .length = 12}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 280, .length = 6}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 286, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 313, .length = 6}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 319, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 326, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 337, .length = 20}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 290, .length = 7}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 337, .length = 20}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 297, .length = 12}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 337, .length = 20}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 573, .length = 4}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 337, .length = 20}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 603, .length = 8}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 337, .length = 20}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 611, .length = 16}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 337, .length = 20}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 627, .length = 21}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 337, .length = 20}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 648, .length = 13}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 449, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 290, .length = 7}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 449, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 573, .length = 4}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 449, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 603, .length = 8}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 534, .length = 11}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 0, .length = 1}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 534, .length = 11}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 1, .length = 1}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 534, .length = 11}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 2, .length = 1}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 590, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 661, .length = 8}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 669, .length = 17}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 686, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 699, .length = 8}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 707, .length = 19}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 726, .length = 13}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 739, .length = 11}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 750, .length = 8}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 758, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 762, .length = 8}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 770, .length = 12}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 782, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 330, .length = 3}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 782, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 794, .length = 4}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 782, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 835, .length = 3}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 789, .length = 5}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 891, .length = 1}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 789, .length = 5}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 928, .length = 11}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 798, .length = 18}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 816, .length = 19}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 838, .length = 5}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 843, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 850, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 857, .length = 11}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 868, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 333, .length = 4}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 868, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 594, .length = 4}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 868, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 598, .length = 5}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 875, .length = 6}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 881, .length = 10}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 939, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 3, .length = 3}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 939, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 6, .length = 3}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 939, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 9, .length = 3}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 939, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 12, .length = 3}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 939, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 15, .length = 3}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 939, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 18, .length = 3}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 939, .length = 7}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 21, .length = 3}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 946, .length = 25}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 971, .length = 2}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 973, .length = 8}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 981, .length = 17}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 998, .length = 10}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 1008, .length = 4}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 1012, .length = 3}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+ {{.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 1015, .length = 16}},
+ {.refcount = &g_refcnt,
+ .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}},
+};
const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 29, 26, 30,
28, 32, 27, 31};
diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h
index 28ad6f2961..3d3911de16 100644
--- a/src/core/lib/transport/static_metadata.h
+++ b/src/core/lib/transport/static_metadata.h
@@ -44,375 +44,463 @@
#include "src/core/lib/transport/metadata.h"
-#define GRPC_STATIC_MDSTR_COUNT 93
-extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
+#define GRPC_STATIC_MDSTR_COUNT 98
+extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
/* "0" */
-#define GRPC_MDSTR_0 (&grpc_static_mdstr_table[0])
+#define GRPC_MDSTR_0 (grpc_static_slice_table[0])
/* "1" */
-#define GRPC_MDSTR_1 (&grpc_static_mdstr_table[1])
+#define GRPC_MDSTR_1 (grpc_static_slice_table[1])
/* "2" */
-#define GRPC_MDSTR_2 (&grpc_static_mdstr_table[2])
+#define GRPC_MDSTR_2 (grpc_static_slice_table[2])
/* "200" */
-#define GRPC_MDSTR_200 (&grpc_static_mdstr_table[3])
+#define GRPC_MDSTR_200 (grpc_static_slice_table[3])
/* "204" */
-#define GRPC_MDSTR_204 (&grpc_static_mdstr_table[4])
+#define GRPC_MDSTR_204 (grpc_static_slice_table[4])
/* "206" */
-#define GRPC_MDSTR_206 (&grpc_static_mdstr_table[5])
+#define GRPC_MDSTR_206 (grpc_static_slice_table[5])
/* "304" */
-#define GRPC_MDSTR_304 (&grpc_static_mdstr_table[6])
+#define GRPC_MDSTR_304 (grpc_static_slice_table[6])
/* "400" */
-#define GRPC_MDSTR_400 (&grpc_static_mdstr_table[7])
+#define GRPC_MDSTR_400 (grpc_static_slice_table[7])
/* "404" */
-#define GRPC_MDSTR_404 (&grpc_static_mdstr_table[8])
+#define GRPC_MDSTR_404 (grpc_static_slice_table[8])
/* "500" */
-#define GRPC_MDSTR_500 (&grpc_static_mdstr_table[9])
+#define GRPC_MDSTR_500 (grpc_static_slice_table[9])
/* "accept" */
-#define GRPC_MDSTR_ACCEPT (&grpc_static_mdstr_table[10])
+#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[10])
/* "accept-charset" */
-#define GRPC_MDSTR_ACCEPT_CHARSET (&grpc_static_mdstr_table[11])
+#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[11])
/* "accept-encoding" */
-#define GRPC_MDSTR_ACCEPT_ENCODING (&grpc_static_mdstr_table[12])
+#define GRPC_MDSTR_ACCEPT_ENCODING (grpc_static_slice_table[12])
/* "accept-language" */
-#define GRPC_MDSTR_ACCEPT_LANGUAGE (&grpc_static_mdstr_table[13])
+#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[13])
/* "accept-ranges" */
-#define GRPC_MDSTR_ACCEPT_RANGES (&grpc_static_mdstr_table[14])
+#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[14])
/* "access-control-allow-origin" */
-#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (&grpc_static_mdstr_table[15])
+#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[15])
/* "age" */
-#define GRPC_MDSTR_AGE (&grpc_static_mdstr_table[16])
+#define GRPC_MDSTR_AGE (grpc_static_slice_table[16])
/* "allow" */
-#define GRPC_MDSTR_ALLOW (&grpc_static_mdstr_table[17])
+#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[17])
/* "application/grpc" */
-#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (&grpc_static_mdstr_table[18])
+#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[18])
/* ":authority" */
-#define GRPC_MDSTR_AUTHORITY (&grpc_static_mdstr_table[19])
+#define GRPC_MDSTR_AUTHORITY (grpc_static_slice_table[19])
/* "authorization" */
-#define GRPC_MDSTR_AUTHORIZATION (&grpc_static_mdstr_table[20])
+#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[20])
/* "cache-control" */
-#define GRPC_MDSTR_CACHE_CONTROL (&grpc_static_mdstr_table[21])
+#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[21])
/* "content-disposition" */
-#define GRPC_MDSTR_CONTENT_DISPOSITION (&grpc_static_mdstr_table[22])
+#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[22])
/* "content-encoding" */
-#define GRPC_MDSTR_CONTENT_ENCODING (&grpc_static_mdstr_table[23])
+#define GRPC_MDSTR_CONTENT_ENCODING (grpc_static_slice_table[23])
/* "content-language" */
-#define GRPC_MDSTR_CONTENT_LANGUAGE (&grpc_static_mdstr_table[24])
+#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[24])
/* "content-length" */
-#define GRPC_MDSTR_CONTENT_LENGTH (&grpc_static_mdstr_table[25])
+#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[25])
/* "content-location" */
-#define GRPC_MDSTR_CONTENT_LOCATION (&grpc_static_mdstr_table[26])
+#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[26])
/* "content-range" */
-#define GRPC_MDSTR_CONTENT_RANGE (&grpc_static_mdstr_table[27])
+#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[27])
/* "content-type" */
-#define GRPC_MDSTR_CONTENT_TYPE (&grpc_static_mdstr_table[28])
+#define GRPC_MDSTR_CONTENT_TYPE (grpc_static_slice_table[28])
/* "cookie" */
-#define GRPC_MDSTR_COOKIE (&grpc_static_mdstr_table[29])
+#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[29])
/* "date" */
-#define GRPC_MDSTR_DATE (&grpc_static_mdstr_table[30])
+#define GRPC_MDSTR_DATE (grpc_static_slice_table[30])
/* "deflate" */
-#define GRPC_MDSTR_DEFLATE (&grpc_static_mdstr_table[31])
+#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[31])
/* "deflate,gzip" */
-#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (&grpc_static_mdstr_table[32])
+#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[32])
/* "" */
-#define GRPC_MDSTR_EMPTY (&grpc_static_mdstr_table[33])
+#define GRPC_MDSTR_EMPTY (grpc_static_slice_table[33])
/* "etag" */
-#define GRPC_MDSTR_ETAG (&grpc_static_mdstr_table[34])
+#define GRPC_MDSTR_ETAG (grpc_static_slice_table[34])
/* "expect" */
-#define GRPC_MDSTR_EXPECT (&grpc_static_mdstr_table[35])
+#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[35])
/* "expires" */
-#define GRPC_MDSTR_EXPIRES (&grpc_static_mdstr_table[36])
+#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[36])
/* "from" */
-#define GRPC_MDSTR_FROM (&grpc_static_mdstr_table[37])
+#define GRPC_MDSTR_FROM (grpc_static_slice_table[37])
/* "GET" */
-#define GRPC_MDSTR_GET (&grpc_static_mdstr_table[38])
+#define GRPC_MDSTR_GET (grpc_static_slice_table[38])
/* "grpc" */
-#define GRPC_MDSTR_GRPC (&grpc_static_mdstr_table[39])
+#define GRPC_MDSTR_GRPC (grpc_static_slice_table[39])
/* "grpc-accept-encoding" */
-#define GRPC_MDSTR_GRPC_ACCEPT_ENCODING (&grpc_static_mdstr_table[40])
+#define GRPC_MDSTR_GRPC_ACCEPT_ENCODING (grpc_static_slice_table[40])
+/* "grpc.max_request_message_bytes" */
+#define GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES \
+ (grpc_static_slice_table[41])
+/* "grpc.max_response_message_bytes" */
+#define GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES \
+ (grpc_static_slice_table[42])
+/* "grpc.timeout" */
+#define GRPC_MDSTR_GRPC_DOT_TIMEOUT (grpc_static_slice_table[43])
+/* "grpc.wait_for_ready" */
+#define GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY (grpc_static_slice_table[44])
/* "grpc-encoding" */
-#define GRPC_MDSTR_GRPC_ENCODING (&grpc_static_mdstr_table[41])
+#define GRPC_MDSTR_GRPC_ENCODING (grpc_static_slice_table[45])
/* "grpc-internal-encoding-request" */
-#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (&grpc_static_mdstr_table[42])
+#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (grpc_static_slice_table[46])
/* "grpc-message" */
-#define GRPC_MDSTR_GRPC_MESSAGE (&grpc_static_mdstr_table[43])
+#define GRPC_MDSTR_GRPC_MESSAGE (grpc_static_slice_table[47])
/* "grpc-payload-bin" */
-#define GRPC_MDSTR_GRPC_PAYLOAD_BIN (&grpc_static_mdstr_table[44])
+#define GRPC_MDSTR_GRPC_PAYLOAD_BIN (grpc_static_slice_table[48])
/* "grpc-stats-bin" */
-#define GRPC_MDSTR_GRPC_STATS_BIN (&grpc_static_mdstr_table[45])
+#define GRPC_MDSTR_GRPC_STATS_BIN (grpc_static_slice_table[49])
/* "grpc-status" */
-#define GRPC_MDSTR_GRPC_STATUS (&grpc_static_mdstr_table[46])
+#define GRPC_MDSTR_GRPC_STATUS (grpc_static_slice_table[50])
/* "grpc-timeout" */
-#define GRPC_MDSTR_GRPC_TIMEOUT (&grpc_static_mdstr_table[47])
+#define GRPC_MDSTR_GRPC_TIMEOUT (grpc_static_slice_table[51])
/* "grpc-tracing-bin" */
-#define GRPC_MDSTR_GRPC_TRACING_BIN (&grpc_static_mdstr_table[48])
+#define GRPC_MDSTR_GRPC_TRACING_BIN (grpc_static_slice_table[52])
/* "gzip" */
-#define GRPC_MDSTR_GZIP (&grpc_static_mdstr_table[49])
+#define GRPC_MDSTR_GZIP (grpc_static_slice_table[53])
/* "gzip, deflate" */
-#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (&grpc_static_mdstr_table[50])
+#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[54])
/* "host" */
-#define GRPC_MDSTR_HOST (&grpc_static_mdstr_table[51])
+#define GRPC_MDSTR_HOST (grpc_static_slice_table[55])
/* "http" */
-#define GRPC_MDSTR_HTTP (&grpc_static_mdstr_table[52])
+#define GRPC_MDSTR_HTTP (grpc_static_slice_table[56])
/* "https" */
-#define GRPC_MDSTR_HTTPS (&grpc_static_mdstr_table[53])
+#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[57])
/* "identity" */
-#define GRPC_MDSTR_IDENTITY (&grpc_static_mdstr_table[54])
+#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[58])
/* "identity,deflate" */
-#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (&grpc_static_mdstr_table[55])
+#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[59])
/* "identity,deflate,gzip" */
#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
- (&grpc_static_mdstr_table[56])
+ (grpc_static_slice_table[60])
/* "identity,gzip" */
-#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (&grpc_static_mdstr_table[57])
+#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[61])
/* "if-match" */
-#define GRPC_MDSTR_IF_MATCH (&grpc_static_mdstr_table[58])
+#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[62])
/* "if-modified-since" */
-#define GRPC_MDSTR_IF_MODIFIED_SINCE (&grpc_static_mdstr_table[59])
+#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[63])
/* "if-none-match" */
-#define GRPC_MDSTR_IF_NONE_MATCH (&grpc_static_mdstr_table[60])
+#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[64])
/* "if-range" */
-#define GRPC_MDSTR_IF_RANGE (&grpc_static_mdstr_table[61])
+#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[65])
/* "if-unmodified-since" */
-#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (&grpc_static_mdstr_table[62])
+#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[66])
/* "last-modified" */
-#define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[63])
+#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[67])
/* "lb-cost-bin" */
-#define GRPC_MDSTR_LB_COST_BIN (&grpc_static_mdstr_table[64])
+#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[68])
/* "lb-token" */
-#define GRPC_MDSTR_LB_TOKEN (&grpc_static_mdstr_table[65])
+#define GRPC_MDSTR_LB_TOKEN (grpc_static_slice_table[69])
/* "link" */
-#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[66])
+#define GRPC_MDSTR_LINK (grpc_static_slice_table[70])
/* "location" */
-#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[67])
+#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[71])
/* "max-forwards" */
-#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[68])
+#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[72])
/* ":method" */
-#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[69])
+#define GRPC_MDSTR_METHOD (grpc_static_slice_table[73])
/* ":path" */
-#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[70])
+#define GRPC_MDSTR_PATH (grpc_static_slice_table[74])
/* "POST" */
-#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[71])
+#define GRPC_MDSTR_POST (grpc_static_slice_table[75])
/* "proxy-authenticate" */
-#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[72])
+#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[76])
/* "proxy-authorization" */
-#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[73])
+#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[77])
/* "PUT" */
-#define GRPC_MDSTR_PUT (&grpc_static_mdstr_table[74])
+#define GRPC_MDSTR_PUT (grpc_static_slice_table[78])
/* "range" */
-#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[75])
+#define GRPC_MDSTR_RANGE (grpc_static_slice_table[79])
/* "referer" */
-#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[76])
+#define GRPC_MDSTR_REFERER (grpc_static_slice_table[80])
/* "refresh" */
-#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[77])
+#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[81])
/* "retry-after" */
-#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[78])
+#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[82])
/* ":scheme" */
-#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[79])
+#define GRPC_MDSTR_SCHEME (grpc_static_slice_table[83])
/* "server" */
-#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[80])
+#define GRPC_MDSTR_SERVER (grpc_static_slice_table[84])
/* "set-cookie" */
-#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[81])
+#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[85])
/* "/" */
-#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[82])
+#define GRPC_MDSTR_SLASH (grpc_static_slice_table[86])
+/* "/grpc.lb.v1.LoadBalancer/BalanceLoad" */
+#define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD \
+ (grpc_static_slice_table[87])
/* "/index.html" */
-#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[83])
+#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[88])
/* ":status" */
-#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[84])
+#define GRPC_MDSTR_STATUS (grpc_static_slice_table[89])
/* "strict-transport-security" */
-#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[85])
+#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[90])
/* "te" */
-#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[86])
+#define GRPC_MDSTR_TE (grpc_static_slice_table[91])
/* "trailers" */
-#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[87])
+#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[92])
/* "transfer-encoding" */
-#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[88])
+#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[93])
/* "user-agent" */
-#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[89])
+#define GRPC_MDSTR_USER_AGENT (grpc_static_slice_table[94])
/* "vary" */
-#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[90])
+#define GRPC_MDSTR_VARY (grpc_static_slice_table[95])
/* "via" */
-#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[91])
+#define GRPC_MDSTR_VIA (grpc_static_slice_table[96])
/* "www-authenticate" */
-#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[92])
+#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[97])
+bool grpc_is_static_metadata_string(grpc_slice slice);
+
+int grpc_static_metadata_index(grpc_slice slice);
#define GRPC_STATIC_MDELEM_COUNT 81
-extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
+extern grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];
/* "accept-charset": "" */
-#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY (&grpc_static_mdelem_table[0])
+#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[0], GRPC_MDELEM_STORAGE_STATIC))
/* "accept": "" */
-#define GRPC_MDELEM_ACCEPT_EMPTY (&grpc_static_mdelem_table[1])
+#define GRPC_MDELEM_ACCEPT_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[1], GRPC_MDELEM_STORAGE_STATIC))
/* "accept-encoding": "" */
-#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY (&grpc_static_mdelem_table[2])
+#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[2], GRPC_MDELEM_STORAGE_STATIC))
/* "accept-encoding": "gzip, deflate" */
#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE \
- (&grpc_static_mdelem_table[3])
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[3], GRPC_MDELEM_STORAGE_STATIC))
/* "accept-language": "" */
-#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY (&grpc_static_mdelem_table[4])
+#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[4], GRPC_MDELEM_STORAGE_STATIC))
/* "accept-ranges": "" */
-#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY (&grpc_static_mdelem_table[5])
+#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5], GRPC_MDELEM_STORAGE_STATIC))
/* "access-control-allow-origin": "" */
#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY \
- (&grpc_static_mdelem_table[6])
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6], GRPC_MDELEM_STORAGE_STATIC))
/* "age": "" */
-#define GRPC_MDELEM_AGE_EMPTY (&grpc_static_mdelem_table[7])
+#define GRPC_MDELEM_AGE_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7], GRPC_MDELEM_STORAGE_STATIC))
/* "allow": "" */
-#define GRPC_MDELEM_ALLOW_EMPTY (&grpc_static_mdelem_table[8])
+#define GRPC_MDELEM_ALLOW_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8], GRPC_MDELEM_STORAGE_STATIC))
/* ":authority": "" */
-#define GRPC_MDELEM_AUTHORITY_EMPTY (&grpc_static_mdelem_table[9])
+#define GRPC_MDELEM_AUTHORITY_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9], GRPC_MDELEM_STORAGE_STATIC))
/* "authorization": "" */
-#define GRPC_MDELEM_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[10])
+#define GRPC_MDELEM_AUTHORIZATION_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10], GRPC_MDELEM_STORAGE_STATIC))
/* "cache-control": "" */
-#define GRPC_MDELEM_CACHE_CONTROL_EMPTY (&grpc_static_mdelem_table[11])
+#define GRPC_MDELEM_CACHE_CONTROL_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11], GRPC_MDELEM_STORAGE_STATIC))
/* "content-disposition": "" */
-#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY (&grpc_static_mdelem_table[12])
+#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12], GRPC_MDELEM_STORAGE_STATIC))
/* "content-encoding": "" */
-#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY (&grpc_static_mdelem_table[13])
+#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13], GRPC_MDELEM_STORAGE_STATIC))
/* "content-language": "" */
-#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY (&grpc_static_mdelem_table[14])
+#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14], GRPC_MDELEM_STORAGE_STATIC))
/* "content-length": "" */
-#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY (&grpc_static_mdelem_table[15])
+#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15], GRPC_MDELEM_STORAGE_STATIC))
/* "content-location": "" */
-#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY (&grpc_static_mdelem_table[16])
+#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16], GRPC_MDELEM_STORAGE_STATIC))
/* "content-range": "" */
-#define GRPC_MDELEM_CONTENT_RANGE_EMPTY (&grpc_static_mdelem_table[17])
+#define GRPC_MDELEM_CONTENT_RANGE_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17], GRPC_MDELEM_STORAGE_STATIC))
/* "content-type": "application/grpc" */
#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \
- (&grpc_static_mdelem_table[18])
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18], GRPC_MDELEM_STORAGE_STATIC))
/* "content-type": "" */
-#define GRPC_MDELEM_CONTENT_TYPE_EMPTY (&grpc_static_mdelem_table[19])
+#define GRPC_MDELEM_CONTENT_TYPE_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19], GRPC_MDELEM_STORAGE_STATIC))
/* "cookie": "" */
-#define GRPC_MDELEM_COOKIE_EMPTY (&grpc_static_mdelem_table[20])
+#define GRPC_MDELEM_COOKIE_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20], GRPC_MDELEM_STORAGE_STATIC))
/* "date": "" */
-#define GRPC_MDELEM_DATE_EMPTY (&grpc_static_mdelem_table[21])
+#define GRPC_MDELEM_DATE_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21], GRPC_MDELEM_STORAGE_STATIC))
/* "etag": "" */
-#define GRPC_MDELEM_ETAG_EMPTY (&grpc_static_mdelem_table[22])
+#define GRPC_MDELEM_ETAG_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22], GRPC_MDELEM_STORAGE_STATIC))
/* "expect": "" */
-#define GRPC_MDELEM_EXPECT_EMPTY (&grpc_static_mdelem_table[23])
+#define GRPC_MDELEM_EXPECT_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23], GRPC_MDELEM_STORAGE_STATIC))
/* "expires": "" */
-#define GRPC_MDELEM_EXPIRES_EMPTY (&grpc_static_mdelem_table[24])
+#define GRPC_MDELEM_EXPIRES_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24], GRPC_MDELEM_STORAGE_STATIC))
/* "from": "" */
-#define GRPC_MDELEM_FROM_EMPTY (&grpc_static_mdelem_table[25])
+#define GRPC_MDELEM_FROM_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-accept-encoding": "deflate" */
-#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE (&grpc_static_mdelem_table[26])
+#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-accept-encoding": "deflate,gzip" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP \
- (&grpc_static_mdelem_table[27])
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-accept-encoding": "gzip" */
-#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP (&grpc_static_mdelem_table[28])
+#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-accept-encoding": "identity" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \
- (&grpc_static_mdelem_table[29])
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-accept-encoding": "identity,deflate" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE \
- (&grpc_static_mdelem_table[30])
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-accept-encoding": "identity,deflate,gzip" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
- (&grpc_static_mdelem_table[31])
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-accept-encoding": "identity,gzip" */
#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \
- (&grpc_static_mdelem_table[32])
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-encoding": "deflate" */
-#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE (&grpc_static_mdelem_table[33])
+#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-encoding": "gzip" */
-#define GRPC_MDELEM_GRPC_ENCODING_GZIP (&grpc_static_mdelem_table[34])
+#define GRPC_MDELEM_GRPC_ENCODING_GZIP \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-encoding": "identity" */
-#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY (&grpc_static_mdelem_table[35])
+#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-status": "0" */
-#define GRPC_MDELEM_GRPC_STATUS_0 (&grpc_static_mdelem_table[36])
+#define GRPC_MDELEM_GRPC_STATUS_0 \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-status": "1" */
-#define GRPC_MDELEM_GRPC_STATUS_1 (&grpc_static_mdelem_table[37])
+#define GRPC_MDELEM_GRPC_STATUS_1 \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC))
/* "grpc-status": "2" */
-#define GRPC_MDELEM_GRPC_STATUS_2 (&grpc_static_mdelem_table[38])
+#define GRPC_MDELEM_GRPC_STATUS_2 \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC))
/* "host": "" */
-#define GRPC_MDELEM_HOST_EMPTY (&grpc_static_mdelem_table[39])
+#define GRPC_MDELEM_HOST_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC))
/* "if-match": "" */
-#define GRPC_MDELEM_IF_MATCH_EMPTY (&grpc_static_mdelem_table[40])
+#define GRPC_MDELEM_IF_MATCH_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC))
/* "if-modified-since": "" */
-#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY (&grpc_static_mdelem_table[41])
+#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC))
/* "if-none-match": "" */
-#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY (&grpc_static_mdelem_table[42])
+#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC))
/* "if-range": "" */
-#define GRPC_MDELEM_IF_RANGE_EMPTY (&grpc_static_mdelem_table[43])
+#define GRPC_MDELEM_IF_RANGE_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC))
/* "if-unmodified-since": "" */
-#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY (&grpc_static_mdelem_table[44])
+#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC))
/* "last-modified": "" */
-#define GRPC_MDELEM_LAST_MODIFIED_EMPTY (&grpc_static_mdelem_table[45])
+#define GRPC_MDELEM_LAST_MODIFIED_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC))
/* "lb-cost-bin": "" */
-#define GRPC_MDELEM_LB_COST_BIN_EMPTY (&grpc_static_mdelem_table[46])
+#define GRPC_MDELEM_LB_COST_BIN_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC))
/* "lb-token": "" */
-#define GRPC_MDELEM_LB_TOKEN_EMPTY (&grpc_static_mdelem_table[47])
+#define GRPC_MDELEM_LB_TOKEN_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC))
/* "link": "" */
-#define GRPC_MDELEM_LINK_EMPTY (&grpc_static_mdelem_table[48])
+#define GRPC_MDELEM_LINK_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC))
/* "location": "" */
-#define GRPC_MDELEM_LOCATION_EMPTY (&grpc_static_mdelem_table[49])
+#define GRPC_MDELEM_LOCATION_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC))
/* "max-forwards": "" */
-#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (&grpc_static_mdelem_table[50])
+#define GRPC_MDELEM_MAX_FORWARDS_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC))
/* ":method": "GET" */
-#define GRPC_MDELEM_METHOD_GET (&grpc_static_mdelem_table[51])
+#define GRPC_MDELEM_METHOD_GET \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC))
/* ":method": "POST" */
-#define GRPC_MDELEM_METHOD_POST (&grpc_static_mdelem_table[52])
+#define GRPC_MDELEM_METHOD_POST \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC))
/* ":method": "PUT" */
-#define GRPC_MDELEM_METHOD_PUT (&grpc_static_mdelem_table[53])
+#define GRPC_MDELEM_METHOD_PUT \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC))
/* ":path": "/" */
-#define GRPC_MDELEM_PATH_SLASH (&grpc_static_mdelem_table[54])
+#define GRPC_MDELEM_PATH_SLASH \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC))
/* ":path": "/index.html" */
-#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (&grpc_static_mdelem_table[55])
+#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC))
/* "proxy-authenticate": "" */
-#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[56])
+#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC))
/* "proxy-authorization": "" */
-#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[57])
+#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC))
/* "range": "" */
-#define GRPC_MDELEM_RANGE_EMPTY (&grpc_static_mdelem_table[58])
+#define GRPC_MDELEM_RANGE_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC))
/* "referer": "" */
-#define GRPC_MDELEM_REFERER_EMPTY (&grpc_static_mdelem_table[59])
+#define GRPC_MDELEM_REFERER_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC))
/* "refresh": "" */
-#define GRPC_MDELEM_REFRESH_EMPTY (&grpc_static_mdelem_table[60])
+#define GRPC_MDELEM_REFRESH_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC))
/* "retry-after": "" */
-#define GRPC_MDELEM_RETRY_AFTER_EMPTY (&grpc_static_mdelem_table[61])
+#define GRPC_MDELEM_RETRY_AFTER_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC))
/* ":scheme": "grpc" */
-#define GRPC_MDELEM_SCHEME_GRPC (&grpc_static_mdelem_table[62])
+#define GRPC_MDELEM_SCHEME_GRPC \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC))
/* ":scheme": "http" */
-#define GRPC_MDELEM_SCHEME_HTTP (&grpc_static_mdelem_table[63])
+#define GRPC_MDELEM_SCHEME_HTTP \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC))
/* ":scheme": "https" */
-#define GRPC_MDELEM_SCHEME_HTTPS (&grpc_static_mdelem_table[64])
+#define GRPC_MDELEM_SCHEME_HTTPS \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC))
/* "server": "" */
-#define GRPC_MDELEM_SERVER_EMPTY (&grpc_static_mdelem_table[65])
+#define GRPC_MDELEM_SERVER_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC))
/* "set-cookie": "" */
-#define GRPC_MDELEM_SET_COOKIE_EMPTY (&grpc_static_mdelem_table[66])
+#define GRPC_MDELEM_SET_COOKIE_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC))
/* ":status": "200" */
-#define GRPC_MDELEM_STATUS_200 (&grpc_static_mdelem_table[67])
+#define GRPC_MDELEM_STATUS_200 \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC))
/* ":status": "204" */
-#define GRPC_MDELEM_STATUS_204 (&grpc_static_mdelem_table[68])
+#define GRPC_MDELEM_STATUS_204 \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC))
/* ":status": "206" */
-#define GRPC_MDELEM_STATUS_206 (&grpc_static_mdelem_table[69])
+#define GRPC_MDELEM_STATUS_206 \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC))
/* ":status": "304" */
-#define GRPC_MDELEM_STATUS_304 (&grpc_static_mdelem_table[70])
+#define GRPC_MDELEM_STATUS_304 \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC))
/* ":status": "400" */
-#define GRPC_MDELEM_STATUS_400 (&grpc_static_mdelem_table[71])
+#define GRPC_MDELEM_STATUS_400 \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC))
/* ":status": "404" */
-#define GRPC_MDELEM_STATUS_404 (&grpc_static_mdelem_table[72])
+#define GRPC_MDELEM_STATUS_404 \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC))
/* ":status": "500" */
-#define GRPC_MDELEM_STATUS_500 (&grpc_static_mdelem_table[73])
+#define GRPC_MDELEM_STATUS_500 \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC))
/* "strict-transport-security": "" */
#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \
- (&grpc_static_mdelem_table[74])
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC))
/* "te": "trailers" */
-#define GRPC_MDELEM_TE_TRAILERS (&grpc_static_mdelem_table[75])
+#define GRPC_MDELEM_TE_TRAILERS \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC))
/* "transfer-encoding": "" */
-#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (&grpc_static_mdelem_table[76])
+#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC))
/* "user-agent": "" */
-#define GRPC_MDELEM_USER_AGENT_EMPTY (&grpc_static_mdelem_table[77])
+#define GRPC_MDELEM_USER_AGENT_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC))
/* "vary": "" */
-#define GRPC_MDELEM_VARY_EMPTY (&grpc_static_mdelem_table[78])
+#define GRPC_MDELEM_VARY_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC))
/* "via": "" */
-#define GRPC_MDELEM_VIA_EMPTY (&grpc_static_mdelem_table[79])
+#define GRPC_MDELEM_VIA_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC))
/* "www-authenticate": "" */
-#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[80])
+#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY \
+ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80], GRPC_MDELEM_STORAGE_STATIC))
-extern const uint8_t
- grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2];
-extern const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT];
+grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b);
extern const uint8_t grpc_static_accept_encoding_metadata[8];
-#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \
- (&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]])
+#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \
+ (GRPC_MAKE_MDELEM( \
+ &grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], \
+ GRPC_MDELEM_STORAGE_STATIC))
#endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */
diff --git a/src/core/lib/transport/timeout_encoding.c b/src/core/lib/transport/timeout_encoding.c
index b58ebbd0a8..0d4d7e5a7e 100644
--- a/src/core/lib/transport/timeout_encoding.c
+++ b/src/core/lib/transport/timeout_encoding.c
@@ -131,20 +131,21 @@ void grpc_http2_encode_timeout(gpr_timespec timeout, char *buffer) {
}
}
-static int is_all_whitespace(const char *p) {
- while (*p == ' ') p++;
- return *p == 0;
+static int is_all_whitespace(const char *p, const char *end) {
+ while (p != end && *p == ' ') p++;
+ return p == end;
}
-int grpc_http2_decode_timeout(const char *buffer, gpr_timespec *timeout) {
+int grpc_http2_decode_timeout(grpc_slice text, gpr_timespec *timeout) {
int32_t x = 0;
- const uint8_t *p = (const uint8_t *)buffer;
+ const uint8_t *p = GRPC_SLICE_START_PTR(text);
+ const uint8_t *end = GRPC_SLICE_END_PTR(text);
int have_digit = 0;
/* skip whitespace */
- for (; *p == ' '; p++)
+ for (; p != end && *p == ' '; p++)
;
/* decode numeric part */
- for (; *p >= '0' && *p <= '9'; p++) {
+ for (; p != end && *p >= '0' && *p <= '9'; p++) {
int32_t digit = (int32_t)(*p - (uint8_t)'0');
have_digit = 1;
/* spec allows max. 8 digits, but we allow values up to 1,000,000,000 */
@@ -158,8 +159,9 @@ int grpc_http2_decode_timeout(const char *buffer, gpr_timespec *timeout) {
}
if (!have_digit) return 0;
/* skip whitespace */
- for (; *p == ' '; p++)
+ for (; p != end && *p == ' '; p++)
;
+ if (p == end) return 0;
/* decode unit specifier */
switch (*p) {
case 'n':
@@ -184,5 +186,5 @@ int grpc_http2_decode_timeout(const char *buffer, gpr_timespec *timeout) {
return 0;
}
p++;
- return is_all_whitespace((const char *)p);
+ return is_all_whitespace((const char *)p, (const char *)end);
}
diff --git a/src/core/lib/transport/timeout_encoding.h b/src/core/lib/transport/timeout_encoding.h
index 92f02f6ecd..9b34cec373 100644
--- a/src/core/lib/transport/timeout_encoding.h
+++ b/src/core/lib/transport/timeout_encoding.h
@@ -42,6 +42,6 @@
/* Encode/decode timeouts to the GRPC over HTTP/2 format;
encoding may round up arbitrarily */
void grpc_http2_encode_timeout(gpr_timespec timeout, char *buffer);
-int grpc_http2_decode_timeout(const char *buffer, gpr_timespec *timeout);
+int grpc_http2_decode_timeout(grpc_slice text, gpr_timespec *timeout);
#endif /* GRPC_CORE_LIB_TRANSPORT_TIMEOUT_ENCODING_H */
diff --git a/src/core/lib/transport/transport.c b/src/core/lib/transport/transport.c
index b448126da8..9bc278c133 100644
--- a/src/core/lib/transport/transport.c
+++ b/src/core/lib/transport/transport.c
@@ -40,6 +40,7 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/transport/transport_impl.h"
@@ -212,12 +213,12 @@ void grpc_transport_stream_op_add_cancellation(grpc_transport_stream_op *op,
}
void grpc_transport_stream_op_add_cancellation_with_message(
- grpc_transport_stream_op *op, grpc_status_code status,
- grpc_slice *optional_message) {
+ grpc_exec_ctx *exec_ctx, grpc_transport_stream_op *op,
+ grpc_status_code status, grpc_slice *optional_message) {
GPR_ASSERT(status != GRPC_STATUS_OK);
if (op->cancel_error != GRPC_ERROR_NONE) {
if (optional_message) {
- grpc_slice_unref(*optional_message);
+ grpc_slice_unref_internal(exec_ctx, *optional_message);
}
return;
}
@@ -227,7 +228,7 @@ void grpc_transport_stream_op_add_cancellation_with_message(
error = grpc_error_set_str(GRPC_ERROR_CREATE(msg),
GRPC_ERROR_STR_GRPC_MESSAGE, msg);
gpr_free(msg);
- grpc_slice_unref(*optional_message);
+ grpc_slice_unref_internal(exec_ctx, *optional_message);
} else {
error = GRPC_ERROR_CREATE("Call cancelled");
}
@@ -235,14 +236,15 @@ void grpc_transport_stream_op_add_cancellation_with_message(
add_error(op, &op->cancel_error, error);
}
-void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op,
+void grpc_transport_stream_op_add_close(grpc_exec_ctx *exec_ctx,
+ grpc_transport_stream_op *op,
grpc_status_code status,
grpc_slice *optional_message) {
GPR_ASSERT(status != GRPC_STATUS_OK);
if (op->cancel_error != GRPC_ERROR_NONE ||
op->close_error != GRPC_ERROR_NONE) {
if (optional_message) {
- grpc_slice_unref(*optional_message);
+ grpc_slice_unref_internal(exec_ctx, *optional_message);
}
return;
}
@@ -252,7 +254,7 @@ void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op,
error = grpc_error_set_str(GRPC_ERROR_CREATE(msg),
GRPC_ERROR_STR_GRPC_MESSAGE, msg);
gpr_free(msg);
- grpc_slice_unref(*optional_message);
+ grpc_slice_unref_internal(exec_ctx, *optional_message);
} else {
error = GRPC_ERROR_CREATE("Call force closed");
}
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index 96c26749c8..d1281830aa 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -249,10 +249,11 @@ void grpc_transport_stream_op_add_cancellation(grpc_transport_stream_op *op,
grpc_status_code status);
void grpc_transport_stream_op_add_cancellation_with_message(
- grpc_transport_stream_op *op, grpc_status_code status,
- grpc_slice *optional_message);
+ grpc_exec_ctx *exec_ctx, grpc_transport_stream_op *op,
+ grpc_status_code status, grpc_slice *optional_message);
-void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op,
+void grpc_transport_stream_op_add_close(grpc_exec_ctx *exec_ctx,
+ grpc_transport_stream_op *op,
grpc_status_code status,
grpc_slice *optional_message);
diff --git a/src/core/lib/transport/transport_op_string.c b/src/core/lib/transport/transport_op_string.c
index 58d6ad508e..b36e4f22d0 100644
--- a/src/core/lib/transport/transport_op_string.c
+++ b/src/core/lib/transport/transport_op_string.c
@@ -47,14 +47,14 @@
/* These routines are here to facilitate debugging - they produce string
representations of various transport data structures */
-static void put_metadata(gpr_strvec *b, grpc_mdelem *md) {
+static void put_metadata(gpr_strvec *b, grpc_mdelem md) {
gpr_strvec_add(b, gpr_strdup("key="));
gpr_strvec_add(
- b, grpc_dump_slice(md->key->slice, GPR_DUMP_HEX | GPR_DUMP_ASCII));
+ b, grpc_dump_slice(GRPC_MDKEY(md), GPR_DUMP_HEX | GPR_DUMP_ASCII));
gpr_strvec_add(b, gpr_strdup(" value="));
gpr_strvec_add(
- b, grpc_dump_slice(md->value->slice, GPR_DUMP_HEX | GPR_DUMP_ASCII));
+ b, grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX | GPR_DUMP_ASCII));
}
static void put_metadata_list(gpr_strvec *b, grpc_metadata_batch md) {
diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc
index 0301b5b8ec..1fdd106130 100644
--- a/src/cpp/common/channel_arguments.cc
+++ b/src/cpp/common/channel_arguments.cc
@@ -38,8 +38,11 @@
#include <grpc++/resource_quota.h>
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/log.h>
+extern "C" {
#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/socket_mutator.h"
+}
namespace grpc {
ChannelArguments::ChannelArguments() {
@@ -94,13 +97,15 @@ void ChannelArguments::SetSocketMutator(grpc_socket_mutator* mutator) {
}
grpc_arg mutator_arg = grpc_socket_mutator_to_arg(mutator);
bool replaced = false;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
for (auto it = args_.begin(); it != args_.end(); ++it) {
if (it->type == mutator_arg.type &&
grpc::string(it->key) == grpc::string(mutator_arg.key)) {
- it->value.pointer.vtable->destroy(it->value.pointer.p);
+ it->value.pointer.vtable->destroy(&exec_ctx, it->value.pointer.p);
it->value.pointer = mutator_arg.value.pointer;
}
}
+ grpc_exec_ctx_finish(&exec_ctx);
if (!replaced) {
args_.push_back(mutator_arg);
}
diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc
index ad2c0f2295..c0dc9dd63e 100644
--- a/src/cpp/common/channel_filter.cc
+++ b/src/cpp/common/channel_filter.cc
@@ -40,11 +40,12 @@ namespace grpc {
// MetadataBatch
-grpc_linked_mdelem *MetadataBatch::AddMetadata(const string &key,
+grpc_linked_mdelem *MetadataBatch::AddMetadata(grpc_exec_ctx *exec_ctx,
+ const string &key,
const string &value) {
grpc_linked_mdelem *storage = new grpc_linked_mdelem;
memset(storage, 0, sizeof(grpc_linked_mdelem));
- storage->md = grpc_mdelem_from_strings(key.c_str(), value.c_str());
+ storage->md = grpc_mdelem_from_strings(exec_ctx, key.c_str(), value.c_str());
grpc_metadata_batch_link_head(batch_, storage);
return storage;
}
@@ -89,7 +90,8 @@ std::vector<FilterRecord> *channel_filters;
namespace {
-bool MaybeAddFilter(grpc_channel_stack_builder *builder, void *arg) {
+bool MaybeAddFilter(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder, void *arg) {
const FilterRecord &filter = *(FilterRecord *)arg;
if (filter.include_filter) {
const grpc_channel_args *args =
diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h
index e420efc71c..cac0a19e5e 100644
--- a/src/cpp/common/channel_filter.h
+++ b/src/cpp/common/channel_filter.h
@@ -70,13 +70,14 @@ class MetadataBatch {
/// Adds metadata and returns the newly allocated storage.
/// The caller takes ownership of the result, which must exist for the
/// lifetime of the gRPC call.
- grpc_linked_mdelem *AddMetadata(const string &key, const string &value);
+ grpc_linked_mdelem *AddMetadata(grpc_exec_ctx *exec_ctx, const string &key,
+ const string &value);
class const_iterator : public std::iterator<std::bidirectional_iterator_tag,
const grpc_mdelem> {
public:
const grpc_mdelem &operator*() const { return *elem_->md; }
- const grpc_mdelem *operator->() const { return elem_->md; }
+ const grpc_mdelem operator->() const { return elem_->md; }
const_iterator &operator++() {
elem_ = elem_->next;
diff --git a/src/cpp/util/slice_cc.cc b/src/cpp/util/slice_cc.cc
index c05f1cf124..6efb68e123 100644
--- a/src/cpp/util/slice_cc.cc
+++ b/src/cpp/util/slice_cc.cc
@@ -35,7 +35,7 @@
namespace grpc {
-Slice::Slice() : slice_(gpr_empty_slice()) {}
+Slice::Slice() : slice_(grpc_empty_slice()) {}
Slice::~Slice() { grpc_slice_unref(slice_); }
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index bfd706a78b..e25c14c2d3 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -157,6 +157,8 @@ CORE_SOURCE_FILES = [
'src/core/lib/slice/percent_encoding.c',
'src/core/lib/slice/slice.c',
'src/core/lib/slice/slice_buffer.c',
+ 'src/core/lib/slice/slice_hash_table.c',
+ 'src/core/lib/slice/slice_intern.c',
'src/core/lib/slice/slice_string_helpers.c',
'src/core/lib/surface/alarm.c',
'src/core/lib/surface/api_trace.c',
@@ -178,7 +180,6 @@ CORE_SOURCE_FILES = [
'src/core/lib/surface/version.c',
'src/core/lib/transport/byte_stream.c',
'src/core/lib/transport/connectivity_state.c',
- 'src/core/lib/transport/mdstr_hash_table.c',
'src/core/lib/transport/metadata.c',
'src/core/lib/transport/metadata_batch.c',
'src/core/lib/transport/pid_controller.c',
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index 6c36df9113..6c3a15c07f 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -179,17 +179,27 @@ grpc_slice_new_type grpc_slice_new_import;
grpc_slice_new_with_user_data_type grpc_slice_new_with_user_data_import;
grpc_slice_new_with_len_type grpc_slice_new_with_len_import;
grpc_slice_malloc_type grpc_slice_malloc_import;
+grpc_slice_intern_type grpc_slice_intern_import;
grpc_slice_from_copied_string_type grpc_slice_from_copied_string_import;
grpc_slice_from_copied_buffer_type grpc_slice_from_copied_buffer_import;
grpc_slice_from_static_string_type grpc_slice_from_static_string_import;
+grpc_slice_from_static_buffer_type grpc_slice_from_static_buffer_import;
grpc_slice_sub_type grpc_slice_sub_import;
grpc_slice_sub_no_ref_type grpc_slice_sub_no_ref_import;
grpc_slice_split_tail_type grpc_slice_split_tail_import;
grpc_slice_split_head_type grpc_slice_split_head_import;
-gpr_empty_slice_type gpr_empty_slice_import;
+grpc_empty_slice_type grpc_empty_slice_import;
+grpc_slice_default_hash_impl_type grpc_slice_default_hash_impl_import;
grpc_slice_cmp_type grpc_slice_cmp_import;
grpc_slice_str_cmp_type grpc_slice_str_cmp_import;
+grpc_slice_buf_cmp_type grpc_slice_buf_cmp_import;
+grpc_slice_buf_start_eq_type grpc_slice_buf_start_eq_import;
+grpc_slice_rchr_type grpc_slice_rchr_import;
+grpc_slice_chr_type grpc_slice_chr_import;
+grpc_slice_slice_type grpc_slice_slice_import;
+grpc_slice_hash_type grpc_slice_hash_import;
grpc_slice_is_equivalent_type grpc_slice_is_equivalent_import;
+grpc_slice_dup_type grpc_slice_dup_import;
grpc_slice_buffer_init_type grpc_slice_buffer_init_import;
grpc_slice_buffer_destroy_type grpc_slice_buffer_destroy_import;
grpc_slice_buffer_add_type grpc_slice_buffer_add_import;
@@ -455,17 +465,27 @@ void grpc_rb_load_imports(HMODULE library) {
grpc_slice_new_with_user_data_import = (grpc_slice_new_with_user_data_type) GetProcAddress(library, "grpc_slice_new_with_user_data");
grpc_slice_new_with_len_import = (grpc_slice_new_with_len_type) GetProcAddress(library, "grpc_slice_new_with_len");
grpc_slice_malloc_import = (grpc_slice_malloc_type) GetProcAddress(library, "grpc_slice_malloc");
+ grpc_slice_intern_import = (grpc_slice_intern_type) GetProcAddress(library, "grpc_slice_intern");
grpc_slice_from_copied_string_import = (grpc_slice_from_copied_string_type) GetProcAddress(library, "grpc_slice_from_copied_string");
grpc_slice_from_copied_buffer_import = (grpc_slice_from_copied_buffer_type) GetProcAddress(library, "grpc_slice_from_copied_buffer");
grpc_slice_from_static_string_import = (grpc_slice_from_static_string_type) GetProcAddress(library, "grpc_slice_from_static_string");
+ grpc_slice_from_static_buffer_import = (grpc_slice_from_static_buffer_type) GetProcAddress(library, "grpc_slice_from_static_buffer");
grpc_slice_sub_import = (grpc_slice_sub_type) GetProcAddress(library, "grpc_slice_sub");
grpc_slice_sub_no_ref_import = (grpc_slice_sub_no_ref_type) GetProcAddress(library, "grpc_slice_sub_no_ref");
grpc_slice_split_tail_import = (grpc_slice_split_tail_type) GetProcAddress(library, "grpc_slice_split_tail");
grpc_slice_split_head_import = (grpc_slice_split_head_type) GetProcAddress(library, "grpc_slice_split_head");
- gpr_empty_slice_import = (gpr_empty_slice_type) GetProcAddress(library, "gpr_empty_slice");
+ grpc_empty_slice_import = (grpc_empty_slice_type) GetProcAddress(library, "grpc_empty_slice");
+ grpc_slice_default_hash_impl_import = (grpc_slice_default_hash_impl_type) GetProcAddress(library, "grpc_slice_default_hash_impl");
grpc_slice_cmp_import = (grpc_slice_cmp_type) GetProcAddress(library, "grpc_slice_cmp");
grpc_slice_str_cmp_import = (grpc_slice_str_cmp_type) GetProcAddress(library, "grpc_slice_str_cmp");
+ grpc_slice_buf_cmp_import = (grpc_slice_buf_cmp_type) GetProcAddress(library, "grpc_slice_buf_cmp");
+ grpc_slice_buf_start_eq_import = (grpc_slice_buf_start_eq_type) GetProcAddress(library, "grpc_slice_buf_start_eq");
+ grpc_slice_rchr_import = (grpc_slice_rchr_type) GetProcAddress(library, "grpc_slice_rchr");
+ grpc_slice_chr_import = (grpc_slice_chr_type) GetProcAddress(library, "grpc_slice_chr");
+ grpc_slice_slice_import = (grpc_slice_slice_type) GetProcAddress(library, "grpc_slice_slice");
+ grpc_slice_hash_import = (grpc_slice_hash_type) GetProcAddress(library, "grpc_slice_hash");
grpc_slice_is_equivalent_import = (grpc_slice_is_equivalent_type) GetProcAddress(library, "grpc_slice_is_equivalent");
+ grpc_slice_dup_import = (grpc_slice_dup_type) GetProcAddress(library, "grpc_slice_dup");
grpc_slice_buffer_init_import = (grpc_slice_buffer_init_type) GetProcAddress(library, "grpc_slice_buffer_init");
grpc_slice_buffer_destroy_import = (grpc_slice_buffer_destroy_type) GetProcAddress(library, "grpc_slice_buffer_destroy");
grpc_slice_buffer_add_import = (grpc_slice_buffer_add_type) GetProcAddress(library, "grpc_slice_buffer_add");
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index 5745686adf..799cfaabfe 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -176,7 +176,7 @@ extern census_resource_id_type census_resource_id_import;
typedef void(*census_record_values_type)(census_context *context, census_value *values, size_t nvalues);
extern census_record_values_type census_record_values_import;
#define census_record_values census_record_values_import
-typedef int(*grpc_compression_algorithm_parse_type)(const char *name, size_t name_length, grpc_compression_algorithm *algorithm);
+typedef int(*grpc_compression_algorithm_parse_type)(grpc_slice value, grpc_compression_algorithm *algorithm);
extern grpc_compression_algorithm_parse_type grpc_compression_algorithm_parse_import;
#define grpc_compression_algorithm_parse grpc_compression_algorithm_parse_import
typedef int(*grpc_compression_algorithm_name_type)(grpc_compression_algorithm algorithm, char **name);
@@ -254,7 +254,7 @@ extern grpc_channel_check_connectivity_state_type grpc_channel_check_connectivit
typedef void(*grpc_channel_watch_connectivity_state_type)(grpc_channel *channel, grpc_connectivity_state last_observed_state, gpr_timespec deadline, grpc_completion_queue *cq, void *tag);
extern grpc_channel_watch_connectivity_state_type grpc_channel_watch_connectivity_state_import;
#define grpc_channel_watch_connectivity_state grpc_channel_watch_connectivity_state_import
-typedef grpc_call *(*grpc_channel_create_call_type)(grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, const char *method, const char *host, gpr_timespec deadline, void *reserved);
+typedef grpc_call *(*grpc_channel_create_call_type)(grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, grpc_slice method, const grpc_slice *host, gpr_timespec deadline, void *reserved);
extern grpc_channel_create_call_type grpc_channel_create_call_import;
#define grpc_channel_create_call grpc_channel_create_call_import
typedef void(*grpc_channel_ping_type)(grpc_channel *channel, grpc_completion_queue *cq, void *tag, void *reserved);
@@ -338,13 +338,13 @@ extern grpc_server_destroy_type grpc_server_destroy_import;
typedef int(*grpc_tracer_set_enabled_type)(const char *name, int enabled);
extern grpc_tracer_set_enabled_type grpc_tracer_set_enabled_import;
#define grpc_tracer_set_enabled grpc_tracer_set_enabled_import
-typedef int(*grpc_header_key_is_legal_type)(const char *key, size_t length);
+typedef int(*grpc_header_key_is_legal_type)(grpc_slice slice);
extern grpc_header_key_is_legal_type grpc_header_key_is_legal_import;
#define grpc_header_key_is_legal grpc_header_key_is_legal_import
-typedef int(*grpc_header_nonbin_value_is_legal_type)(const char *value, size_t length);
+typedef int(*grpc_header_nonbin_value_is_legal_type)(grpc_slice slice);
extern grpc_header_nonbin_value_is_legal_type grpc_header_nonbin_value_is_legal_import;
#define grpc_header_nonbin_value_is_legal grpc_header_nonbin_value_is_legal_import
-typedef int(*grpc_is_binary_header_type)(const char *key, size_t length);
+typedef int(*grpc_is_binary_header_type)(grpc_slice slice);
extern grpc_is_binary_header_type grpc_is_binary_header_import;
#define grpc_is_binary_header grpc_is_binary_header_import
typedef const char *(*grpc_call_error_to_string_type)(grpc_call_error error);
@@ -488,6 +488,9 @@ extern grpc_slice_new_with_len_type grpc_slice_new_with_len_import;
typedef grpc_slice(*grpc_slice_malloc_type)(size_t length);
extern grpc_slice_malloc_type grpc_slice_malloc_import;
#define grpc_slice_malloc grpc_slice_malloc_import
+typedef grpc_slice(*grpc_slice_intern_type)(grpc_slice slice);
+extern grpc_slice_intern_type grpc_slice_intern_import;
+#define grpc_slice_intern grpc_slice_intern_import
typedef grpc_slice(*grpc_slice_from_copied_string_type)(const char *source);
extern grpc_slice_from_copied_string_type grpc_slice_from_copied_string_import;
#define grpc_slice_from_copied_string grpc_slice_from_copied_string_import
@@ -497,6 +500,9 @@ extern grpc_slice_from_copied_buffer_type grpc_slice_from_copied_buffer_import;
typedef grpc_slice(*grpc_slice_from_static_string_type)(const char *source);
extern grpc_slice_from_static_string_type grpc_slice_from_static_string_import;
#define grpc_slice_from_static_string grpc_slice_from_static_string_import
+typedef grpc_slice(*grpc_slice_from_static_buffer_type)(const void *source, size_t len);
+extern grpc_slice_from_static_buffer_type grpc_slice_from_static_buffer_import;
+#define grpc_slice_from_static_buffer grpc_slice_from_static_buffer_import
typedef grpc_slice(*grpc_slice_sub_type)(grpc_slice s, size_t begin, size_t end);
extern grpc_slice_sub_type grpc_slice_sub_import;
#define grpc_slice_sub grpc_slice_sub_import
@@ -509,18 +515,42 @@ extern grpc_slice_split_tail_type grpc_slice_split_tail_import;
typedef grpc_slice(*grpc_slice_split_head_type)(grpc_slice *s, size_t split);
extern grpc_slice_split_head_type grpc_slice_split_head_import;
#define grpc_slice_split_head grpc_slice_split_head_import
-typedef grpc_slice(*gpr_empty_slice_type)(void);
-extern gpr_empty_slice_type gpr_empty_slice_import;
-#define gpr_empty_slice gpr_empty_slice_import
+typedef grpc_slice(*grpc_empty_slice_type)(void);
+extern grpc_empty_slice_type grpc_empty_slice_import;
+#define grpc_empty_slice grpc_empty_slice_import
+typedef uint32_t(*grpc_slice_default_hash_impl_type)(void *, grpc_slice s);
+extern grpc_slice_default_hash_impl_type grpc_slice_default_hash_impl_import;
+#define grpc_slice_default_hash_impl grpc_slice_default_hash_impl_import
typedef int(*grpc_slice_cmp_type)(grpc_slice a, grpc_slice b);
extern grpc_slice_cmp_type grpc_slice_cmp_import;
#define grpc_slice_cmp grpc_slice_cmp_import
typedef int(*grpc_slice_str_cmp_type)(grpc_slice a, const char *b);
extern grpc_slice_str_cmp_type grpc_slice_str_cmp_import;
#define grpc_slice_str_cmp grpc_slice_str_cmp_import
+typedef int(*grpc_slice_buf_cmp_type)(grpc_slice a, const void *b, size_t blen);
+extern grpc_slice_buf_cmp_type grpc_slice_buf_cmp_import;
+#define grpc_slice_buf_cmp grpc_slice_buf_cmp_import
+typedef int(*grpc_slice_buf_start_eq_type)(grpc_slice a, const void *b, size_t blen);
+extern grpc_slice_buf_start_eq_type grpc_slice_buf_start_eq_import;
+#define grpc_slice_buf_start_eq grpc_slice_buf_start_eq_import
+typedef int(*grpc_slice_rchr_type)(grpc_slice s, char c);
+extern grpc_slice_rchr_type grpc_slice_rchr_import;
+#define grpc_slice_rchr grpc_slice_rchr_import
+typedef int(*grpc_slice_chr_type)(grpc_slice s, char c);
+extern grpc_slice_chr_type grpc_slice_chr_import;
+#define grpc_slice_chr grpc_slice_chr_import
+typedef int(*grpc_slice_slice_type)(grpc_slice haystack, grpc_slice needle);
+extern grpc_slice_slice_type grpc_slice_slice_import;
+#define grpc_slice_slice grpc_slice_slice_import
+typedef uint32_t(*grpc_slice_hash_type)(grpc_slice s);
+extern grpc_slice_hash_type grpc_slice_hash_import;
+#define grpc_slice_hash grpc_slice_hash_import
typedef int(*grpc_slice_is_equivalent_type)(grpc_slice a, grpc_slice b);
extern grpc_slice_is_equivalent_type grpc_slice_is_equivalent_import;
#define grpc_slice_is_equivalent grpc_slice_is_equivalent_import
+typedef grpc_slice(*grpc_slice_dup_type)(grpc_slice a);
+extern grpc_slice_dup_type grpc_slice_dup_import;
+#define grpc_slice_dup grpc_slice_dup_import
typedef void(*grpc_slice_buffer_init_type)(grpc_slice_buffer *sb);
extern grpc_slice_buffer_init_type grpc_slice_buffer_init_import;
#define grpc_slice_buffer_init grpc_slice_buffer_init_import
diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c
index 07fcd995d7..1ce3a49097 100644
--- a/test/core/bad_client/bad_client.c
+++ b/test/core/bad_client/bad_client.c
@@ -33,15 +33,18 @@
#include "test/core/bad_client/bad_client.h"
+#include <stdio.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
-#include <stdio.h>
+
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/http_server_filter.h"
#include "src/core/lib/iomgr/endpoint_pair.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/support/murmur_hash.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/surface/completion_queue.h"
@@ -117,7 +120,7 @@ void grpc_run_bad_client_test(
grpc_resource_quota *resource_quota =
grpc_resource_quota_create("bad_client_test");
sfd = grpc_iomgr_create_endpoint_pair("fixture", resource_quota, 65536);
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
/* Create server, completion events */
a.server = grpc_server_create(NULL, NULL);
@@ -181,7 +184,7 @@ void grpc_run_bad_client_test(
grpc_exec_ctx_finish(&exec_ctx);
GPR_ASSERT(
gpr_event_wait(&args.read_done, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)));
- grpc_slice_buffer_destroy(&args.incoming);
+ grpc_slice_buffer_destroy_internal(&exec_ctx, &args.incoming);
}
// Shutdown.
grpc_endpoint_shutdown(&exec_ctx, sfd.client);
@@ -194,7 +197,7 @@ void grpc_run_bad_client_test(
.type == GRPC_OP_COMPLETE);
grpc_server_destroy(a.server);
grpc_completion_queue_destroy(a.cq);
- grpc_slice_buffer_destroy(&outgoing);
+ grpc_slice_buffer_destroy_internal(&exec_ctx, &outgoing);
grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
diff --git a/test/core/bad_client/tests/large_metadata.c b/test/core/bad_client/tests/large_metadata.c
index 9c804e78c1..f9255be1dc 100644
--- a/test/core/bad_client/tests/large_metadata.c
+++ b/test/core/bad_client/tests/large_metadata.c
@@ -126,8 +126,8 @@ static void server_verifier(grpc_server *server, grpc_completion_queue *cq,
CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
cq_verify(cqv);
- GPR_ASSERT(0 == strcmp(call_details.host, "localhost"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo/bar"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.host, "localhost"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo/bar"));
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
@@ -153,16 +153,14 @@ static void server_verifier_sends_too_much_metadata(grpc_server *server,
CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
cq_verify(cqv);
- GPR_ASSERT(0 == strcmp(call_details.host, "localhost"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo/bar"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.host, "localhost"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo/bar"));
const size_t metadata_value_size = 16 * 1024;
grpc_metadata meta;
- meta.key = "key";
- meta.value = gpr_malloc(metadata_value_size + 1);
- memset((char *)meta.value, 'a', metadata_value_size);
- ((char *)meta.value)[metadata_value_size] = 0;
- meta.value_length = metadata_value_size;
+ meta.key = grpc_slice_from_static_string("key");
+ meta.value = grpc_slice_malloc(metadata_value_size);
+ memset(GRPC_SLICE_START_PTR(meta.value), 'a', metadata_value_size);
grpc_op op;
memset(&op, 0, sizeof(op));
@@ -176,7 +174,7 @@ static void server_verifier_sends_too_much_metadata(grpc_server *server,
CQ_EXPECT_COMPLETION(cqv, tag(102), 0); // Operation fails.
cq_verify(cqv);
- gpr_free((char *)meta.value);
+ grpc_slice_unref(meta.value);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
grpc_call_destroy(s);
diff --git a/test/core/bad_client/tests/simple_request.c b/test/core/bad_client/tests/simple_request.c
index c08aa40a0a..db31ba6fb3 100644
--- a/test/core/bad_client/tests/simple_request.c
+++ b/test/core/bad_client/tests/simple_request.c
@@ -117,8 +117,8 @@ static void verifier(grpc_server *server, grpc_completion_queue *cq,
CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
cq_verify(cqv);
- GPR_ASSERT(0 == strcmp(call_details.host, "localhost"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo/bar"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.host, "localhost"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo/bar"));
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
diff --git a/test/core/bad_ssl/bad_ssl_test.c b/test/core/bad_ssl/bad_ssl_test.c
index f8a9fe6cac..9cce77e71a 100644
--- a/test/core/bad_ssl/bad_ssl_test.c
+++ b/test/core/bad_ssl/bad_ssl_test.c
@@ -57,8 +57,7 @@ static void run_test(const char *target, size_t nops) {
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
grpc_status_code status;
grpc_call_error error;
gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5);
@@ -80,9 +79,10 @@ static void run_test(const char *target, size_t nops) {
grpc_metadata_array_init(&trailing_metadata_recv);
channel = grpc_secure_channel_create(ssl_creds, target, &args, NULL);
+ grpc_slice host = grpc_slice_from_static_string("foo.test.google.fr:1234");
c = grpc_channel_create_call(channel, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
- "/foo", "foo.test.google.fr:1234", deadline,
- NULL);
+ grpc_slice_from_static_string("/foo"), &host,
+ deadline, NULL);
memset(ops, 0, sizeof(ops));
op = ops;
@@ -95,7 +95,6 @@ static void run_test(const char *target, size_t nops) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -117,7 +116,7 @@ static void run_test(const char *target, size_t nops) {
GPR_ASSERT(status != GRPC_STATUS_OK);
grpc_call_destroy(c);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
diff --git a/test/core/channel/channel_args_test.c b/test/core/channel/channel_args_test.c
index d3eb969f09..b2c41652a4 100644
--- a/test/core/channel/channel_args_test.c
+++ b/test/core/channel/channel_args_test.c
@@ -37,10 +37,12 @@
#include <grpc/support/useful.h>
#include "src/core/lib/channel/channel_args.h"
-
+#include "src/core/lib/iomgr/exec_ctx.h"
#include "test/core/util/test_config.h"
static void test_create(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
grpc_arg arg_int;
grpc_arg arg_string;
grpc_arg to_add[2];
@@ -68,10 +70,12 @@ static void test_create(void) {
GPR_ASSERT(strcmp(ch_args->args[1].value.string, arg_string.value.string) ==
0);
- grpc_channel_args_destroy(ch_args);
+ grpc_channel_args_destroy(&exec_ctx, ch_args);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_set_compression_algorithm(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_channel_args *ch_args;
ch_args =
@@ -81,10 +85,12 @@ static void test_set_compression_algorithm(void) {
GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM) == 0);
GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_INTEGER);
- grpc_channel_args_destroy(ch_args);
+ grpc_channel_args_destroy(&exec_ctx, ch_args);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_compression_algorithm_states(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_channel_args *ch_args, *ch_args_wo_gzip, *ch_args_wo_gzip_deflate;
unsigned states_bitset;
size_t i;
@@ -100,10 +106,10 @@ static void test_compression_algorithm_states(void) {
/* disable gzip and deflate */
ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state(
- &ch_args, GRPC_COMPRESS_GZIP, 0);
+ &exec_ctx, &ch_args, GRPC_COMPRESS_GZIP, 0);
GPR_ASSERT(ch_args == ch_args_wo_gzip);
ch_args_wo_gzip_deflate = grpc_channel_args_compression_algorithm_set_state(
- &ch_args_wo_gzip, GRPC_COMPRESS_DEFLATE, 0);
+ &exec_ctx, &ch_args_wo_gzip, GRPC_COMPRESS_DEFLATE, 0);
GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate);
states_bitset = (unsigned)grpc_channel_args_compression_algorithm_get_states(
@@ -118,7 +124,7 @@ static void test_compression_algorithm_states(void) {
/* re-enabled gzip only */
ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state(
- &ch_args_wo_gzip_deflate, GRPC_COMPRESS_GZIP, 1);
+ &exec_ctx, &ch_args_wo_gzip_deflate, GRPC_COMPRESS_GZIP, 1);
GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate);
states_bitset = (unsigned)grpc_channel_args_compression_algorithm_get_states(
@@ -131,7 +137,8 @@ static void test_compression_algorithm_states(void) {
}
}
- grpc_channel_args_destroy(ch_args);
+ grpc_channel_args_destroy(&exec_ctx, ch_args);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_set_socket_mutator(void) {
@@ -144,7 +151,11 @@ static void test_set_socket_mutator(void) {
GPR_ASSERT(strcmp(ch_args->args[0].key, GRPC_ARG_SOCKET_MUTATOR) == 0);
GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_POINTER);
- grpc_channel_args_destroy(ch_args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, ch_args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
}
int main(int argc, char **argv) {
diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c
index 0840820cca..ab5a50304d 100644
--- a/test/core/channel/channel_stack_test.c
+++ b/test/core/channel/channel_stack_test.c
@@ -39,6 +39,7 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+#include "src/core/lib/slice/slice_internal.h"
#include "test/core/util/test_config.h"
static void channel_init_func(grpc_exec_ctx *exec_ctx,
@@ -119,7 +120,7 @@ static void test_create_channel_stack(void) {
int *channel_data;
int *call_data;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- grpc_mdstr *path = grpc_mdstr_from_string("/service/method");
+ grpc_slice path = grpc_slice_from_static_string("/service/method");
arg.type = GRPC_ARG_INTEGER;
arg.key = "test_key";
@@ -156,8 +157,8 @@ static void test_create_channel_stack(void) {
GRPC_CHANNEL_STACK_UNREF(&exec_ctx, channel_stack, "done");
+ grpc_slice_unref_internal(&exec_ctx, path);
grpc_exec_ctx_finish(&exec_ctx);
- GRPC_MDSTR_UNREF(path);
}
int main(int argc, char **argv) {
diff --git a/test/core/client_channel/lb_policies_test.c b/test/core/client_channel/lb_policies_test.c
index 95595d7c51..4b4c359d6f 100644
--- a/test/core/client_channel/lb_policies_test.c
+++ b/test/core/client_channel/lb_policies_test.c
@@ -155,8 +155,7 @@ static void kill_server(const servers_fixture *f, size_t i) {
typedef struct request_data {
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
- char *details;
- size_t details_capacity;
+ grpc_slice details;
grpc_status_code status;
grpc_call_details *call_details;
} request_data;
@@ -268,8 +267,6 @@ static request_sequences perform_request(servers_fixture *f,
for (iter_num = 0; iter_num < spec->num_iters; iter_num++) {
cq_verifier *cqv = cq_verifier_create(f->cq);
- rdata->details = NULL;
- rdata->details_capacity = 0;
was_cancelled = 2;
for (i = 0; i < f->num_servers; i++) {
@@ -290,8 +287,9 @@ static request_sequences perform_request(servers_fixture *f,
}
memset(s_valid, 0, f->num_servers * sizeof(int));
+ grpc_slice host = grpc_slice_from_static_string("foo.test.google.fr");
c = grpc_channel_create_call(client, NULL, GRPC_PROPAGATE_DEFAULTS, f->cq,
- "/foo", "foo.test.google.fr",
+ grpc_slice_from_static_string("/foo"), &host,
gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
GPR_ASSERT(c);
completed_client = 0;
@@ -317,8 +315,6 @@ static request_sequences perform_request(servers_fixture *f,
&rdata->trailing_metadata_recv;
op->data.recv_status_on_client.status = &rdata->status;
op->data.recv_status_on_client.status_details = &rdata->details;
- op->data.recv_status_on_client.status_details_capacity =
- &rdata->details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -361,7 +357,8 @@ static request_sequences perform_request(servers_fixture *f,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -380,12 +377,12 @@ static request_sequences perform_request(servers_fixture *f,
}
cq_verify(cqv);
- gpr_log(GPR_DEBUG, "status=%d; %s", rdata->status, rdata->details);
GPR_ASSERT(rdata->status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(rdata->details, "xyz"));
- GPR_ASSERT(0 == strcmp(rdata->call_details[s_idx].method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(rdata->details, "xyz"));
GPR_ASSERT(0 ==
- strcmp(rdata->call_details[s_idx].host, "foo.test.google.fr"));
+ grpc_slice_str_cmp(rdata->call_details[s_idx].method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(rdata->call_details[s_idx].host,
+ "foo.test.google.fr"));
GPR_ASSERT(was_cancelled == 1);
grpc_call_destroy(f->server_calls[s_idx]);
@@ -418,7 +415,7 @@ static request_sequences perform_request(servers_fixture *f,
for (i = 0; i < f->num_servers; i++) {
grpc_call_details_destroy(&rdata->call_details[i]);
}
- gpr_free(rdata->details);
+ grpc_slice_unref(rdata->details);
}
gpr_free(s_valid);
@@ -450,10 +447,12 @@ static grpc_call **perform_multirequest(servers_fixture *f,
op->flags = 0;
op->reserved = NULL;
+ grpc_slice host = grpc_slice_from_static_string("foo.test.google.fr");
for (i = 0; i < concurrent_calls; i++) {
- calls[i] = grpc_channel_create_call(
- client, NULL, GRPC_PROPAGATE_DEFAULTS, f->cq, "/foo",
- "foo.test.google.fr", gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+ calls[i] =
+ grpc_channel_create_call(client, NULL, GRPC_PROPAGATE_DEFAULTS, f->cq,
+ grpc_slice_from_static_string("/foo"), &host,
+ gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
GPR_ASSERT(calls[i]);
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(calls[i], ops,
(size_t)(op - ops), tag(1),
@@ -641,7 +640,11 @@ static void test_get_channel_info() {
arg.value.string = "{\"loadBalancingPolicy\": \"ROUND_ROBIN\"}";
grpc_channel_args *args = grpc_channel_args_copy_and_add(NULL, &arg, 1);
channel = grpc_insecure_channel_create("ipv4:127.0.0.1:1234", args, NULL);
- grpc_channel_args_destroy(args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
// Ensures that resolver returns.
grpc_channel_check_connectivity_state(channel, true /* try_to_connect */);
// Now request the service config again.
diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
index ffa167a0e7..5ba8ef85e7 100644
--- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
@@ -64,6 +64,7 @@ static grpc_error *my_resolve_address(const char *name, const char *addr,
}
static grpc_resolver *create_resolver(const char *name) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_resolver_factory *factory = grpc_resolver_factory_lookup("dns");
grpc_uri *uri = grpc_uri_parse(name, 0);
GPR_ASSERT(uri);
@@ -71,9 +72,10 @@ static grpc_resolver *create_resolver(const char *name) {
memset(&args, 0, sizeof(args));
args.uri = uri;
grpc_resolver *resolver =
- grpc_resolver_factory_create_resolver(factory, &args);
+ grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
grpc_resolver_factory_unref(factory);
grpc_uri_destroy(uri);
+ grpc_exec_ctx_finish(&exec_ctx);
return resolver;
}
@@ -123,7 +125,7 @@ int main(int argc, char **argv) {
GPR_ASSERT(wait_loop(30, &ev2));
GPR_ASSERT(result != NULL);
- grpc_channel_args_destroy(result);
+ grpc_channel_args_destroy(&exec_ctx, result);
GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test");
grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/client_channel/resolvers/dns_resolver_test.c b/test/core/client_channel/resolvers/dns_resolver_test.c
index 41a9125431..5603a57b5f 100644
--- a/test/core/client_channel/resolvers/dns_resolver_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_test.c
@@ -48,7 +48,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
GPR_ASSERT(uri);
memset(&args, 0, sizeof(args));
args.uri = uri;
- resolver = grpc_resolver_factory_create_resolver(factory, &args);
+ resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
GPR_ASSERT(resolver != NULL);
GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_succeeds");
grpc_uri_destroy(uri);
@@ -65,7 +65,7 @@ static void test_fails(grpc_resolver_factory *factory, const char *string) {
GPR_ASSERT(uri);
memset(&args, 0, sizeof(args));
args.uri = uri;
- resolver = grpc_resolver_factory_create_resolver(factory, &args);
+ resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
GPR_ASSERT(resolver == NULL);
grpc_uri_destroy(uri);
grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.c b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
index ebf311ab83..bf49fb155d 100644
--- a/test/core/client_channel/resolvers/sockaddr_resolver_test.c
+++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
@@ -54,7 +54,7 @@ void on_resolution_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
GPR_ASSERT(channel_arg != NULL);
GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
GPR_ASSERT(strcmp(res->expected_server_name, channel_arg->value.string) == 0);
- grpc_channel_args_destroy(res->resolver_result);
+ grpc_channel_args_destroy(exec_ctx, res->resolver_result);
}
static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
@@ -67,7 +67,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
GPR_ASSERT(uri);
memset(&args, 0, sizeof(args));
args.uri = uri;
- resolver = grpc_resolver_factory_create_resolver(factory, &args);
+ resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
GPR_ASSERT(resolver != NULL);
on_resolution_arg on_res_arg;
@@ -93,7 +93,7 @@ static void test_fails(grpc_resolver_factory *factory, const char *string) {
GPR_ASSERT(uri);
memset(&args, 0, sizeof(args));
args.uri = uri;
- resolver = grpc_resolver_factory_create_resolver(factory, &args);
+ resolver = grpc_resolver_factory_create_resolver(&exec_ctx, factory, &args);
GPR_ASSERT(resolver == NULL);
grpc_uri_destroy(uri);
grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/client_channel/set_initial_connect_string_test.c b/test/core/client_channel/set_initial_connect_string_test.c
index b16a3ebf45..e816347123 100644
--- a/test/core/client_channel/set_initial_connect_string_test.c
+++ b/test/core/client_channel/set_initial_connect_string_test.c
@@ -140,9 +140,11 @@ static void start_rpc(int use_creds, int target_port) {
} else {
state.channel = grpc_insecure_channel_create(state.target, NULL, NULL);
}
+ grpc_slice host = grpc_slice_from_static_string("localhost");
state.call = grpc_channel_create_call(
- state.channel, NULL, GRPC_PROPAGATE_DEFAULTS, state.cq, "/Service/Method",
- "localhost", gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+ state.channel, NULL, GRPC_PROPAGATE_DEFAULTS, state.cq,
+ grpc_slice_from_static_string("/Service/Method"), &host,
+ gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
memset(&state.op, 0, sizeof(state.op));
state.op.op = GRPC_OP_SEND_INITIAL_METADATA;
state.op.data.send_initial_metadata.count = 0;
@@ -157,7 +159,7 @@ static void cleanup_rpc(void) {
grpc_event ev;
grpc_slice_buffer_destroy(&state.incoming_buffer);
grpc_slice_buffer_destroy(&state.temp_incoming_buffer);
- grpc_channel_credentials_unref(state.creds);
+ grpc_channel_credentials_release(state.creds);
grpc_call_destroy(state.call);
grpc_completion_queue_shutdown(state.cq);
do {
diff --git a/test/core/compression/algorithm_test.c b/test/core/compression/algorithm_test.c
index bdee748ae6..fa0bdb8c19 100644
--- a/test/core/compression/algorithm_test.c
+++ b/test/core/compression/algorithm_test.c
@@ -40,6 +40,7 @@
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/static_metadata.h"
#include "test/core/util/test_config.h"
@@ -51,29 +52,35 @@ static void test_algorithm_mesh(void) {
for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
char *name;
grpc_compression_algorithm parsed;
- grpc_mdstr *mdstr;
- grpc_mdelem *mdelem;
+ grpc_slice mdstr;
+ grpc_mdelem mdelem;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
GPR_ASSERT(
grpc_compression_algorithm_name((grpc_compression_algorithm)i, &name));
- GPR_ASSERT(grpc_compression_algorithm_parse(name, strlen(name), &parsed));
+ GPR_ASSERT(grpc_compression_algorithm_parse(
+ grpc_slice_from_static_string(name), &parsed));
GPR_ASSERT((int)parsed == i);
- mdstr = grpc_mdstr_from_string(name);
- GPR_ASSERT(mdstr == grpc_compression_algorithm_mdstr(parsed));
- GPR_ASSERT(parsed == grpc_compression_algorithm_from_mdstr(mdstr));
+ mdstr = grpc_slice_from_copied_string(name);
+ GPR_ASSERT(0 ==
+ grpc_slice_cmp(mdstr, grpc_compression_algorithm_slice(parsed)));
+ GPR_ASSERT(parsed == grpc_compression_algorithm_from_slice(mdstr));
mdelem = grpc_compression_encoding_mdelem(parsed);
- GPR_ASSERT(mdelem->value == mdstr);
- GPR_ASSERT(mdelem->key == GRPC_MDSTR_GRPC_ENCODING);
- GRPC_MDSTR_UNREF(mdstr);
- GRPC_MDELEM_UNREF(mdelem);
+ GPR_ASSERT(0 == grpc_slice_cmp(GRPC_MDVALUE(mdelem), mdstr));
+ GPR_ASSERT(0 ==
+ grpc_slice_cmp(GRPC_MDKEY(mdelem), GRPC_MDSTR_GRPC_ENCODING));
+ grpc_slice_unref_internal(&exec_ctx, mdstr);
+ GRPC_MDELEM_UNREF(&exec_ctx, mdelem);
+ grpc_exec_ctx_finish(&exec_ctx);
}
/* test failure */
- GPR_ASSERT(NULL ==
- grpc_compression_encoding_mdelem(GRPC_COMPRESS_ALGORITHMS_COUNT));
+ GPR_ASSERT(GRPC_MDISNULL(
+ grpc_compression_encoding_mdelem(GRPC_COMPRESS_ALGORITHMS_COUNT)));
}
static void test_algorithm_failure(void) {
- grpc_mdstr *mdstr;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_slice mdstr;
gpr_log(GPR_DEBUG, "test_algorithm_failure");
@@ -81,14 +88,17 @@ static void test_algorithm_failure(void) {
NULL) == 0);
GPR_ASSERT(grpc_compression_algorithm_name(GRPC_COMPRESS_ALGORITHMS_COUNT + 1,
NULL) == 0);
- mdstr = grpc_mdstr_from_string("this-is-an-invalid-algorithm");
- GPR_ASSERT(grpc_compression_algorithm_from_mdstr(mdstr) ==
+ mdstr = grpc_slice_from_static_string("this-is-an-invalid-algorithm");
+ GPR_ASSERT(grpc_compression_algorithm_from_slice(mdstr) ==
GRPC_COMPRESS_ALGORITHMS_COUNT);
- GPR_ASSERT(grpc_compression_algorithm_mdstr(GRPC_COMPRESS_ALGORITHMS_COUNT) ==
- NULL);
- GPR_ASSERT(grpc_compression_algorithm_mdstr(GRPC_COMPRESS_ALGORITHMS_COUNT +
- 1) == NULL);
- GRPC_MDSTR_UNREF(mdstr);
+ GPR_ASSERT(0 == grpc_slice_cmp(grpc_compression_algorithm_slice(
+ GRPC_COMPRESS_ALGORITHMS_COUNT),
+ grpc_empty_slice()));
+ GPR_ASSERT(0 == grpc_slice_cmp(grpc_compression_algorithm_slice(
+ GRPC_COMPRESS_ALGORITHMS_COUNT + 1),
+ grpc_empty_slice()));
+ grpc_slice_unref_internal(&exec_ctx, mdstr);
+ grpc_exec_ctx_finish(&exec_ctx);
}
int main(int argc, char **argv) {
diff --git a/test/core/compression/compression_test.c b/test/core/compression/compression_test.c
index 4c43746e33..7b2e56dc01 100644
--- a/test/core/compression/compression_test.c
+++ b/test/core/compression/compression_test.c
@@ -54,7 +54,7 @@ static void test_compression_algorithm_parse(void) {
const char *valid_name = valid_names[i];
grpc_compression_algorithm algorithm;
const int success = grpc_compression_algorithm_parse(
- valid_name, strlen(valid_name), &algorithm);
+ grpc_slice_from_static_string(valid_name), &algorithm);
GPR_ASSERT(success != 0);
GPR_ASSERT(algorithm == valid_algorithms[i]);
}
@@ -64,7 +64,7 @@ static void test_compression_algorithm_parse(void) {
grpc_compression_algorithm algorithm;
int success;
success = grpc_compression_algorithm_parse(
- invalid_name, strlen(invalid_name), &algorithm);
+ grpc_slice_from_static_string(invalid_name), &algorithm);
GPR_ASSERT(success == 0);
/* the value of "algorithm" is undefined upon failure */
}
diff --git a/test/core/compression/message_compress_test.c b/test/core/compression/message_compress_test.c
index fc53cd9d36..2432ca768a 100644
--- a/test/core/compression/message_compress_test.c
+++ b/test/core/compression/message_compress_test.c
@@ -40,6 +40,7 @@
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
+#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/support/murmur_hash.h"
#include "test/core/util/slice_splitter.h"
#include "test/core/util/test_config.h"
@@ -82,7 +83,12 @@ static void assert_passthrough(grpc_slice value,
grpc_split_slices_to_buffer(uncompressed_split_mode, &value, 1, &input);
- was_compressed = grpc_msg_compress(algorithm, &input, &compressed_raw);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ was_compressed =
+ grpc_msg_compress(&exec_ctx, algorithm, &input, &compressed_raw);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
GPR_ASSERT(input.count > 0);
switch (compress_result_check) {
@@ -99,8 +105,13 @@ static void assert_passthrough(grpc_slice value,
grpc_split_slice_buffer(compressed_split_mode, &compressed_raw, &compressed);
- GPR_ASSERT(grpc_msg_decompress(
- was_compressed ? algorithm : GRPC_COMPRESS_NONE, &compressed, &output));
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ GPR_ASSERT(grpc_msg_decompress(
+ &exec_ctx, was_compressed ? algorithm : GRPC_COMPRESS_NONE, &compressed,
+ &output));
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
final = grpc_slice_merge(output.slices, output.count);
GPR_ASSERT(0 == grpc_slice_cmp(value, final));
@@ -160,7 +171,9 @@ static void test_tiny_data_compress(void) {
for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
if (i == GRPC_COMPRESS_NONE) continue;
- GPR_ASSERT(0 == grpc_msg_compress(i, &input, &output));
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ GPR_ASSERT(0 == grpc_msg_compress(&exec_ctx, i, &input, &output));
+ grpc_exec_ctx_finish(&exec_ctx);
GPR_ASSERT(1 == output.count);
}
@@ -180,8 +193,9 @@ static void test_bad_decompression_data_crc(void) {
grpc_slice_buffer_init(&output);
grpc_slice_buffer_add(&input, create_test_value(ONE_MB_A));
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
/* compress it */
- grpc_msg_compress(GRPC_COMPRESS_GZIP, &input, &corrupted);
+ grpc_msg_compress(&exec_ctx, GRPC_COMPRESS_GZIP, &input, &corrupted);
/* corrupt the output by smashing the CRC */
GPR_ASSERT(corrupted.count > 1);
GPR_ASSERT(GRPC_SLICE_LENGTH(corrupted.slices[1]) > 8);
@@ -189,7 +203,9 @@ static void test_bad_decompression_data_crc(void) {
memcpy(GRPC_SLICE_START_PTR(corrupted.slices[1]) + idx, &bad, 4);
/* try (and fail) to decompress the corrupted compresed buffer */
- GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_GZIP, &corrupted, &output));
+ GPR_ASSERT(0 == grpc_msg_decompress(&exec_ctx, GRPC_COMPRESS_GZIP, &corrupted,
+ &output));
+ grpc_exec_ctx_finish(&exec_ctx);
grpc_slice_buffer_destroy(&input);
grpc_slice_buffer_destroy(&corrupted);
@@ -208,7 +224,10 @@ static void test_bad_decompression_data_trailing_garbage(void) {
"\x78\xda\x63\x60\x60\x60\x00\x00\x00\x04\x00\x01\x99", 13));
/* try (and fail) to decompress the invalid compresed buffer */
- GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_DEFLATE, &input, &output));
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ GPR_ASSERT(0 == grpc_msg_decompress(&exec_ctx, GRPC_COMPRESS_DEFLATE, &input,
+ &output));
+ grpc_exec_ctx_finish(&exec_ctx);
grpc_slice_buffer_destroy(&input);
grpc_slice_buffer_destroy(&output);
@@ -224,7 +243,10 @@ static void test_bad_decompression_data_stream(void) {
grpc_slice_from_copied_buffer("\x78\xda\xff\xff", 4));
/* try (and fail) to decompress the invalid compresed buffer */
- GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_DEFLATE, &input, &output));
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ GPR_ASSERT(0 == grpc_msg_decompress(&exec_ctx, GRPC_COMPRESS_DEFLATE, &input,
+ &output));
+ grpc_exec_ctx_finish(&exec_ctx);
grpc_slice_buffer_destroy(&input);
grpc_slice_buffer_destroy(&output);
@@ -239,13 +261,16 @@ static void test_bad_compression_algorithm(void) {
grpc_slice_buffer_init(&output);
grpc_slice_buffer_add(
&input, grpc_slice_from_copied_string("Never gonna give you up"));
- was_compressed =
- grpc_msg_compress(GRPC_COMPRESS_ALGORITHMS_COUNT, &input, &output);
+
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ was_compressed = grpc_msg_compress(&exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT,
+ &input, &output);
GPR_ASSERT(0 == was_compressed);
- was_compressed =
- grpc_msg_compress(GRPC_COMPRESS_ALGORITHMS_COUNT + 123, &input, &output);
+ was_compressed = grpc_msg_compress(
+ &exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT + 123, &input, &output);
GPR_ASSERT(0 == was_compressed);
+ grpc_exec_ctx_finish(&exec_ctx);
grpc_slice_buffer_destroy(&input);
grpc_slice_buffer_destroy(&output);
@@ -261,13 +286,15 @@ static void test_bad_decompression_algorithm(void) {
grpc_slice_buffer_add(&input,
grpc_slice_from_copied_string(
"I'm not really compressed but it doesn't matter"));
- was_decompressed =
- grpc_msg_decompress(GRPC_COMPRESS_ALGORITHMS_COUNT, &input, &output);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ was_decompressed = grpc_msg_decompress(
+ &exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT, &input, &output);
GPR_ASSERT(0 == was_decompressed);
- was_decompressed = grpc_msg_decompress(GRPC_COMPRESS_ALGORITHMS_COUNT + 123,
- &input, &output);
+ was_decompressed = grpc_msg_decompress(
+ &exec_ctx, GRPC_COMPRESS_ALGORITHMS_COUNT + 123, &input, &output);
GPR_ASSERT(0 == was_decompressed);
+ grpc_exec_ctx_finish(&exec_ctx);
grpc_slice_buffer_destroy(&input);
grpc_slice_buffer_destroy(&output);
diff --git a/test/core/end2end/bad_server_response_test.c b/test/core/end2end/bad_server_response_test.c
index 1c4a17fda8..496bb4de0f 100644
--- a/test/core/end2end/bad_server_response_test.c
+++ b/test/core/end2end/bad_server_response_test.c
@@ -47,6 +47,7 @@
#include <grpc/support/thd.h>
#include "src/core/lib/iomgr/sockaddr.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
#include "test/core/end2end/cq_verifier.h"
@@ -170,16 +171,17 @@ static void start_rpc(int target_port, grpc_status_code expected_status,
grpc_status_code status;
grpc_call_error error;
cq_verifier *cqv;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
state.cq = grpc_completion_queue_create(NULL);
cqv = cq_verifier_create(state.cq);
gpr_join_host_port(&state.target, "127.0.0.1", target_port);
state.channel = grpc_insecure_channel_create(state.target, NULL, NULL);
+ grpc_slice host = grpc_slice_from_static_string("localhost");
state.call = grpc_channel_create_call(
- state.channel, NULL, GRPC_PROPAGATE_DEFAULTS, state.cq, "/Service/Method",
- "localhost", gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+ state.channel, NULL, GRPC_PROPAGATE_DEFAULTS, state.cq,
+ grpc_slice_from_static_string("/Service/Method"), &host,
+ gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
@@ -204,7 +206,6 @@ static void start_rpc(int target_port, grpc_status_code expected_status,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -216,20 +217,20 @@ static void start_rpc(int target_port, grpc_status_code expected_status,
CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
cq_verify(cqv);
- gpr_log(GPR_DEBUG, "Rpc status: %d, details: %s", status, details);
GPR_ASSERT(status == expected_status);
- GPR_ASSERT(NULL != strstr(details, expected_detail));
+ GPR_ASSERT(-1 != grpc_slice_slice(details, grpc_slice_from_static_string(
+ expected_detail)));
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
- gpr_free(details);
+ grpc_slice_unref(details);
cq_verifier_destroy(cqv);
}
-static void cleanup_rpc(void) {
+static void cleanup_rpc(grpc_exec_ctx *exec_ctx) {
grpc_event ev;
- grpc_slice_buffer_destroy(&state.temp_incoming_buffer);
- grpc_slice_buffer_destroy(&state.outgoing_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &state.temp_incoming_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &state.outgoing_buffer);
grpc_call_destroy(state.call);
grpc_completion_queue_shutdown(state.cq);
do {
@@ -298,8 +299,8 @@ static void run_test(const char *response_payload,
/* clean up */
grpc_endpoint_shutdown(&exec_ctx, state.tcp);
grpc_endpoint_destroy(&exec_ctx, state.tcp);
+ cleanup_rpc(&exec_ctx);
grpc_exec_ctx_finish(&exec_ctx);
- cleanup_rpc();
test_tcp_server_destroy(&test_server);
grpc_shutdown();
diff --git a/test/core/end2end/connection_refused_test.c b/test/core/end2end/connection_refused_test.c
index 728d6dca59..81a6b8720d 100644
--- a/test/core/end2end/connection_refused_test.c
+++ b/test/core/end2end/connection_refused_test.c
@@ -40,6 +40,7 @@
#include <grpc/support/string_util.h>
#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/service_config.h"
@@ -59,8 +60,7 @@ static void run_test(bool wait_for_ready, bool use_service_config) {
grpc_op *op;
grpc_metadata_array trailing_metadata_recv;
grpc_status_code status;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
gpr_log(GPR_INFO, "TEST: wait_for_ready=%d use_service_config=%d",
wait_for_ready, use_service_config);
@@ -97,9 +97,10 @@ static void run_test(bool wait_for_ready, bool use_service_config) {
gpr_join_host_port(&addr, "127.0.0.1", port);
gpr_log(GPR_INFO, "server: %s", addr);
chan = grpc_insecure_channel_create(addr, args, NULL);
- call = grpc_channel_create_call(chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
- "/service/method", "nonexistant", deadline,
- NULL);
+ grpc_slice host = grpc_slice_from_static_string("nonexistant");
+ call = grpc_channel_create_call(
+ chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
+ grpc_slice_from_static_string("/service/method"), &host, deadline, NULL);
gpr_free(addr);
@@ -116,7 +117,6 @@ static void run_test(bool wait_for_ready, bool use_service_config) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -142,10 +142,14 @@ static void run_test(bool wait_for_ready, bool use_service_config) {
grpc_channel_destroy(chan);
cq_verifier_destroy(cqv);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&trailing_metadata_recv);
- if (args != NULL) grpc_channel_args_destroy(args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ if (args != NULL) grpc_channel_args_destroy(&exec_ctx, args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
grpc_shutdown();
}
diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c
index 57373970c4..925c59e696 100644
--- a/test/core/end2end/cq_verifier.c
+++ b/test/core/end2end/cq_verifier.c
@@ -92,8 +92,8 @@ static int has_metadata(const grpc_metadata *md, size_t count, const char *key,
const char *value) {
size_t i;
for (i = 0; i < count; i++) {
- if (0 == strcmp(key, md[i].key) && strlen(value) == md[i].value_length &&
- 0 == memcmp(md[i].value, value, md[i].value_length)) {
+ if (0 == grpc_slice_str_cmp(md[i].key, key) &&
+ 0 == grpc_slice_str_cmp(md[i].value, value)) {
return 1;
}
}
@@ -105,6 +105,23 @@ int contains_metadata(grpc_metadata_array *array, const char *key,
return has_metadata(array->metadata, array->count, key, value);
}
+static int has_metadata_slices(const grpc_metadata *md, size_t count,
+ grpc_slice key, grpc_slice value) {
+ size_t i;
+ for (i = 0; i < count; i++) {
+ if (0 == grpc_slice_cmp(md[i].key, key) &&
+ 0 == grpc_slice_cmp(md[i].value, value)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int contains_metadata_slices(grpc_metadata_array *array, grpc_slice key,
+ grpc_slice value) {
+ return has_metadata_slices(array->metadata, array->count, key, value);
+}
+
static grpc_slice merge_slices(grpc_slice *slices, size_t nslices) {
size_t i;
size_t len = 0;
diff --git a/test/core/end2end/cq_verifier.h b/test/core/end2end/cq_verifier.h
index b754de9bbe..035aa270e4 100644
--- a/test/core/end2end/cq_verifier.h
+++ b/test/core/end2end/cq_verifier.h
@@ -71,5 +71,7 @@ int byte_buffer_eq_slice(grpc_byte_buffer *bb, grpc_slice b);
int byte_buffer_eq_string(grpc_byte_buffer *byte_buffer, const char *string);
int contains_metadata(grpc_metadata_array *array, const char *key,
const char *value);
+int contains_metadata_slices(grpc_metadata_array *array, grpc_slice key,
+ grpc_slice value);
#endif /* GRPC_TEST_CORE_END2END_CQ_VERIFIER_H */
diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c
index 11e8604f56..76d2747c9c 100644
--- a/test/core/end2end/dualstack_socket_test.c
+++ b/test/core/end2end/dualstack_socket_test.c
@@ -88,8 +88,7 @@ void test_connect(const char *server_host, const char *client_host, int port,
grpc_metadata_array request_metadata_recv;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
grpc_call_details call_details;
char *peer;
@@ -168,8 +167,10 @@ void test_connect(const char *server_host, const char *client_host, int port,
}
/* Send a trivial request. */
+ grpc_slice host = grpc_slice_from_static_string("foo.test.google.fr");
c = grpc_channel_create_call(client, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
- "/foo", "foo.test.google.fr", deadline, NULL);
+ grpc_slice_from_static_string("/foo"), &host,
+ deadline, NULL);
GPR_ASSERT(c);
memset(ops, 0, sizeof(ops));
@@ -192,7 +193,6 @@ void test_connect(const char *server_host, const char *client_host, int port,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -216,7 +216,8 @@ void test_connect(const char *server_host, const char *client_host, int port,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
@@ -235,9 +236,10 @@ void test_connect(const char *server_host, const char *client_host, int port,
gpr_free(peer);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
- GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 ==
+ grpc_slice_str_cmp(call_details.host, "foo.test.google.fr"));
GPR_ASSERT(was_cancelled == 1);
grpc_call_destroy(s);
@@ -271,7 +273,7 @@ void test_connect(const char *server_host, const char *client_host, int port,
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
- gpr_free(details);
+ grpc_slice_unref(details);
if (picked_port) {
grpc_recycle_unused_port(port);
}
diff --git a/test/core/end2end/end2end_test_utils.c b/test/core/end2end/end2end_test_utils.c
index 46fb4ec1af..8783d8451b 100644
--- a/test/core/end2end/end2end_test_utils.c
+++ b/test/core/end2end/end2end_test_utils.c
@@ -39,13 +39,27 @@
const char *get_host_override_string(const char *str,
grpc_end2end_test_config config) {
- return (config.feature_mask & FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER ? str
- : NULL);
+ if (config.feature_mask & FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER) {
+ return str;
+ } else {
+ return NULL;
+ }
+}
+
+const grpc_slice *get_host_override_slice(const char *str,
+ grpc_end2end_test_config config) {
+ const char *r = get_host_override_string(str, config);
+ if (r != NULL) {
+ static grpc_slice ret;
+ ret = grpc_slice_from_static_string(r);
+ return &ret;
+ }
+ return NULL;
}
-void validate_host_override_string(const char *pattern, const char *str,
+void validate_host_override_string(const char *pattern, grpc_slice str,
grpc_end2end_test_config config) {
if (config.feature_mask & FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER) {
- GPR_ASSERT(0 == strcmp(str, pattern));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(str, pattern));
}
}
diff --git a/test/core/end2end/end2end_tests.h b/test/core/end2end/end2end_tests.h
index f25e90b5f6..cb0afd9cd9 100644
--- a/test/core/end2end/end2end_tests.h
+++ b/test/core/end2end/end2end_tests.h
@@ -72,8 +72,12 @@ void grpc_end2end_tests(int argc, char **argv, grpc_end2end_test_config config);
const char *get_host_override_string(const char *str,
grpc_end2end_test_config config);
+/* Returns a pointer to a statically allocated slice: future invocations
+ overwrite past invocations, not threadsafe, etc... */
+const grpc_slice *get_host_override_slice(const char *str,
+ grpc_end2end_test_config config);
-void validate_host_override_string(const char *pattern, const char *str,
+void validate_host_override_string(const char *pattern, grpc_slice str,
grpc_end2end_test_config config);
#endif /* GRPC_TEST_CORE_END2END_END2END_TESTS_H */
diff --git a/test/core/end2end/fake_resolver.c b/test/core/end2end/fake_resolver.c
index 865b55de4d..55a42b8fa3 100644
--- a/test/core/end2end/fake_resolver.c
+++ b/test/core/end2end/fake_resolver.c
@@ -48,6 +48,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
@@ -76,8 +77,8 @@ typedef struct {
static void fake_resolver_destroy(grpc_exec_ctx* exec_ctx, grpc_resolver* gr) {
fake_resolver* r = (fake_resolver*)gr;
gpr_mu_destroy(&r->mu);
- grpc_channel_args_destroy(r->channel_args);
- grpc_lb_addresses_destroy(r->addresses);
+ grpc_channel_args_destroy(exec_ctx, r->channel_args);
+ grpc_lb_addresses_destroy(exec_ctx, r->addresses);
gpr_free(r);
}
@@ -140,7 +141,8 @@ static void fake_resolver_factory_unref(grpc_resolver_factory* factory) {}
static void do_nothing(void* ignored) {}
-static grpc_resolver* fake_resolver_create(grpc_resolver_factory* factory,
+static grpc_resolver* fake_resolver_create(grpc_exec_ctx* exec_ctx,
+ grpc_resolver_factory* factory,
grpc_resolver_args* args) {
if (0 != strcmp(args->uri->authority, "")) {
gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme",
@@ -172,10 +174,10 @@ static grpc_resolver* fake_resolver_create(grpc_resolver_factory* factory,
addresses->addresses[i].is_balancer = lb_enabled;
if (errors_found) break;
}
- grpc_slice_buffer_destroy(&path_parts);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &path_parts);
grpc_slice_unref(path_slice);
if (errors_found) {
- grpc_lb_addresses_destroy(addresses);
+ grpc_lb_addresses_destroy(exec_ctx, addresses);
return NULL;
}
// Instantiate resolver.
diff --git a/test/core/end2end/fixtures/h2_census.c b/test/core/end2end/fixtures/h2_census.c
index c52d7660f5..8e60123ed6 100644
--- a/test/core/end2end/fixtures/h2_census.c
+++ b/test/core/end2end/fixtures/h2_census.c
@@ -85,7 +85,11 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f,
client_args = grpc_channel_args_copy_and_add(client_args, &arg, 1);
f->client = grpc_insecure_channel_create(ffd->localaddr, client_args, NULL);
GPR_ASSERT(f->client);
- grpc_channel_args_destroy(client_args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, client_args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
}
void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
@@ -97,7 +101,11 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
}
server_args = grpc_channel_args_copy_and_add(server_args, &arg, 1);
f->server = grpc_server_create(server_args, NULL);
- grpc_channel_args_destroy(server_args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, server_args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
grpc_server_register_completion_queue(f->server, f->cq, NULL);
GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
grpc_server_start(f->server);
diff --git a/test/core/end2end/fixtures/h2_compress.c b/test/core/end2end/fixtures/h2_compress.c
index fedd2ebc46..c01e45664b 100644
--- a/test/core/end2end/fixtures/h2_compress.c
+++ b/test/core/end2end/fixtures/h2_compress.c
@@ -78,7 +78,9 @@ void chttp2_init_client_fullstack_compression(grpc_end2end_test_fixture *f,
grpc_channel_args *client_args) {
fullstack_compression_fixture_data *ffd = f->fixture_data;
if (ffd->client_args_compression != NULL) {
- grpc_channel_args_destroy(ffd->client_args_compression);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, ffd->client_args_compression);
+ grpc_exec_ctx_finish(&exec_ctx);
}
ffd->client_args_compression = grpc_channel_args_set_compression_algorithm(
client_args, GRPC_COMPRESS_GZIP);
@@ -90,7 +92,9 @@ void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture *f,
grpc_channel_args *server_args) {
fullstack_compression_fixture_data *ffd = f->fixture_data;
if (ffd->server_args_compression != NULL) {
- grpc_channel_args_destroy(ffd->server_args_compression);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, ffd->server_args_compression);
+ grpc_exec_ctx_finish(&exec_ctx);
}
ffd->server_args_compression = grpc_channel_args_set_compression_algorithm(
server_args, GRPC_COMPRESS_GZIP);
@@ -104,11 +108,13 @@ void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture *f,
}
void chttp2_tear_down_fullstack_compression(grpc_end2end_test_fixture *f) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
fullstack_compression_fixture_data *ffd = f->fixture_data;
- grpc_channel_args_destroy(ffd->client_args_compression);
- grpc_channel_args_destroy(ffd->server_args_compression);
+ grpc_channel_args_destroy(&exec_ctx, ffd->client_args_compression);
+ grpc_channel_args_destroy(&exec_ctx, ffd->server_args_compression);
gpr_free(ffd->localaddr);
gpr_free(ffd);
+ grpc_exec_ctx_finish(&exec_ctx);
}
/* All test configurations */
diff --git a/test/core/end2end/fixtures/h2_load_reporting.c b/test/core/end2end/fixtures/h2_load_reporting.c
index 7a76489b44..38321f34db 100644
--- a/test/core/end2end/fixtures/h2_load_reporting.c
+++ b/test/core/end2end/fixtures/h2_load_reporting.c
@@ -88,7 +88,11 @@ void chttp2_init_server_load_reporting(grpc_end2end_test_fixture *f,
}
server_args = grpc_channel_args_copy_and_add(server_args, &arg, 1);
f->server = grpc_server_create(server_args, NULL);
- grpc_channel_args_destroy(server_args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, server_args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
grpc_server_register_completion_queue(f->server, f->cq, NULL);
GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
grpc_server_start(f->server);
diff --git a/test/core/end2end/fixtures/h2_oauth2.c b/test/core/end2end/fixtures/h2_oauth2.c
index 6122f4f2f9..28011be787 100644
--- a/test/core/end2end/fixtures/h2_oauth2.c
+++ b/test/core/end2end/fixtures/h2_oauth2.c
@@ -59,8 +59,8 @@ static const grpc_metadata *find_metadata(const grpc_metadata *md,
const char *value) {
size_t i;
for (i = 0; i < md_count; i++) {
- if (strcmp(key, md[i].key) == 0 && strlen(value) == md[i].value_length &&
- memcmp(md[i].value, value, md[i].value_length) == 0) {
+ if (grpc_slice_str_cmp(md[i].key, key) == 0 &&
+ grpc_slice_str_cmp(md[i].value, value) == 0) {
return &md[i];
}
}
@@ -163,7 +163,11 @@ static void chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack(
grpc_channel_args *new_client_args =
grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
chttp2_init_client_secure_fullstack(f, new_client_args, ssl_oauth2_creds);
- grpc_channel_args_destroy(new_client_args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, new_client_args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
grpc_channel_credentials_release(ssl_creds);
grpc_call_credentials_release(oauth2_creds);
}
diff --git a/test/core/end2end/fixtures/h2_ssl.c b/test/core/end2end/fixtures/h2_ssl.c
index bbd522cf30..cf44cd093c 100644
--- a/test/core/end2end/fixtures/h2_ssl.c
+++ b/test/core/end2end/fixtures/h2_ssl.c
@@ -118,7 +118,11 @@ static void chttp2_init_client_simple_ssl_secure_fullstack(
grpc_channel_args *new_client_args =
grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds);
- grpc_channel_args_destroy(new_client_args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, new_client_args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
}
static int fail_server_auth_check(grpc_channel_args *server_args) {
diff --git a/test/core/end2end/fixtures/h2_ssl_cert.c b/test/core/end2end/fixtures/h2_ssl_cert.c
index e39cb491de..92fac10d49 100644
--- a/test/core/end2end/fixtures/h2_ssl_cert.c
+++ b/test/core/end2end/fixtures/h2_ssl_cert.c
@@ -186,7 +186,11 @@ typedef enum { NONE, SELF_SIGNED, SIGNED, BAD_CERT_PAIR } certtype;
grpc_channel_args *new_client_args = \
grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1); \
chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds); \
- grpc_channel_args_destroy(new_client_args); \
+ { \
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; \
+ grpc_channel_args_destroy(&exec_ctx, new_client_args); \
+ grpc_exec_ctx_finish(&exec_ctx); \
+ } \
}
CLIENT_INIT(NONE)
@@ -317,8 +321,9 @@ static void simple_request_body(grpc_end2end_test_fixture f,
grpc_op *op;
grpc_call_error error;
+ grpc_slice host = grpc_slice_from_static_string("foo.test.google.fr:1234");
c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
- "/foo", "foo.test.google.fr:1234", deadline,
+ grpc_slice_from_static_string("/foo"), &host, deadline,
NULL);
GPR_ASSERT(c);
diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.c b/test/core/end2end/fixtures/h2_ssl_proxy.c
index 27cf3ebf32..740b075bf6 100644
--- a/test/core/end2end/fixtures/h2_ssl_proxy.c
+++ b/test/core/end2end/fixtures/h2_ssl_proxy.c
@@ -79,7 +79,11 @@ static grpc_channel *create_proxy_client(const char *target,
channel =
grpc_secure_channel_create(ssl_creds, target, new_client_args, NULL);
grpc_channel_credentials_release(ssl_creds);
- grpc_channel_args_destroy(new_client_args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, new_client_args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
return channel;
}
@@ -151,7 +155,11 @@ static void chttp2_init_client_simple_ssl_secure_fullstack(
grpc_channel_args *new_client_args =
grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds);
- grpc_channel_args_destroy(new_client_args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, new_client_args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
}
static int fail_server_auth_check(grpc_channel_args *server_args) {
diff --git a/test/core/end2end/fixtures/http_proxy.c b/test/core/end2end/fixtures/http_proxy.c
index 57fc4a38f8..f60c405cda 100644
--- a/test/core/end2end/fixtures/http_proxy.c
+++ b/test/core/end2end/fixtures/http_proxy.c
@@ -59,6 +59,7 @@
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/tcp_client.h"
#include "src/core/lib/iomgr/tcp_server.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "test/core/util/port.h"
struct grpc_end2end_http_proxy {
@@ -110,12 +111,14 @@ static void proxy_connection_unref(grpc_exec_ctx* exec_ctx,
if (conn->server_endpoint != NULL)
grpc_endpoint_destroy(exec_ctx, conn->server_endpoint);
grpc_pollset_set_destroy(conn->pollset_set);
- grpc_slice_buffer_destroy(&conn->client_read_buffer);
- grpc_slice_buffer_destroy(&conn->client_deferred_write_buffer);
- grpc_slice_buffer_destroy(&conn->client_write_buffer);
- grpc_slice_buffer_destroy(&conn->server_read_buffer);
- grpc_slice_buffer_destroy(&conn->server_deferred_write_buffer);
- grpc_slice_buffer_destroy(&conn->server_write_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &conn->client_read_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx,
+ &conn->client_deferred_write_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &conn->client_write_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &conn->server_read_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx,
+ &conn->server_deferred_write_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &conn->server_write_buffer);
grpc_http_parser_destroy(&conn->http_parser);
grpc_http_request_destroy(&conn->http_request);
gpr_free(conn);
@@ -468,7 +471,7 @@ void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) {
grpc_tcp_server_shutdown_listeners(&exec_ctx, proxy->server);
grpc_tcp_server_unref(&exec_ctx, proxy->server);
gpr_free(proxy->proxy_name);
- grpc_channel_args_destroy(proxy->channel_args);
+ grpc_channel_args_destroy(&exec_ctx, proxy->channel_args);
grpc_closure destroyed;
grpc_closure_init(&destroyed, destroy_pollset, proxy->pollset);
grpc_pollset_shutdown(&exec_ctx, proxy->pollset, &destroyed);
diff --git a/test/core/end2end/fixtures/proxy.c b/test/core/end2end/fixtures/proxy.c
index beed80df81..d014893742 100644
--- a/test/core/end2end/fixtures/proxy.c
+++ b/test/core/end2end/fixtures/proxy.c
@@ -80,8 +80,7 @@ typedef struct {
grpc_metadata_array p2s_trailing_metadata;
grpc_status_code p2s_status;
- char *p2s_status_details;
- size_t p2s_status_details_capacity;
+ grpc_slice p2s_status_details;
int c2p_server_cancelled;
} proxy_call;
@@ -153,7 +152,7 @@ static void unrefpc(proxy_call *pc, const char *reason) {
grpc_metadata_array_destroy(&pc->c2p_initial_metadata);
grpc_metadata_array_destroy(&pc->p2s_initial_metadata);
grpc_metadata_array_destroy(&pc->p2s_trailing_metadata);
- gpr_free(pc->p2s_status_details);
+ grpc_slice_unref(pc->p2s_status_details);
gpr_free(pc);
}
}
@@ -309,7 +308,6 @@ static void on_p2s_status(void *arg, int success) {
op.data.send_status_from_server.trailing_metadata =
pc->p2s_trailing_metadata.metadata;
op.data.send_status_from_server.status = pc->p2s_status;
- op.data.send_status_from_server.status_details = pc->p2s_status_details;
refpc(pc, "on_c2p_sent_status");
err = grpc_call_start_batch(pc->c2p, &op, 1,
new_closure(on_c2p_sent_status, pc), NULL);
@@ -339,7 +337,7 @@ static void on_new_call(void *arg, int success) {
pc->c2p = proxy->new_call;
pc->p2s = grpc_channel_create_call(
proxy->client, pc->c2p, GRPC_PROPAGATE_DEFAULTS, proxy->cq,
- proxy->new_call_details.method, proxy->new_call_details.host,
+ proxy->new_call_details.method, &proxy->new_call_details.host,
proxy->new_call_details.deadline, NULL);
gpr_ref_init(&pc->refs, 1);
@@ -384,8 +382,6 @@ static void on_new_call(void *arg, int success) {
&pc->p2s_trailing_metadata;
op.data.recv_status_on_client.status = &pc->p2s_status;
op.data.recv_status_on_client.status_details = &pc->p2s_status_details;
- op.data.recv_status_on_client.status_details_capacity =
- &pc->p2s_status_details_capacity;
refpc(pc, "on_p2s_status");
err = grpc_call_start_batch(pc->p2s, &op, 1, new_closure(on_p2s_status, pc),
NULL);
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index 19ac6ced14..c9d5c24798 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -44,6 +44,7 @@
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/tcp_client.h"
#include "src/core/lib/iomgr/timer.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/server.h"
#include "src/core/lib/transport/metadata.h"
#include "test/core/end2end/data/ssl_test_data.h"
@@ -90,7 +91,7 @@ static uint8_t next_byte(input_stream *inp) {
static void end(input_stream *inp) { inp->cur = inp->end; }
-static char *read_string(input_stream *inp) {
+static char *read_string(input_stream *inp, bool *special) {
char *str = NULL;
size_t cap = 0;
size_t sz = 0;
@@ -102,18 +103,56 @@ static char *read_string(input_stream *inp) {
}
c = (char)next_byte(inp);
str[sz++] = c;
- } while (c != 0);
+ } while (c != 0 && c != 1);
+ if (special != NULL) {
+ *special = (c == 1);
+ }
+ if (c == 1) {
+ str[sz-1] = 0;
+ }
return str;
}
-static void read_buffer(input_stream *inp, char **buffer, size_t *length) {
+static void read_buffer(input_stream *inp, char **buffer, size_t *length,
+ bool *special) {
*length = next_byte(inp);
+ if (*length == 255) {
+ if (special != NULL) *special = true;
+ *length = next_byte(inp);
+ } else {
+ if (special != NULL) *special = false;
+ }
*buffer = gpr_malloc(*length);
for (size_t i = 0; i < *length; i++) {
(*buffer)[i] = (char)next_byte(inp);
}
}
+static grpc_slice maybe_intern(grpc_slice s, bool intern) {
+ grpc_slice r = intern ? grpc_slice_intern(s) : grpc_slice_ref(s);
+ grpc_slice_unref(s);
+ return r;
+}
+
+static grpc_slice read_string_like_slice(input_stream *inp) {
+ bool special;
+ char *s = read_string(inp, &special);
+ grpc_slice r = maybe_intern(grpc_slice_from_copied_string(s), special);
+ gpr_free(s);
+ return r;
+}
+
+static grpc_slice read_buffer_like_slice(input_stream *inp) {
+ char *buffer;
+ size_t length;
+ bool special;
+ read_buffer(inp, &buffer, &length, &special);
+ grpc_slice r =
+ maybe_intern(grpc_slice_from_copied_buffer(buffer, length), special);
+ gpr_free(buffer);
+ return r;
+}
+
static uint32_t read_uint22(input_stream *inp) {
uint8_t b = next_byte(inp);
uint32_t x = b & 0x7f;
@@ -170,12 +209,12 @@ static grpc_channel_args *read_args(input_stream *inp) {
switch (next_byte(inp)) {
case 1:
args[i].type = GRPC_ARG_STRING;
- args[i].key = read_string(inp);
- args[i].value.string = read_string(inp);
+ args[i].key = read_string(inp, NULL);
+ args[i].value.string = read_string(inp, NULL);
break;
case 2:
args[i].type = GRPC_ARG_INTEGER;
- args[i].key = read_string(inp);
+ args[i].key = read_string(inp, NULL);
args[i].value.integer = read_int(inp);
break;
case 3:
@@ -217,7 +256,7 @@ static const char *read_cred_artifact(cred_artifact_ctx *ctx, input_stream *inp,
size_t num_builtins) {
uint8_t b = next_byte(inp);
if (b == 0) return NULL;
- if (b == 1) return ctx->release[ctx->num_release++] = read_string(inp);
+ if (b == 1) return ctx->release[ctx->num_release++] = read_string(inp, NULL);
if (b >= num_builtins + 1) {
end(inp);
return NULL;
@@ -504,8 +543,7 @@ typedef struct call_state {
grpc_status_code status;
grpc_metadata_array recv_initial_metadata;
grpc_metadata_array recv_trailing_metadata;
- char *recv_status_details;
- size_t recv_status_details_capacity;
+ grpc_slice recv_status_details;
int cancelled;
int pending_ops;
grpc_call_details call_details;
@@ -519,6 +557,11 @@ typedef struct call_state {
size_t cap_to_free;
void **to_free;
+ // array of slices to unref
+ size_t num_slices_to_unref;
+ size_t cap_slices_to_unref;
+ grpc_slice *slices_to_unref;
+
struct call_state *next;
struct call_state *prev;
} call_state;
@@ -554,12 +597,15 @@ static call_state *maybe_delete_call_state(call_state *call) {
call->next->prev = call->prev;
grpc_metadata_array_destroy(&call->recv_initial_metadata);
grpc_metadata_array_destroy(&call->recv_trailing_metadata);
- gpr_free(call->recv_status_details);
+ grpc_slice_unref(call->recv_status_details);
grpc_call_details_destroy(&call->call_details);
for (size_t i = 0; i < call->num_to_free; i++) {
gpr_free(call->to_free[i]);
}
+ for (size_t i = 0; i < call->num_slices_to_unref; i++) {
+ grpc_slice_unref(call->slices_to_unref[i]);
+ }
gpr_free(call->to_free);
gpr_free(call);
@@ -576,6 +622,17 @@ static void add_to_free(call_state *call, void *p) {
call->to_free[call->num_to_free++] = p;
}
+static grpc_slice *add_to_slice_unref(call_state *call, grpc_slice s) {
+ if (call->num_slices_to_unref == call->cap_slices_to_unref) {
+ call->cap_slices_to_unref = GPR_MAX(8, 2 * call->cap_slices_to_unref);
+ call->slices_to_unref =
+ gpr_realloc(call->slices_to_unref,
+ sizeof(*call->slices_to_unref) * call->cap_slices_to_unref);
+ }
+ call->slices_to_unref[call->num_to_free++] = s;
+ return &call->slices_to_unref[call->num_to_free - 1];
+}
+
static void read_metadata(input_stream *inp, size_t *count,
grpc_metadata **metadata, call_state *cs) {
*count = next_byte(inp);
@@ -583,12 +640,11 @@ static void read_metadata(input_stream *inp, size_t *count,
*metadata = gpr_malloc(*count * sizeof(**metadata));
memset(*metadata, 0, *count * sizeof(**metadata));
for (size_t i = 0; i < *count; i++) {
- (*metadata)[i].key = read_string(inp);
- read_buffer(inp, (char **)&(*metadata)[i].value,
- &(*metadata)[i].value_length);
+ (*metadata)[i].key = read_string_like_slice(inp);
+ (*metadata)[i].value = read_buffer_like_slice(inp);
(*metadata)[i].flags = read_uint32(inp);
- add_to_free(cs, (void *)(*metadata)[i].key);
- add_to_free(cs, (void *)(*metadata)[i].value);
+ add_to_slice_unref(cs, (*metadata)[i].key);
+ add_to_slice_unref(cs, (*metadata)[i].value);
}
} else {
*metadata = gpr_malloc(1);
@@ -652,7 +708,7 @@ static validator *make_finished_batch_validator(call_state *cs,
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
- grpc_test_only_set_metadata_hash_seed(0);
+ grpc_test_only_set_slice_hash_seed(0);
if (squelch) gpr_set_log_function(dont_log);
input_stream inp = {data, data + size};
grpc_resolve_address = my_resolve_address;
@@ -738,13 +794,17 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// create an insecure channel
case 2: {
if (g_channel == NULL) {
- char *target = read_string(&inp);
+ char *target = read_string(&inp, NULL);
char *target_uri;
gpr_asprintf(&target_uri, "dns:%s", target);
grpc_channel_args *args = read_args(&inp);
g_channel = grpc_insecure_channel_create(target_uri, args, NULL);
GPR_ASSERT(g_channel != NULL);
- grpc_channel_args_destroy(args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
gpr_free(target_uri);
gpr_free(target);
} else {
@@ -768,7 +828,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
grpc_channel_args *args = read_args(&inp);
g_server = grpc_server_create(args, NULL);
GPR_ASSERT(g_server != NULL);
- grpc_channel_args_destroy(args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
grpc_server_register_completion_queue(g_server, cq, NULL);
grpc_server_start(g_server);
server_shutdown = false;
@@ -859,8 +923,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
parent_call = g_active_call->call;
}
uint32_t propagation_mask = read_uint32(&inp);
- char *method = read_string(&inp);
- char *host = read_string(&inp);
+ grpc_slice method = read_string_like_slice(&inp);
+ grpc_slice host = read_string_like_slice(&inp);
gpr_timespec deadline =
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN));
@@ -869,12 +933,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
call_state *cs = new_call(g_active_call, CLIENT);
cs->call =
grpc_channel_create_call(g_channel, parent_call, propagation_mask,
- cq, method, host, deadline, NULL);
+ cq, method, &host, deadline, NULL);
} else {
end(&inp);
}
- gpr_free(method);
- gpr_free(host);
+ grpc_slice_unref(method);
+ grpc_slice_unref(host);
break;
}
// switch the 'current' call
@@ -939,7 +1003,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
g_active_call);
op->data.send_status_from_server.status = next_byte(&inp);
op->data.send_status_from_server.status_details =
- read_string(&inp);
+ add_to_slice_unref(g_active_call,
+ read_buffer_like_slice(&inp));
break;
case GRPC_OP_RECV_INITIAL_METADATA:
op->op = GRPC_OP_RECV_INITIAL_METADATA;
@@ -959,8 +1024,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
&g_active_call->recv_trailing_metadata;
op->data.recv_status_on_client.status_details =
&g_active_call->recv_status_details;
- op->data.recv_status_on_client.status_details_capacity =
- &g_active_call->recv_status_details_capacity;
break;
case GRPC_OP_RECV_CLOSE_ON_SERVER:
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
@@ -1048,14 +1111,14 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
}
// enable a tracer
case 17: {
- char *tracer = read_string(&inp);
+ char *tracer = read_string(&inp, NULL);
grpc_tracer_set_enabled(tracer, 1);
gpr_free(tracer);
break;
}
// disable a tracer
case 18: {
- char *tracer = read_string(&inp);
+ char *tracer = read_string(&inp, NULL);
grpc_tracer_set_enabled(tracer, 0);
gpr_free(tracer);
break;
@@ -1097,14 +1160,18 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// create a secure channel
case 22: {
if (g_channel == NULL) {
- char *target = read_string(&inp);
+ char *target = read_string(&inp, NULL);
char *target_uri;
gpr_asprintf(&target_uri, "dns:%s", target);
grpc_channel_args *args = read_args(&inp);
grpc_channel_credentials *creds = read_channel_creds(&inp);
g_channel = grpc_secure_channel_create(creds, target_uri, args, NULL);
GPR_ASSERT(g_channel != NULL);
- grpc_channel_args_destroy(args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
gpr_free(target_uri);
gpr_free(target);
grpc_channel_credentials_release(creds);
diff --git a/test/core/end2end/fuzzers/client_fuzzer.c b/test/core/end2end/fuzzers/client_fuzzer.c
index c5260cd287..0972a4c8e7 100644
--- a/test/core/end2end/fuzzers/client_fuzzer.c
+++ b/test/core/end2end/fuzzers/client_fuzzer.c
@@ -37,6 +37,7 @@
#include <grpc/support/alloc.h>
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/channel.h"
#include "test/core/util/memory_counters.h"
#include "test/core/util/mock_endpoint.h"
@@ -51,7 +52,7 @@ static void *tag(int n) { return (void *)(uintptr_t)n; }
static void dont_log(gpr_log_func_args *args) {}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
- grpc_test_only_set_metadata_hash_seed(0);
+ grpc_test_only_set_slice_hash_seed(0);
struct grpc_memory_counters counters;
if (squelch) gpr_set_log_function(dont_log);
if (leak_check) grpc_memory_counters_init();
@@ -62,7 +63,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
grpc_resource_quota_create("client_fuzzer");
grpc_endpoint *mock_endpoint =
grpc_mock_endpoint_create(discard_write, resource_quota);
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
grpc_transport *transport =
@@ -71,9 +72,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
grpc_channel *channel = grpc_channel_create(
&exec_ctx, "test-target", NULL, GRPC_CLIENT_DIRECT_CHANNEL, transport);
- grpc_call *call =
- grpc_channel_create_call(channel, NULL, 0, cq, "/foo", "localhost",
- gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+ grpc_slice host = grpc_slice_from_static_string("localhost");
+ grpc_call *call = grpc_channel_create_call(
+ channel, NULL, 0, cq, grpc_slice_from_static_string("/foo"), &host,
+ gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array_init(&initial_metadata_recv);
@@ -81,8 +83,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_status_code status;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
grpc_op ops[6];
memset(ops, 0, sizeof(ops));
@@ -110,7 +111,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -155,7 +155,7 @@ done:
grpc_completion_queue_destroy(cq);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_channel_destroy(channel);
if (response_payload_recv != NULL) {
grpc_byte_buffer_destroy(response_payload_recv);
diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary
index 12db0ff024..d5ee01bfbf 100644
--- a/test/core/end2end/fuzzers/hpack.dictionary
+++ b/test/core/end2end/fuzzers/hpack.dictionary
@@ -40,6 +40,10 @@
"\x03GET"
"\x04grpc"
"\x14grpc-accept-encoding"
+"\x1Egrpc.max_request_message_bytes"
+"\x1Fgrpc.max_response_message_bytes"
+"\x0Cgrpc.timeout"
+"\x13grpc.wait_for_ready"
"\x0Dgrpc-encoding"
"\x1Egrpc-internal-encoding-request"
"\x0Cgrpc-message"
@@ -82,6 +86,7 @@
"\x06server"
"\x0Aset-cookie"
"\x01/"
+"$/grpc.lb.v1.LoadBalancer/BalanceLoad"
"\x0B/index.html"
"\x07:status"
"\x19strict-transport-security"
diff --git a/test/core/end2end/fuzzers/server_fuzzer.c b/test/core/end2end/fuzzers/server_fuzzer.c
index 164022ec79..186542d4b2 100644
--- a/test/core/end2end/fuzzers/server_fuzzer.c
+++ b/test/core/end2end/fuzzers/server_fuzzer.c
@@ -34,6 +34,7 @@
#include <grpc/grpc.h>
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/server.h"
#include "test/core/util/memory_counters.h"
#include "test/core/util/mock_endpoint.h"
@@ -49,7 +50,7 @@ static int detag(void *p) { return (int)(uintptr_t)p; }
static void dont_log(gpr_log_func_args *args) {}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
- grpc_test_only_set_metadata_hash_seed(0);
+ grpc_test_only_set_slice_hash_seed(0);
struct grpc_memory_counters counters;
if (squelch) gpr_set_log_function(dont_log);
if (leak_check) grpc_memory_counters_init();
@@ -60,7 +61,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
grpc_resource_quota_create("server_fuzzer");
grpc_endpoint *mock_endpoint =
grpc_mock_endpoint_create(discard_write, resource_quota);
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
grpc_mock_endpoint_put_read(
&exec_ctx, mock_endpoint,
grpc_slice_from_copied_buffer((const char *)data, size));
diff --git a/test/core/end2end/goaway_server_test.c b/test/core/end2end/goaway_server_test.c
index a8c7b2be5a..b5187b048a 100644
--- a/test/core/end2end/goaway_server_test.c
+++ b/test/core/end2end/goaway_server_test.c
@@ -101,8 +101,7 @@ int main(int argc, char **argv) {
grpc_metadata_array request_metadata1;
grpc_call_details request_details1;
grpc_status_code status1;
- char *details1 = NULL;
- size_t details_capacity1 = 0;
+ grpc_slice details1;
grpc_metadata_array_init(&trailing_metadata_recv1);
grpc_metadata_array_init(&request_metadata1);
grpc_call_details_init(&request_details1);
@@ -111,8 +110,7 @@ int main(int argc, char **argv) {
grpc_metadata_array request_metadata2;
grpc_call_details request_details2;
grpc_status_code status2;
- char *details2 = NULL;
- size_t details_capacity2 = 0;
+ grpc_slice details2;
grpc_metadata_array_init(&trailing_metadata_recv2);
grpc_metadata_array_init(&request_metadata2);
grpc_call_details_init(&request_details2);
@@ -129,9 +127,11 @@ int main(int argc, char **argv) {
/* create a channel that picks first amongst the servers */
grpc_channel *chan = grpc_insecure_channel_create("test", NULL, NULL);
/* and an initial call to them */
- grpc_call *call1 = grpc_channel_create_call(
- chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq, "/foo", "127.0.0.1",
- GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20), NULL);
+ grpc_slice host = grpc_slice_from_static_string("127.0.0.1");
+ grpc_call *call1 =
+ grpc_channel_create_call(chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
+ grpc_slice_from_static_string("/foo"), &host,
+ GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20), NULL);
/* send initial metadata to probe connectivity */
memset(ops, 0, sizeof(ops));
op = ops;
@@ -150,7 +150,6 @@ int main(int argc, char **argv) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv1;
op->data.recv_status_on_client.status = &status1;
op->data.recv_status_on_client.status_details = &details1;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity1;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -205,9 +204,10 @@ int main(int argc, char **argv) {
cq_verify_empty(cqv);
/* and a new call: should go through to server2 when we start it */
- grpc_call *call2 = grpc_channel_create_call(
- chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq, "/foo", "127.0.0.1",
- GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20), NULL);
+ grpc_call *call2 =
+ grpc_channel_create_call(chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
+ grpc_slice_from_static_string("/foo"), &host,
+ GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20), NULL);
/* send initial metadata to probe connectivity */
memset(ops, 0, sizeof(ops));
op = ops;
@@ -226,7 +226,6 @@ int main(int argc, char **argv) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv2;
op->data.recv_status_on_client.status = &status2;
op->data.recv_status_on_client.status_details = &details2;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity2;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -292,11 +291,11 @@ int main(int argc, char **argv) {
grpc_metadata_array_destroy(&trailing_metadata_recv1);
grpc_metadata_array_destroy(&request_metadata1);
grpc_call_details_destroy(&request_details1);
- gpr_free(details1);
+ grpc_slice_unref(details1);
grpc_metadata_array_destroy(&trailing_metadata_recv2);
grpc_metadata_array_destroy(&request_metadata2);
grpc_call_details_destroy(&request_details2);
- gpr_free(details2);
+ grpc_slice_unref(details2);
cq_verifier_destroy(cqv);
grpc_completion_queue_destroy(cq);
diff --git a/test/core/end2end/invalid_call_argument_test.c b/test/core/end2end/invalid_call_argument_test.c
index 765b6ad1be..3b26ddb6d0 100644
--- a/test/core/end2end/invalid_call_argument_test.c
+++ b/test/core/end2end/invalid_call_argument_test.c
@@ -56,8 +56,7 @@ struct test_state {
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_status_code status;
- char *details;
- size_t details_capacity;
+ grpc_slice details;
grpc_call *server_call;
grpc_server *server;
grpc_metadata_array server_initial_metadata_recv;
@@ -76,17 +75,16 @@ static void prepare_test(int is_client) {
g_state.deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(2);
g_state.cq = grpc_completion_queue_create(NULL);
g_state.cqv = cq_verifier_create(g_state.cq);
- g_state.details = NULL;
- g_state.details_capacity = 0;
memset(g_state.ops, 0, sizeof(g_state.ops));
if (is_client) {
/* create a call, channel to a non existant server */
g_state.chan =
grpc_insecure_channel_create("nonexistant:54321", NULL, NULL);
+ grpc_slice host = grpc_slice_from_static_string("nonexistant");
g_state.call = grpc_channel_create_call(
- g_state.chan, NULL, GRPC_PROPAGATE_DEFAULTS, g_state.cq, "/Foo",
- "nonexistant", g_state.deadline, NULL);
+ g_state.chan, NULL, GRPC_PROPAGATE_DEFAULTS, g_state.cq,
+ grpc_slice_from_static_string("/Foo"), &host, g_state.deadline, NULL);
} else {
g_state.server = grpc_server_create(NULL, NULL);
grpc_server_register_completion_queue(g_state.server, g_state.cq, NULL);
@@ -97,9 +95,10 @@ static void prepare_test(int is_client) {
gpr_join_host_port(&server_hostport, "localhost", port);
g_state.chan = grpc_insecure_channel_create(server_hostport, NULL, NULL);
gpr_free(server_hostport);
+ grpc_slice host = grpc_slice_from_static_string("bar");
g_state.call = grpc_channel_create_call(
- g_state.chan, NULL, GRPC_PROPAGATE_DEFAULTS, g_state.cq, "/Foo", "bar",
- g_state.deadline, NULL);
+ g_state.chan, NULL, GRPC_PROPAGATE_DEFAULTS, g_state.cq,
+ grpc_slice_from_static_string("/Foo"), &host, g_state.deadline, NULL);
grpc_metadata_array_init(&g_state.server_initial_metadata_recv);
grpc_call_details_init(&g_state.call_details);
op = g_state.ops;
@@ -126,7 +125,7 @@ static void cleanup_test() {
grpc_call_destroy(g_state.call);
cq_verifier_destroy(g_state.cqv);
grpc_channel_destroy(g_state.chan);
- gpr_free(g_state.details);
+ grpc_slice_unref(g_state.details);
grpc_metadata_array_destroy(&g_state.initial_metadata_recv);
grpc_metadata_array_destroy(&g_state.trailing_metadata_recv);
@@ -289,7 +288,8 @@ static void test_send_server_status_from_client() {
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -398,8 +398,6 @@ static void test_recv_status_on_client_twice() {
&g_state.trailing_metadata_recv;
op->data.recv_status_on_client.status = &g_state.status;
op->data.recv_status_on_client.status_details = &g_state.details;
- op->data.recv_status_on_client.status_details_capacity =
- &g_state.details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -414,7 +412,6 @@ static void test_recv_status_on_client_twice() {
op->data.recv_status_on_client.trailing_metadata = NULL;
op->data.recv_status_on_client.status = NULL;
op->data.recv_status_on_client.status_details = NULL;
- op->data.recv_status_on_client.status_details_capacity = NULL;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -453,8 +450,6 @@ static void test_recv_status_on_client_from_server() {
&g_state.trailing_metadata_recv;
op->data.recv_status_on_client.status = &g_state.status;
op->data.recv_status_on_client.status_details = &g_state.details;
- op->data.recv_status_on_client.status_details_capacity =
- &g_state.details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -474,7 +469,8 @@ static void test_send_status_from_server_with_invalid_flags() {
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 1;
op->reserved = NULL;
op++;
@@ -495,7 +491,8 @@ static void test_too_many_trailing_metadata() {
op->data.send_status_from_server.trailing_metadata_count =
(size_t)INT_MAX + 1;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -515,14 +512,15 @@ static void test_send_server_status_twice() {
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
diff --git a/test/core/end2end/no_server_test.c b/test/core/end2end/no_server_test.c
index 03ff70a188..5c0f7a0f48 100644
--- a/test/core/end2end/no_server_test.c
+++ b/test/core/end2end/no_server_test.c
@@ -52,8 +52,7 @@ int main(int argc, char **argv) {
grpc_op *op;
grpc_metadata_array trailing_metadata_recv;
grpc_status_code status;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
grpc_test_init(argc, argv);
grpc_init();
@@ -65,8 +64,10 @@ int main(int argc, char **argv) {
/* create a call, channel to a non existant server */
chan = grpc_insecure_channel_create("nonexistant:54321", NULL, NULL);
+ grpc_slice host = grpc_slice_from_static_string("nonexistant");
call = grpc_channel_create_call(chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
- "/Foo", "nonexistant", deadline, NULL);
+ grpc_slice_from_static_string("/Foo"), &host,
+ deadline, NULL);
memset(ops, 0, sizeof(ops));
op = ops;
@@ -79,7 +80,6 @@ int main(int argc, char **argv) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -101,7 +101,7 @@ int main(int argc, char **argv) {
grpc_channel_destroy(chan);
cq_verifier_destroy(cqv);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_shutdown();
diff --git a/test/core/end2end/tests/authority_not_supported.c b/test/core/end2end/tests/authority_not_supported.c
index 705970f6ca..40d217e619 100644
--- a/test/core/end2end/tests/authority_not_supported.c
+++ b/test/core/end2end/tests/authority_not_supported.c
@@ -103,9 +103,14 @@ static void test_with_authority_header(grpc_end2end_test_config config) {
grpc_byte_buffer *request_payload =
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
gpr_timespec deadline = five_seconds_time();
- grpc_metadata meta_c[2] = {
- {"key1", "val1", 4, 0, {{NULL, NULL, NULL, NULL}}},
- {"key2", "val2", 4, 0, {{NULL, NULL, NULL, NULL}}}};
+ grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"),
+ grpc_slice_from_static_string("val1"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}},
+ {grpc_slice_from_static_string("key2"),
+ grpc_slice_from_static_string("val2"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}}};
grpc_end2end_test_fixture f =
begin_test(config, "test_with_authority_header", NULL, NULL);
cq_verifier *cqv = cq_verifier_create(f.cq);
@@ -116,11 +121,12 @@ static void test_with_authority_header(grpc_end2end_test_config config) {
grpc_byte_buffer *response_payload_recv = NULL;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
+ grpc_slice host = grpc_slice_from_static_string("foo.test.google.fr");
c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
- "/foo", "foo.test.google.fr", deadline, NULL);
+ grpc_slice_from_static_string("/foo"), &host,
+ deadline, NULL);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -157,7 +163,6 @@ static void test_with_authority_header(grpc_end2end_test_config config) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -169,7 +174,7 @@ static void test_with_authority_header(grpc_end2end_test_config config) {
GPR_ASSERT(status == GRPC_STATUS_CANCELLED);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
diff --git a/test/core/end2end/tests/bad_hostname.c b/test/core/end2end/tests/bad_hostname.c
index e0c7ac7c02..f18abc78f0 100644
--- a/test/core/end2end/tests/bad_hostname.c
+++ b/test/core/end2end/tests/bad_hostname.c
@@ -109,11 +109,12 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
+ grpc_slice host = grpc_slice_from_static_string("slartibartfast.local");
c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
- "/foo", "slartibartfast.local", deadline, NULL);
+ grpc_slice_from_static_string("/foo"), &host,
+ deadline, NULL);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -141,7 +142,6 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -153,7 +153,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
GPR_ASSERT(status == GRPC_STATUS_INTERNAL);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/binary_metadata.c b/test/core/end2end/tests/binary_metadata.c
index dd7a8a9ad3..004cc9e2af 100644
--- a/test/core/end2end/tests/binary_metadata.c
+++ b/test/core/end2end/tests/binary_metadata.c
@@ -110,25 +110,25 @@ static void test_request_response_with_metadata_and_payload(
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
gpr_timespec deadline = five_seconds_time();
grpc_metadata meta_c[2] = {
- {"key1-bin",
- "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc",
- 13,
+ {grpc_slice_from_static_string("key1-bin"),
+ grpc_slice_from_static_string(
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc"),
0,
{{NULL, NULL, NULL, NULL}}},
- {"key2-bin",
- "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d",
- 14,
+ {grpc_slice_from_static_string("key2-bin"),
+ grpc_slice_from_static_string(
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d"),
0,
{{NULL, NULL, NULL, NULL}}}};
grpc_metadata meta_s[2] = {
- {"key3-bin",
- "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee",
- 15,
+ {grpc_slice_from_static_string("key3-bin"),
+ grpc_slice_from_static_string(
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee"),
0,
{{NULL, NULL, NULL, NULL}}},
- {"key4-bin",
- "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
- 16,
+ {grpc_slice_from_static_string("key4-bin"),
+ grpc_slice_from_static_string(
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"),
0,
{{NULL, NULL, NULL, NULL}}}};
grpc_end2end_test_fixture f = begin_test(
@@ -144,13 +144,13 @@ static void test_request_response_with_metadata_and_payload(
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -190,7 +190,6 @@ static void test_request_response_with_metadata_and_payload(
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -238,7 +237,7 @@ static void test_request_response_with_metadata_and_payload(
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
- op->data.send_status_from_server.status_details =
+ grpc_slice status_string = grpc_slice_from_static_string(
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12"
"\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24"
"\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36"
@@ -253,7 +252,8 @@ static void test_request_response_with_metadata_and_payload(
"\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
"\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea"
"\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc"
- "\xfd\xfe\xff";
+ "\xfd\xfe\xff");
+ op->data.send_status_from_server.status_details = &status_string;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -267,24 +267,25 @@ static void test_request_response_with_metadata_and_payload(
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(
0 ==
- strcmp(details,
- "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
- "\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
- "\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
- "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
- "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
- "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
- "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
- "\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
- "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
- "\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
- "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
- "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
- "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
- "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
- "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"
- "\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ grpc_slice_str_cmp(
+ details,
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
+ "\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
+ "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
+ "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
+ "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
+ "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
+ "\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
+ "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
+ "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
+ "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
+ "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
+ "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"
+ "\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 0);
@@ -303,7 +304,7 @@ static void test_request_response_with_metadata_and_payload(
&initial_metadata_recv, "key4-bin",
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"));
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/call_creds.c b/test/core/end2end/tests/call_creds.c
index 606938fff6..ebc854606b 100644
--- a/test/core/end2end/tests/call_creds.c
+++ b/test/core/end2end/tests/call_creds.c
@@ -156,8 +156,7 @@ static void request_response_with_payload_and_call_creds(
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
grpc_call_credentials *creds = NULL;
grpc_auth_context *s_auth_context = NULL;
@@ -167,8 +166,9 @@ static void request_response_with_payload_and_call_creds(
cqv = cq_verifier_create(f.cq);
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
creds = grpc_google_iam_credentials_create(iam_token, iam_selector, NULL);
@@ -225,7 +225,6 @@ static void request_response_with_payload_and_call_creds(
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -284,7 +283,8 @@ static void request_response_with_payload_and_call_creds(
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -296,8 +296,8 @@ static void request_response_with_payload_and_call_creds(
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_OK);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 0);
@@ -337,7 +337,7 @@ static void request_response_with_payload_and_call_creds(
break;
}
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
@@ -391,8 +391,7 @@ static void test_request_with_server_rejecting_client_creds(
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
grpc_byte_buffer *response_payload_recv = NULL;
grpc_slice request_payload_slice =
grpc_slice_from_copied_string("hello world");
@@ -404,8 +403,9 @@ static void test_request_with_server_rejecting_client_creds(
cqv = cq_verifier_create(f.cq);
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -425,7 +425,6 @@ static void test_request_with_server_rejecting_client_creds(
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -468,7 +467,7 @@ static void test_request_with_server_rejecting_client_creds(
grpc_byte_buffer_destroy(request_payload);
grpc_byte_buffer_destroy(response_payload_recv);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_call_destroy(c);
diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c
index e582c59f2d..a0bec34ec9 100644
--- a/test/core/end2end/tests/cancel_after_accept.c
+++ b/test/core/end2end/tests/cancel_after_accept.c
@@ -43,6 +43,7 @@
#include <grpc/support/useful.h>
#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/service_config.h"
@@ -118,8 +119,7 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
grpc_byte_buffer *request_payload_recv = NULL;
grpc_byte_buffer *response_payload_recv = NULL;
grpc_slice request_payload_slice =
@@ -154,8 +154,9 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
cq_verifier *cqv = cq_verifier_create(f.cq);
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/service/method",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -170,7 +171,6 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -246,12 +246,16 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
grpc_byte_buffer_destroy(response_payload);
grpc_byte_buffer_destroy(request_payload_recv);
grpc_byte_buffer_destroy(response_payload_recv);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_call_destroy(c);
grpc_call_destroy(s);
- if (args != NULL) grpc_channel_args_destroy(args);
+ if (args != NULL) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
cq_verifier_destroy(cqv);
end_test(&f);
diff --git a/test/core/end2end/tests/cancel_after_client_done.c b/test/core/end2end/tests/cancel_after_client_done.c
index 7742f9d179..63b8150cb6 100644
--- a/test/core/end2end/tests/cancel_after_client_done.c
+++ b/test/core/end2end/tests/cancel_after_client_done.c
@@ -113,8 +113,7 @@ static void test_cancel_after_accept_and_writes_closed(
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
grpc_byte_buffer *request_payload_recv = NULL;
grpc_byte_buffer *response_payload_recv = NULL;
grpc_slice request_payload_slice =
@@ -128,8 +127,9 @@ static void test_cancel_after_accept_and_writes_closed(
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -144,7 +144,6 @@ static void test_cancel_after_accept_and_writes_closed(
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -224,7 +223,7 @@ static void test_cancel_after_accept_and_writes_closed(
grpc_byte_buffer_destroy(response_payload);
grpc_byte_buffer_destroy(request_payload_recv);
grpc_byte_buffer_destroy(response_payload_recv);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_call_destroy(c);
grpc_call_destroy(s);
diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c
index c3c5418f20..216c363760 100644
--- a/test/core/end2end/tests/cancel_after_invoke.c
+++ b/test/core/end2end/tests/cancel_after_invoke.c
@@ -113,8 +113,7 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
grpc_byte_buffer *response_payload_recv = NULL;
grpc_slice request_payload_slice =
grpc_slice_from_copied_string("hello world");
@@ -122,8 +121,9 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -138,7 +138,6 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -183,7 +182,7 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
grpc_byte_buffer_destroy(request_payload);
grpc_byte_buffer_destroy(response_payload_recv);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_call_destroy(c);
diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c
index d4842829c0..c198fd1713 100644
--- a/test/core/end2end/tests/cancel_before_invoke.c
+++ b/test/core/end2end/tests/cancel_before_invoke.c
@@ -111,8 +111,7 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
grpc_byte_buffer *response_payload_recv = NULL;
grpc_slice request_payload_slice =
grpc_slice_from_copied_string("hello world");
@@ -120,8 +119,9 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config,
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -138,7 +138,6 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -181,7 +180,7 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config,
grpc_byte_buffer_destroy(request_payload);
grpc_byte_buffer_destroy(response_payload_recv);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_call_destroy(c);
diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c
index 5be850b6ea..af919805c7 100644
--- a/test/core/end2end/tests/cancel_in_a_vacuum.c
+++ b/test/core/end2end/tests/cancel_in_a_vacuum.c
@@ -106,8 +106,9 @@ static void test_cancel_in_a_vacuum(grpc_end2end_test_config config,
cq_verifier *v_client = cq_verifier_create(f.cq);
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
diff --git a/test/core/end2end/tests/cancel_with_status.c b/test/core/end2end/tests/cancel_with_status.c
index 3aecaf7159..38f8c612d1 100644
--- a/test/core/end2end/tests/cancel_with_status.c
+++ b/test/core/end2end/tests/cancel_with_status.c
@@ -108,14 +108,14 @@ static void simple_request_body(grpc_end2end_test_config config,
grpc_metadata_array trailing_metadata_recv;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
gpr_log(GPR_DEBUG, "test with %" PRIuPTR " ops", num_ops);
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -128,7 +128,6 @@ static void simple_request_body(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -156,9 +155,9 @@ static void simple_request_body(grpc_end2end_test_config config,
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
diff --git a/test/core/end2end/tests/compressed_payload.c b/test/core/end2end/tests/compressed_payload.c
index 81fc7091f8..847bc1a8c9 100644
--- a/test/core/end2end/tests/compressed_payload.c
+++ b/test/core/end2end/tests/compressed_payload.c
@@ -48,6 +48,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/call_test_only.h"
+#include "src/core/lib/transport/static_metadata.h"
#include "test/core/end2end/cq_verifier.h"
static void *tag(intptr_t t) { return (void *)t; }
@@ -125,8 +126,7 @@ static void request_for_disabled_algorithm(
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
cq_verifier *cqv;
char str[1024];
@@ -140,15 +140,20 @@ static void request_for_disabled_algorithm(
NULL, requested_client_compression_algorithm);
server_args =
grpc_channel_args_set_compression_algorithm(NULL, GRPC_COMPRESS_NONE);
- server_args = grpc_channel_args_compression_algorithm_set_state(
- &server_args, algorithm_to_disable, false);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ server_args = grpc_channel_args_compression_algorithm_set_state(
+ &exec_ctx, &server_args, algorithm_to_disable, false);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
f = begin_test(config, test_name, client_args, server_args);
cqv = cq_verifier_create(f.cq);
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -187,7 +192,6 @@ static void request_for_disabled_algorithm(
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -241,13 +245,13 @@ static void request_for_disabled_algorithm(
gpr_asprintf(&expected_details, "Compression algorithm '%s' is disabled.",
algo_name);
/* and we expect a specific reason for it */
- GPR_ASSERT(0 == strcmp(details, expected_details));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, expected_details));
gpr_free(expected_details);
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
@@ -262,8 +266,12 @@ static void request_for_disabled_algorithm(
grpc_byte_buffer_destroy(request_payload);
grpc_byte_buffer_destroy(request_payload_recv);
- grpc_channel_args_destroy(client_args);
- grpc_channel_args_destroy(server_args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, client_args);
+ grpc_channel_args_destroy(&exec_ctx, server_args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
end_test(&f);
config.tear_down_data(&f);
@@ -297,8 +305,7 @@ static void request_with_payload_template(
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
cq_verifier *cqv;
char request_str[1024];
@@ -323,8 +330,9 @@ static void request_with_payload_template(
cqv = cq_verifier_create(f.cq);
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -354,7 +362,6 @@ static void request_with_payload_template(
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -481,7 +488,8 @@ static void request_with_payload_template(
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -495,13 +503,13 @@ static void request_with_payload_template(
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_OK);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 0);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
@@ -512,8 +520,12 @@ static void request_with_payload_template(
cq_verifier_destroy(cqv);
- grpc_channel_args_destroy(client_args);
- grpc_channel_args_destroy(server_args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, client_args);
+ grpc_channel_args_destroy(&exec_ctx, server_args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
end_test(&f);
config.tear_down_data(&f);
@@ -557,17 +569,14 @@ static void test_invoke_request_with_compressed_payload_md_override(
grpc_metadata gzip_compression_override;
grpc_metadata identity_compression_override;
- gzip_compression_override.key = GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY;
- gzip_compression_override.value = "gzip";
- gzip_compression_override.value_length =
- strlen(gzip_compression_override.value);
+ gzip_compression_override.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST;
+ gzip_compression_override.value = grpc_slice_from_static_string("gzip");
memset(&gzip_compression_override.internal_data, 0,
sizeof(gzip_compression_override.internal_data));
- identity_compression_override.key = GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY;
- identity_compression_override.value = "identity";
- identity_compression_override.value_length =
- strlen(identity_compression_override.value);
+ identity_compression_override.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST;
+ identity_compression_override.value =
+ grpc_slice_from_static_string("identity");
memset(&identity_compression_override.internal_data, 0,
sizeof(identity_compression_override.internal_data));
diff --git a/test/core/end2end/tests/default_host.c b/test/core/end2end/tests/default_host.c
index 208e31697e..0c39957fa7 100644
--- a/test/core/end2end/tests/default_host.c
+++ b/test/core/end2end/tests/default_host.c
@@ -110,13 +110,13 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
char *peer;
c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
- "/foo", NULL, deadline, NULL);
+ grpc_slice_from_static_string("/foo"), NULL,
+ deadline, NULL);
GPR_ASSERT(c);
peer = grpc_call_get_peer(c);
@@ -149,7 +149,6 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -182,7 +181,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -199,12 +199,12 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
- GPR_ASSERT(0 == strncmp(call_details.host, "localhost", 9));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
+ GPR_ASSERT(grpc_slice_buf_start_eq(call_details.host, "localhost", 9));
GPR_ASSERT(was_cancelled == 1);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/disappearing_server.c b/test/core/end2end/tests/disappearing_server.c
index 8ebf7e643e..a01372144c 100644
--- a/test/core/end2end/tests/disappearing_server.c
+++ b/test/core/end2end/tests/disappearing_server.c
@@ -93,13 +93,13 @@ static void do_request_and_shutdown_server(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f->client, NULL, GRPC_PROPAGATE_DEFAULTS, f->cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f->client, NULL, GRPC_PROPAGATE_DEFAULTS, f->cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -128,7 +128,6 @@ static void do_request_and_shutdown_server(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -156,7 +155,8 @@ static void do_request_and_shutdown_server(grpc_end2end_test_config config,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -174,13 +174,13 @@ static void do_request_and_shutdown_server(grpc_end2end_test_config config,
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 1);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/empty_batch.c b/test/core/end2end/tests/empty_batch.c
index dc8e52a60f..1b420ad4cb 100644
--- a/test/core/end2end/tests/empty_batch.c
+++ b/test/core/end2end/tests/empty_batch.c
@@ -106,8 +106,9 @@ static void empty_batch_body(grpc_end2end_test_config config,
grpc_op *op = NULL;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c
index 41ae575fff..5546893ea0 100644
--- a/test/core/end2end/tests/filter_call_init_fails.c
+++ b/test/core/end2end/tests/filter_call_init_fails.c
@@ -125,12 +125,12 @@ static void test_request(grpc_end2end_test_config config) {
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -165,7 +165,6 @@ static void test_request(grpc_end2end_test_config config) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -181,9 +180,9 @@ static void test_request(grpc_end2end_test_config config) {
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
- GPR_ASSERT(0 == strcmp(details, "access denied"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
@@ -241,7 +240,8 @@ static const grpc_channel_filter test_filter = {
* Registration
*/
-static bool maybe_add_filter(grpc_channel_stack_builder *builder, void *arg) {
+static bool maybe_add_filter(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder, void *arg) {
if (g_enable_filter) {
// Want to add the filter as close to the end as possible, to make
// sure that all of the filters work well together. However, we
diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c
index bf9fd9073d..45040ab351 100644
--- a/test/core/end2end/tests/filter_causes_close.c
+++ b/test/core/end2end/tests/filter_causes_close.c
@@ -121,12 +121,12 @@ static void test_request(grpc_end2end_test_config config) {
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -161,7 +161,6 @@ static void test_request(grpc_end2end_test_config config) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -177,9 +176,10 @@ static void test_request(grpc_end2end_test_config config) {
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
- GPR_ASSERT(0 == strcmp(details, "Failure that's not preventable."));
+ GPR_ASSERT(0 ==
+ grpc_slice_str_cmp(details, "Failure that's not preventable."));
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
@@ -213,8 +213,8 @@ static void recv_im_ready(grpc_exec_ctx *exec_ctx, void *arg,
grpc_slice message =
grpc_slice_from_copied_string("Failure that's not preventable.");
grpc_transport_stream_op *op = grpc_make_transport_stream_op(NULL);
- grpc_transport_stream_op_add_close(op, GRPC_STATUS_PERMISSION_DENIED,
- &message);
+ grpc_transport_stream_op_add_close(exec_ctx, op,
+ GRPC_STATUS_PERMISSION_DENIED, &message);
grpc_call_next_op(exec_ctx, elem, op);
}
grpc_exec_ctx_sched(
@@ -268,7 +268,8 @@ static const grpc_channel_filter test_filter = {
* Registration
*/
-static bool maybe_add_filter(grpc_channel_stack_builder *builder, void *arg) {
+static bool maybe_add_filter(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder, void *arg) {
if (g_enable_filter) {
return grpc_channel_stack_builder_prepend_filter(builder, &test_filter,
NULL, NULL);
diff --git a/test/core/end2end/tests/filter_latency.c b/test/core/end2end/tests/filter_latency.c
index 37ce3b1222..e5288d5ef7 100644
--- a/test/core/end2end/tests/filter_latency.c
+++ b/test/core/end2end/tests/filter_latency.c
@@ -128,8 +128,7 @@ static void test_request(grpc_end2end_test_config config) {
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
gpr_mu_lock(&g_mu);
@@ -138,8 +137,10 @@ static void test_request(grpc_end2end_test_config config) {
gpr_mu_unlock(&g_mu);
const gpr_timespec start_time = gpr_now(GPR_CLOCK_MONOTONIC);
- c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
- "/foo", "foo.test.google.fr", deadline, NULL);
+ c = grpc_channel_create_call(
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr", config), deadline, NULL);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -173,7 +174,6 @@ static void test_request(grpc_end2end_test_config config) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -198,7 +198,8 @@ static void test_request(grpc_end2end_test_config config) {
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_string = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_string;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -215,9 +216,9 @@ static void test_request(grpc_end2end_test_config config) {
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
@@ -314,7 +315,8 @@ static const grpc_channel_filter test_server_filter = {
* Registration
*/
-static bool maybe_add_filter(grpc_channel_stack_builder *builder, void *arg) {
+static bool maybe_add_filter(grpc_exec_ctx *exec_ctx,
+ grpc_channel_stack_builder *builder, void *arg) {
grpc_channel_filter *filter = arg;
if (g_enable_filter) {
// Want to add the filter as close to the end as possible, to make
diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c
index 5fecadbe44..08af25dd28 100644
--- a/test/core/end2end/tests/graceful_server_shutdown.c
+++ b/test/core/end2end/tests/graceful_server_shutdown.c
@@ -107,13 +107,13 @@ static void test_early_server_shutdown_finishes_inflight_calls(
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -143,7 +143,6 @@ static void test_early_server_shutdown_finishes_inflight_calls(
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -171,7 +170,8 @@ static void test_early_server_shutdown_finishes_inflight_calls(
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -191,12 +191,12 @@ static void test_early_server_shutdown_finishes_inflight_calls(
grpc_call_destroy(s);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 1);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/high_initial_seqno.c b/test/core/end2end/tests/high_initial_seqno.c
index 01a4909ccd..217ca2bb72 100644
--- a/test/core/end2end/tests/high_initial_seqno.c
+++ b/test/core/end2end/tests/high_initial_seqno.c
@@ -113,13 +113,13 @@ static void simple_request_body(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -148,7 +148,6 @@ static void simple_request_body(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -172,7 +171,8 @@ static void simple_request_body(grpc_end2end_test_config config,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -189,13 +189,13 @@ static void simple_request_body(grpc_end2end_test_config config,
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 1);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/hpack_size.c b/test/core/end2end/tests/hpack_size.c
index cec8b2faae..9aedc9c143 100644
--- a/test/core/end2end/tests/hpack_size.c
+++ b/test/core/end2end/tests/hpack_size.c
@@ -254,24 +254,24 @@ static void simple_request_body(grpc_end2end_test_config config,
grpc_status_code status;
grpc_call_error error;
grpc_metadata extra_metadata[3];
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
memset(extra_metadata, 0, sizeof(extra_metadata));
- extra_metadata[0].key = "hobbit-first-name";
- extra_metadata[0].value = hobbits[index % GPR_ARRAY_SIZE(hobbits)][0];
- extra_metadata[0].value_length = strlen(extra_metadata[0].value);
- extra_metadata[1].key = "hobbit-second-name";
- extra_metadata[1].value = hobbits[index % GPR_ARRAY_SIZE(hobbits)][1];
- extra_metadata[1].value_length = strlen(extra_metadata[1].value);
- extra_metadata[2].key = "dragon";
- extra_metadata[2].value = dragons[index % GPR_ARRAY_SIZE(dragons)];
- extra_metadata[2].value_length = strlen(extra_metadata[2].value);
+ extra_metadata[0].key = grpc_slice_from_static_string("hobbit-first-name");
+ extra_metadata[0].value = grpc_slice_from_static_string(
+ hobbits[index % GPR_ARRAY_SIZE(hobbits)][0]);
+ extra_metadata[1].key = grpc_slice_from_static_string("hobbit-second-name");
+ extra_metadata[1].value = grpc_slice_from_static_string(
+ hobbits[index % GPR_ARRAY_SIZE(hobbits)][1]);
+ extra_metadata[2].key = grpc_slice_from_static_string("dragon");
+ extra_metadata[2].value =
+ grpc_slice_from_static_string(dragons[index % GPR_ARRAY_SIZE(dragons)]);
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -301,7 +301,6 @@ static void simple_request_body(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -325,7 +324,8 @@ static void simple_request_body(grpc_end2end_test_config config,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -342,13 +342,13 @@ static void simple_request_body(grpc_end2end_test_config config,
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 1);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/idempotent_request.c b/test/core/end2end/tests/idempotent_request.c
index 4f6d3bb808..2db7accaaa 100644
--- a/test/core/end2end/tests/idempotent_request.c
+++ b/test/core/end2end/tests/idempotent_request.c
@@ -111,14 +111,14 @@ static void simple_request_body(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
char *peer;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -152,7 +152,6 @@ static void simple_request_body(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -185,7 +184,8 @@ static void simple_request_body(grpc_end2end_test_config config,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -202,14 +202,14 @@ static void simple_request_body(grpc_end2end_test_config config,
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c
index 24abfa2ea0..e18953a641 100644
--- a/test/core/end2end/tests/invoke_large_request.c
+++ b/test/core/end2end/tests/invoke_large_request.c
@@ -140,13 +140,13 @@ static void test_invoke_large_request(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -185,7 +185,6 @@ static void test_invoke_large_request(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -232,7 +231,8 @@ static void test_invoke_large_request(grpc_end2end_test_config config,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -244,13 +244,13 @@ static void test_invoke_large_request(grpc_end2end_test_config config,
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 1);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/large_metadata.c b/test/core/end2end/tests/large_metadata.c
index 69b4b24b06..b45ceb2664 100644
--- a/test/core/end2end/tests/large_metadata.c
+++ b/test/core/end2end/tests/large_metadata.c
@@ -122,21 +122,19 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) {
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
- meta.key = "key";
- meta.value = gpr_malloc(large_size + 1);
- memset((char *)meta.value, 'a', large_size);
- ((char *)meta.value)[large_size] = 0;
- meta.value_length = large_size;
+ meta.key = grpc_slice_from_static_string("key");
+ meta.value = grpc_slice_malloc(large_size);
+ memset(GRPC_SLICE_START_PTR(meta.value), 'a', large_size);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
@@ -170,7 +168,6 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -216,7 +213,8 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) {
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -228,15 +226,17 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) {
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_OK);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 0);
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
- GPR_ASSERT(contains_metadata(&request_metadata_recv, "key", meta.value));
+ GPR_ASSERT(contains_metadata_slices(&request_metadata_recv,
+ grpc_slice_from_static_string("key"),
+ meta.value));
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
@@ -250,7 +250,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) {
grpc_byte_buffer_destroy(request_payload);
grpc_byte_buffer_destroy(request_payload_recv);
- gpr_free((char *)meta.value);
+ grpc_slice_unref(meta.value);
end_test(&f);
config.tear_down_data(&f);
diff --git a/test/core/end2end/tests/load_reporting_hook.c b/test/core/end2end/tests/load_reporting_hook.c
index 5b75f26bd2..edc4251119 100644
--- a/test/core/end2end/tests/load_reporting_hook.c
+++ b/test/core/end2end/tests/load_reporting_hook.c
@@ -146,13 +146,13 @@ static void request_response_with_payload(
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, method_name,
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string(method_name),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -193,7 +193,6 @@ static void request_response_with_payload(
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -242,7 +241,8 @@ static void request_response_with_payload(
op->data.send_status_from_server.trailing_metadata_count = 1;
op->data.send_status_from_server.trailing_metadata = trailing_lr_metadata;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -255,7 +255,7 @@ static void request_response_with_payload(
GPR_ASSERT(status == GRPC_STATUS_OK);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
@@ -295,15 +295,13 @@ static void test_load_reporting_hook(grpc_end2end_test_config config) {
grpc_metadata initial_lr_metadata;
grpc_metadata trailing_lr_metadata;
- initial_lr_metadata.key = GRPC_LB_TOKEN_MD_KEY;
- initial_lr_metadata.value = "client-token";
- initial_lr_metadata.value_length = strlen(initial_lr_metadata.value);
+ initial_lr_metadata.key = GRPC_MDSTR_LB_TOKEN;
+ initial_lr_metadata.value = grpc_slice_from_static_string("client-token");
memset(&initial_lr_metadata.internal_data, 0,
sizeof(initial_lr_metadata.internal_data));
- trailing_lr_metadata.key = GRPC_LB_COST_MD_KEY;
- trailing_lr_metadata.value = "server-token";
- trailing_lr_metadata.value_length = strlen(trailing_lr_metadata.value);
+ trailing_lr_metadata.key = GRPC_MDSTR_LB_COST_BIN;
+ trailing_lr_metadata.value = grpc_slice_from_static_string("server-token");
memset(&trailing_lr_metadata.internal_data, 0,
sizeof(trailing_lr_metadata.internal_data));
@@ -311,7 +309,11 @@ static void test_load_reporting_hook(grpc_end2end_test_config config) {
response_msg, &initial_lr_metadata,
&trailing_lr_metadata);
end_test(&f);
- grpc_channel_args_destroy(lr_server_args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, lr_server_args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
config.tear_down_data(&f);
}
diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c
index 9338bc5f0d..56243179b0 100644
--- a/test/core/end2end/tests/max_concurrent_streams.c
+++ b/test/core/end2end/tests/max_concurrent_streams.c
@@ -109,13 +109,13 @@ static void simple_request_body(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -144,7 +144,6 @@ static void simple_request_body(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -168,7 +167,8 @@ static void simple_request_body(grpc_end2end_test_config config,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -185,13 +185,13 @@ static void simple_request_body(grpc_end2end_test_config config,
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 1);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
@@ -223,11 +223,9 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
grpc_metadata_array trailing_metadata_recv2;
grpc_status_code status1;
grpc_call_error error;
- char *details1 = NULL;
- size_t details_capacity1 = 0;
+ grpc_slice details1;
grpc_status_code status2;
- char *details2 = NULL;
- size_t details_capacity2 = 0;
+ grpc_slice details2;
grpc_op ops[6];
grpc_op *op;
int was_cancelled;
@@ -261,13 +259,15 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
the first completes */
deadline = n_seconds_time(1000);
c1 = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/alpha",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/alpha"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c1);
c2 = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/beta",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/beta"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c2);
@@ -295,7 +295,6 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv1;
op->data.recv_status_on_client.status = &status1;
op->data.recv_status_on_client.status_details = &details1;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity1;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -327,7 +326,6 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv2;
op->data.recv_status_on_client.status = &status2;
op->data.recv_status_on_client.status_details = &details2;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity2;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -378,7 +376,8 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -413,7 +412,7 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -431,8 +430,8 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
grpc_call_destroy(c2);
grpc_call_destroy(s2);
- gpr_free(details1);
- gpr_free(details2);
+ grpc_slice_unref(details1);
+ grpc_slice_unref(details2);
grpc_metadata_array_destroy(&initial_metadata_recv1);
grpc_metadata_array_destroy(&trailing_metadata_recv1);
grpc_metadata_array_destroy(&initial_metadata_recv2);
diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c
index c222d9dfae..4140df9aad 100644
--- a/test/core/end2end/tests/max_message_length.c
+++ b/test/core/end2end/tests/max_message_length.c
@@ -43,6 +43,7 @@
#include <grpc/support/useful.h>
#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/service_config.h"
@@ -129,8 +130,7 @@ static void test_max_message_length_on_request(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
grpc_channel_args *client_args = NULL;
@@ -168,14 +168,19 @@ static void test_max_message_length_on_request(grpc_end2end_test_config config,
f = begin_test(config, "test_max_request_message_length", client_args,
server_args);
- if (client_args != NULL) grpc_channel_args_destroy(client_args);
- if (server_args != NULL) grpc_channel_args_destroy(server_args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ if (client_args != NULL) grpc_channel_args_destroy(&exec_ctx, client_args);
+ if (server_args != NULL) grpc_channel_args_destroy(&exec_ctx, server_args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
cqv = cq_verifier_create(f.cq);
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/service/method",
- get_host_override_string("foo.test.google.fr:1234", config),
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config),
gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
GPR_ASSERT(c);
@@ -209,7 +214,6 @@ static void test_max_message_length_on_request(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -248,19 +252,20 @@ static void test_max_message_length_on_request(grpc_end2end_test_config config,
CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
cq_verify(cqv);
- GPR_ASSERT(0 == strcmp(call_details.method, "/service/method"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 1);
done:
GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT);
- GPR_ASSERT(strcmp(details,
- send_limit
- ? "Sent message larger than max (11 vs. 5)"
- : "Received message larger than max (11 vs. 5)") == 0);
+ GPR_ASSERT(
+ grpc_slice_str_cmp(
+ details, send_limit
+ ? "Sent message larger than max (11 vs. 5)"
+ : "Received message larger than max (11 vs. 5)") == 0);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
@@ -303,8 +308,7 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
grpc_channel_args *client_args = NULL;
@@ -342,14 +346,19 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config,
f = begin_test(config, "test_max_response_message_length", client_args,
server_args);
- if (client_args != NULL) grpc_channel_args_destroy(client_args);
- if (server_args != NULL) grpc_channel_args_destroy(server_args);
-
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ if (client_args != NULL) grpc_channel_args_destroy(&exec_ctx, client_args);
+ if (server_args != NULL) grpc_channel_args_destroy(&exec_ctx, server_args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
cqv = cq_verifier_create(f.cq);
- c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
- "/service/method", "foo.test.google.fr:1234",
- gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+ c = grpc_channel_create_call(
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config),
+ gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
@@ -382,7 +391,6 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -416,7 +424,8 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -427,16 +436,18 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config,
CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
cq_verify(cqv);
- GPR_ASSERT(0 == strcmp(call_details.method, "/service/method"));
- GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr:1234"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ GPR_ASSERT(0 ==
+ grpc_slice_str_cmp(call_details.host, "foo.test.google.fr:1234"));
GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT);
- GPR_ASSERT(strcmp(details,
- send_limit
- ? "Sent message larger than max (11 vs. 5)"
- : "Received message larger than max (11 vs. 5)") == 0);
+ GPR_ASSERT(
+ grpc_slice_str_cmp(
+ details, send_limit
+ ? "Sent message larger than max (11 vs. 5)"
+ : "Received message larger than max (11 vs. 5)") == 0);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/negative_deadline.c b/test/core/end2end/tests/negative_deadline.c
index 929777d39e..403386b5e7 100644
--- a/test/core/end2end/tests/negative_deadline.c
+++ b/test/core/end2end/tests/negative_deadline.c
@@ -108,14 +108,14 @@ static void simple_request_body(grpc_end2end_test_config config,
grpc_metadata_array trailing_metadata_recv;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
gpr_log(GPR_DEBUG, "test with %" PRIuPTR " ops", num_ops);
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -128,7 +128,6 @@ static void simple_request_body(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -155,7 +154,7 @@ static void simple_request_body(grpc_end2end_test_config config,
GPR_ASSERT(status == GRPC_STATUS_DEADLINE_EXCEEDED);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
diff --git a/test/core/end2end/tests/network_status_change.c b/test/core/end2end/tests/network_status_change.c
index 2ebda2ccb8..6cfeaa851a 100644
--- a/test/core/end2end/tests/network_status_change.c
+++ b/test/core/end2end/tests/network_status_change.c
@@ -119,13 +119,13 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) {
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -159,7 +159,6 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -201,7 +200,8 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) {
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -214,11 +214,11 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) {
// Expected behavior of a RPC when network is lost.
GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/no_logging.c b/test/core/end2end/tests/no_logging.c
index 54614cb029..5c22631bad 100644
--- a/test/core/end2end/tests/no_logging.c
+++ b/test/core/end2end/tests/no_logging.c
@@ -139,14 +139,14 @@ static void simple_request_body(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
char *peer;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -179,7 +179,6 @@ static void simple_request_body(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -210,7 +209,8 @@ static void simple_request_body(grpc_end2end_test_config config,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -227,14 +227,14 @@ static void simple_request_body(grpc_end2end_test_config config,
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c
index db2e5c83de..dd989e3ad6 100644
--- a/test/core/end2end/tests/payload.c
+++ b/test/core/end2end/tests/payload.c
@@ -138,13 +138,13 @@ static void request_response_with_payload(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -183,7 +183,6 @@ static void request_response_with_payload(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -230,7 +229,8 @@ static void request_response_with_payload(grpc_end2end_test_config config,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -242,8 +242,8 @@ static void request_response_with_payload(grpc_end2end_test_config config,
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_OK);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 0);
@@ -251,7 +251,7 @@ static void request_response_with_payload(grpc_end2end_test_config config,
GPR_ASSERT(
byte_buffer_eq_slice(response_payload_recv, response_payload_slice));
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c
index 0a1566e9c2..b69b7f27a6 100644
--- a/test/core/end2end/tests/ping_pong_streaming.c
+++ b/test/core/end2end/tests/ping_pong_streaming.c
@@ -112,8 +112,7 @@ static void test_pingpong_streaming(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
grpc_byte_buffer *request_payload;
grpc_byte_buffer *request_payload_recv;
@@ -126,8 +125,9 @@ static void test_pingpong_streaming(grpc_end2end_test_config config,
grpc_slice_from_copied_string("hello you");
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -152,7 +152,6 @@ static void test_pingpong_streaming(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -248,7 +247,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -270,7 +270,7 @@ static void test_pingpong_streaming(grpc_end2end_test_config config,
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
- gpr_free(details);
+ grpc_slice_unref(details);
end_test(&f);
config.tear_down_data(&f);
diff --git a/test/core/end2end/tests/registered_call.c b/test/core/end2end/tests/registered_call.c
index 6594b420b9..e0716737a3 100644
--- a/test/core/end2end/tests/registered_call.c
+++ b/test/core/end2end/tests/registered_call.c
@@ -111,8 +111,7 @@ static void simple_request_body(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_registered_call(
@@ -144,7 +143,6 @@ static void simple_request_body(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -168,7 +166,8 @@ static void simple_request_body(grpc_end2end_test_config config,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -185,13 +184,13 @@ static void simple_request_body(grpc_end2end_test_config config,
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 1);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/request_with_flags.c b/test/core/end2end/tests/request_with_flags.c
index 9c18e155f3..1328a7e891 100644
--- a/test/core/end2end/tests/request_with_flags.c
+++ b/test/core/end2end/tests/request_with_flags.c
@@ -117,13 +117,13 @@ static void test_invoke_request_with_flags(
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
grpc_call_error expectation;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -157,7 +157,6 @@ static void test_invoke_request_with_flags(
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = flags_for_op[op->op];
op->reserved = NULL;
op++;
@@ -168,9 +167,9 @@ static void test_invoke_request_with_flags(
if (expectation == GRPC_CALL_OK) {
CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
cq_verify(cqv);
+ grpc_slice_unref(details);
}
- gpr_free(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c
index c84e3ac5b5..3258c0451b 100644
--- a/test/core/end2end/tests/request_with_payload.c
+++ b/test/core/end2end/tests/request_with_payload.c
@@ -116,13 +116,13 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -156,7 +156,6 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -197,7 +196,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -209,14 +209,14 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_OK);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 0);
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/resource_quota_server.c b/test/core/end2end/tests/resource_quota_server.c
index 7ec33e97a3..9c5bde2d12 100644
--- a/test/core/end2end/tests/resource_quota_server.c
+++ b/test/core/end2end/tests/resource_quota_server.c
@@ -149,8 +149,7 @@ void resource_quota_server(grpc_end2end_test_config config) {
grpc_call_details *call_details =
malloc(sizeof(grpc_call_details) * NUM_CALLS);
grpc_status_code *status = malloc(sizeof(grpc_status_code) * NUM_CALLS);
- char **details = malloc(sizeof(char *) * NUM_CALLS);
- size_t *details_capacity = malloc(sizeof(size_t) * NUM_CALLS);
+ grpc_slice *details = malloc(sizeof(grpc_slice) * NUM_CALLS);
grpc_byte_buffer **request_payload_recv =
malloc(sizeof(grpc_byte_buffer *) * NUM_CALLS);
int *was_cancelled = malloc(sizeof(int) * NUM_CALLS);
@@ -173,8 +172,6 @@ void resource_quota_server(grpc_end2end_test_config config) {
grpc_metadata_array_init(&trailing_metadata_recv[i]);
grpc_metadata_array_init(&request_metadata_recv[i]);
grpc_call_details_init(&call_details[i]);
- details[i] = NULL;
- details_capacity[i] = 0;
request_payload_recv[i] = NULL;
was_cancelled[i] = 0;
}
@@ -190,8 +187,10 @@ void resource_quota_server(grpc_end2end_test_config config) {
for (int i = 0; i < NUM_CALLS; i++) {
client_calls[i] = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- "foo.test.google.fr", n_seconds_time(60), NULL);
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr", config),
+ n_seconds_time(60), NULL);
memset(ops, 0, sizeof(ops));
op = ops;
@@ -219,8 +218,6 @@ void resource_quota_server(grpc_end2end_test_config config) {
&trailing_metadata_recv[i];
op->data.recv_status_on_client.status = &status[i];
op->data.recv_status_on_client.status_details = &details[i];
- op->data.recv_status_on_client.status_details_capacity =
- &details_capacity[i];
op->flags = 0;
op->reserved = NULL;
op++;
@@ -260,7 +257,7 @@ void resource_quota_server(grpc_end2end_test_config config) {
grpc_metadata_array_destroy(&initial_metadata_recv[call_id]);
grpc_metadata_array_destroy(&trailing_metadata_recv[call_id]);
grpc_call_destroy(client_calls[call_id]);
- gpr_free(details[call_id]);
+ grpc_slice_unref(details[call_id]);
pending_client_calls--;
} else if (ev_tag < SERVER_RECV_BASE_TAG) {
@@ -317,7 +314,8 @@ void resource_quota_server(grpc_end2end_test_config config) {
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -370,7 +368,6 @@ void resource_quota_server(grpc_end2end_test_config config) {
free(call_details);
free(status);
free(details);
- free(details_capacity);
free(request_payload_recv);
free(was_cancelled);
diff --git a/test/core/end2end/tests/server_finishes_request.c b/test/core/end2end/tests/server_finishes_request.c
index 3bb25fd924..ee18c6817b 100644
--- a/test/core/end2end/tests/server_finishes_request.c
+++ b/test/core/end2end/tests/server_finishes_request.c
@@ -111,13 +111,13 @@ static void simple_request_body(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -142,7 +142,6 @@ static void simple_request_body(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -166,7 +165,8 @@ static void simple_request_body(grpc_end2end_test_config config,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -183,13 +183,13 @@ static void simple_request_body(grpc_end2end_test_config config,
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 1);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/shutdown_finishes_calls.c b/test/core/end2end/tests/shutdown_finishes_calls.c
index b80a2e35f2..0be5315360 100644
--- a/test/core/end2end/tests/shutdown_finishes_calls.c
+++ b/test/core/end2end/tests/shutdown_finishes_calls.c
@@ -100,13 +100,13 @@ static void test_early_server_shutdown_finishes_inflight_calls(
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -136,7 +136,6 @@ static void test_early_server_shutdown_finishes_inflight_calls(
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -172,12 +171,12 @@ static void test_early_server_shutdown_finishes_inflight_calls(
grpc_server_destroy(f.server);
GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 1);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/simple_cacheable_request.c b/test/core/end2end/tests/simple_cacheable_request.c
index 2c229b08fe..ea916e7b3a 100644
--- a/test/core/end2end/tests/simple_cacheable_request.c
+++ b/test/core/end2end/tests/simple_cacheable_request.c
@@ -111,12 +111,22 @@ static void test_cacheable_request_response_with_metadata_and_payload(
grpc_byte_buffer *response_payload =
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
gpr_timespec deadline = five_seconds_time();
- grpc_metadata meta_c[2] = {
- {"key1", "val1", 4, 0, {{NULL, NULL, NULL, NULL}}},
- {"key2", "val2", 4, 0, {{NULL, NULL, NULL, NULL}}}};
- grpc_metadata meta_s[2] = {
- {"key3", "val3", 4, 0, {{NULL, NULL, NULL, NULL}}},
- {"key4", "val4", 4, 0, {{NULL, NULL, NULL, NULL}}}};
+ grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"),
+ grpc_slice_from_static_string("val1"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}},
+ {grpc_slice_from_static_string("key2"),
+ grpc_slice_from_static_string("val2"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}}};
+ grpc_metadata meta_s[2] = {{grpc_slice_from_static_string("key3"),
+ grpc_slice_from_static_string("val3"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}},
+ {grpc_slice_from_static_string("key4"),
+ grpc_slice_from_static_string("val4"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}}};
grpc_end2end_test_fixture f = begin_test(
config, "test_cacheable_request_response_with_metadata_and_payload", NULL,
NULL);
@@ -131,13 +141,13 @@ static void test_cacheable_request_response_with_metadata_and_payload(
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -177,7 +187,6 @@ static void test_cacheable_request_response_with_metadata_and_payload(
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -225,7 +234,8 @@ static void test_cacheable_request_response_with_metadata_and_payload(
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -237,8 +247,8 @@ static void test_cacheable_request_response_with_metadata_and_payload(
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_OK);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) {
@@ -254,7 +264,7 @@ static void test_cacheable_request_response_with_metadata_and_payload(
GPR_ASSERT(contains_metadata(&initial_metadata_recv, "key3", "val3"));
GPR_ASSERT(contains_metadata(&initial_metadata_recv, "key4", "val4"));
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c
index ec40c8f22d..83ad8515df 100644
--- a/test/core/end2end/tests/simple_delayed_request.c
+++ b/test/core/end2end/tests/simple_delayed_request.c
@@ -100,15 +100,15 @@ static void simple_delayed_request_body(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
config.init_client(f, client_args);
c = grpc_channel_create_call(
- f->client, NULL, GRPC_PROPAGATE_DEFAULTS, f->cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f->client, NULL, GRPC_PROPAGATE_DEFAULTS, f->cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -137,7 +137,6 @@ static void simple_delayed_request_body(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -163,7 +162,8 @@ static void simple_delayed_request_body(grpc_end2end_test_config config,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -180,13 +180,13 @@ static void simple_delayed_request_body(grpc_end2end_test_config config,
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 1);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/simple_metadata.c b/test/core/end2end/tests/simple_metadata.c
index 5490cc2b75..162c89c618 100644
--- a/test/core/end2end/tests/simple_metadata.c
+++ b/test/core/end2end/tests/simple_metadata.c
@@ -109,12 +109,22 @@ static void test_request_response_with_metadata_and_payload(
grpc_byte_buffer *response_payload =
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
gpr_timespec deadline = five_seconds_time();
- grpc_metadata meta_c[2] = {
- {"key1", "val1", 4, 0, {{NULL, NULL, NULL, NULL}}},
- {"key2", "val2", 4, 0, {{NULL, NULL, NULL, NULL}}}};
- grpc_metadata meta_s[2] = {
- {"key3", "val3", 4, 0, {{NULL, NULL, NULL, NULL}}},
- {"key4", "val4", 4, 0, {{NULL, NULL, NULL, NULL}}}};
+ grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"),
+ grpc_slice_from_static_string("val1"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}},
+ {grpc_slice_from_static_string("key2"),
+ grpc_slice_from_static_string("val2"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}}};
+ grpc_metadata meta_s[2] = {{grpc_slice_from_static_string("key3"),
+ grpc_slice_from_static_string("val3"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}},
+ {grpc_slice_from_static_string("key4"),
+ grpc_slice_from_static_string("val4"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}}};
grpc_end2end_test_fixture f = begin_test(
config, "test_request_response_with_metadata_and_payload", NULL, NULL);
cq_verifier *cqv = cq_verifier_create(f.cq);
@@ -128,13 +138,13 @@ static void test_request_response_with_metadata_and_payload(
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -174,7 +184,6 @@ static void test_request_response_with_metadata_and_payload(
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -222,7 +231,8 @@ static void test_request_response_with_metadata_and_payload(
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -234,8 +244,8 @@ static void test_request_response_with_metadata_and_payload(
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_OK);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 0);
@@ -246,7 +256,7 @@ static void test_request_response_with_metadata_and_payload(
GPR_ASSERT(contains_metadata(&initial_metadata_recv, "key3", "val3"));
GPR_ASSERT(contains_metadata(&initial_metadata_recv, "key4", "val4"));
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c
index 2dea5d6af2..e0a69826c4 100644
--- a/test/core/end2end/tests/simple_request.c
+++ b/test/core/end2end/tests/simple_request.c
@@ -111,14 +111,14 @@ static void simple_request_body(grpc_end2end_test_config config,
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
char *peer;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -152,7 +152,6 @@ static void simple_request_body(grpc_end2end_test_config config,
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -185,7 +184,8 @@ static void simple_request_body(grpc_end2end_test_config config,
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -202,14 +202,14 @@ static void simple_request_body(grpc_end2end_test_config config,
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(0 == call_details.flags);
GPR_ASSERT(was_cancelled == 1);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/streaming_error_response.c b/test/core/end2end/tests/streaming_error_response.c
index 583bc9268f..05012523a7 100644
--- a/test/core/end2end/tests/streaming_error_response.c
+++ b/test/core/end2end/tests/streaming_error_response.c
@@ -121,13 +121,13 @@ static void test(grpc_end2end_test_config config, bool request_status_early) {
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -154,7 +154,6 @@ static void test(grpc_end2end_test_config config, bool request_status_early) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
}
error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
@@ -202,7 +201,8 @@ static void test(grpc_end2end_test_config config, bool request_status_early) {
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_FAILED_PRECONDITION;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op++;
error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), NULL);
GPR_ASSERT(GRPC_CALL_OK == error);
@@ -232,7 +232,6 @@ static void test(grpc_end2end_test_config config, bool request_status_early) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), NULL);
GPR_ASSERT(GRPC_CALL_OK == error);
@@ -245,13 +244,13 @@ static void test(grpc_end2end_test_config config, bool request_status_early) {
}
GPR_ASSERT(status == GRPC_STATUS_FAILED_PRECONDITION);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(was_cancelled == 1);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/end2end/tests/trailing_metadata.c b/test/core/end2end/tests/trailing_metadata.c
index 9fd4fbc052..b6741dbf3d 100644
--- a/test/core/end2end/tests/trailing_metadata.c
+++ b/test/core/end2end/tests/trailing_metadata.c
@@ -109,15 +109,30 @@ static void test_request_response_with_metadata_and_payload(
grpc_byte_buffer *response_payload =
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
gpr_timespec deadline = five_seconds_time();
- grpc_metadata meta_c[2] = {
- {"key1", "val1", 4, 0, {{NULL, NULL, NULL, NULL}}},
- {"key2", "val2", 4, 0, {{NULL, NULL, NULL, NULL}}}};
- grpc_metadata meta_s[2] = {
- {"key3", "val3", 4, 0, {{NULL, NULL, NULL, NULL}}},
- {"key4", "val4", 4, 0, {{NULL, NULL, NULL, NULL}}}};
- grpc_metadata meta_t[2] = {
- {"key5", "val5", 4, 0, {{NULL, NULL, NULL, NULL}}},
- {"key6", "val6", 4, 0, {{NULL, NULL, NULL, NULL}}}};
+ grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"),
+ grpc_slice_from_static_string("val1"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}},
+ {grpc_slice_from_static_string("key2"),
+ grpc_slice_from_static_string("val2"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}}};
+ grpc_metadata meta_s[2] = {{grpc_slice_from_static_string("key3"),
+ grpc_slice_from_static_string("val3"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}},
+ {grpc_slice_from_static_string("key4"),
+ grpc_slice_from_static_string("val4"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}}};
+ grpc_metadata meta_t[2] = {{grpc_slice_from_static_string("key5"),
+ grpc_slice_from_static_string("val5"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}},
+ {grpc_slice_from_static_string("key6"),
+ grpc_slice_from_static_string("val6"),
+ 0,
+ {{NULL, NULL, NULL, NULL}}}};
grpc_end2end_test_fixture f = begin_test(
config, "test_request_response_with_metadata_and_payload", NULL, NULL);
cq_verifier *cqv = cq_verifier_create(f.cq);
@@ -131,13 +146,13 @@ static void test_request_response_with_metadata_and_payload(
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
int was_cancelled = 2;
c = grpc_channel_create_call(
- f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, "/foo",
- get_host_override_string("foo.test.google.fr:1234", config), deadline,
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
NULL);
GPR_ASSERT(c);
@@ -177,7 +192,6 @@ static void test_request_response_with_metadata_and_payload(
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -226,7 +240,8 @@ static void test_request_response_with_metadata_and_payload(
op->data.send_status_from_server.trailing_metadata_count = 2;
op->data.send_status_from_server.trailing_metadata = meta_t;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
- op->data.send_status_from_server.status_details = "xyz";
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -238,8 +253,8 @@ static void test_request_response_with_metadata_and_payload(
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_OK);
- GPR_ASSERT(0 == strcmp(details, "xyz"));
- GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
validate_host_override_string("foo.test.google.fr:1234", call_details.host,
config);
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
@@ -251,7 +266,7 @@ static void test_request_response_with_metadata_and_payload(
GPR_ASSERT(contains_metadata(&trailing_metadata_recv, "key5", "val5"));
GPR_ASSERT(contains_metadata(&trailing_metadata_recv, "key6", "val6"));
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
diff --git a/test/core/fling/client.c b/test/core/fling/client.c
index e717b7f7fe..bb44320f34 100644
--- a/test/core/fling/client.c
+++ b/test/core/fling/client.c
@@ -57,8 +57,7 @@ static grpc_metadata_array initial_metadata_recv;
static grpc_metadata_array trailing_metadata_recv;
static grpc_byte_buffer *response_payload_recv = NULL;
static grpc_status_code status;
-static char *details = NULL;
-static size_t details_capacity = 0;
+static grpc_slice details;
static grpc_op *op;
static void init_ping_pong_request(void) {
@@ -86,15 +85,16 @@ static void init_ping_pong_request(void) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op++;
}
static void step_ping_pong_request(void) {
GPR_TIMER_BEGIN("ping_pong", 1);
- call = grpc_channel_create_call(channel, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
- "/Reflector/reflectUnary", "localhost",
- gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+ grpc_slice host = grpc_slice_from_static_string("localhost");
+ call = grpc_channel_create_call(
+ channel, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
+ grpc_slice_from_static_string("/Reflector/reflectUnary"), &host,
+ gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call, ops,
(size_t)(op - ops),
(void *)1, NULL));
@@ -109,9 +109,11 @@ static void init_ping_pong_stream(void) {
grpc_metadata_array_init(&initial_metadata_recv);
grpc_call_error error;
- call = grpc_channel_create_call(channel, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
- "/Reflector/reflectStream", "localhost",
- gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+ grpc_slice host = grpc_slice_from_static_string("localhost");
+ call = grpc_channel_create_call(
+ channel, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
+ grpc_slice_from_static_string("/Reflector/reflectStream"), &host,
+ gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
stream_init_ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
stream_init_ops[0].data.send_initial_metadata.count = 0;
stream_init_ops[1].op = GRPC_OP_RECV_INITIAL_METADATA;
diff --git a/test/core/fling/server.c b/test/core/fling/server.c
index fd446f1128..d4849e3bbe 100644
--- a/test/core/fling/server.c
+++ b/test/core/fling/server.c
@@ -118,7 +118,7 @@ static void handle_unary_method(void) {
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
op->data.send_status_from_server.trailing_metadata_count = 0;
- op->data.send_status_from_server.status_details = "";
+ op->data.send_status_from_server.status_details = NULL;
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
@@ -168,7 +168,7 @@ static void start_send_status(void) {
status_op[0].op = GRPC_OP_SEND_STATUS_FROM_SERVER;
status_op[0].data.send_status_from_server.status = GRPC_STATUS_OK;
status_op[0].data.send_status_from_server.trailing_metadata_count = 0;
- status_op[0].data.send_status_from_server.status_details = "";
+ status_op[0].data.send_status_from_server.status_details = NULL;
status_op[1].op = GRPC_OP_RECV_CLOSE_ON_SERVER;
status_op[1].data.recv_close_on_server.cancelled = &was_cancelled;
@@ -259,8 +259,8 @@ int main(int argc, char **argv) {
switch ((intptr_t)s) {
case FLING_SERVER_NEW_REQUEST:
if (call != NULL) {
- if (0 ==
- strcmp(call_details.method, "/Reflector/reflectStream")) {
+ if (0 == grpc_slice_str_cmp(call_details.method,
+ "/Reflector/reflectStream")) {
/* Received streaming call. Send metadata here. */
start_read_op(FLING_SERVER_READ_FOR_STREAMING);
send_initial_metadata();
diff --git a/test/core/http/httpcli_test.c b/test/core/http/httpcli_test.c
index 3e312c1dde..57b779cccf 100644
--- a/test/core/http/httpcli_test.c
+++ b/test/core/http/httpcli_test.c
@@ -93,7 +93,7 @@ static void test_get(int port) {
grpc_httpcli_get(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
n_seconds_time(15),
grpc_closure_create(on_finish, &response), &response);
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
gpr_mu_lock(g_mu);
while (!g_done) {
grpc_pollset_worker *worker = NULL;
@@ -133,7 +133,7 @@ static void test_post(int port) {
grpc_httpcli_post(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
"hello", 5, n_seconds_time(15),
grpc_closure_create(on_finish, &response), &response);
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
gpr_mu_lock(g_mu);
while (!g_done) {
grpc_pollset_worker *worker = NULL;
diff --git a/test/core/http/httpscli_test.c b/test/core/http/httpscli_test.c
index d06035149e..765ae101c5 100644
--- a/test/core/http/httpscli_test.c
+++ b/test/core/http/httpscli_test.c
@@ -94,7 +94,7 @@ static void test_get(int port) {
grpc_httpcli_get(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
n_seconds_time(15),
grpc_closure_create(on_finish, &response), &response);
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
gpr_mu_lock(g_mu);
while (!g_done) {
grpc_pollset_worker *worker = NULL;
@@ -135,7 +135,7 @@ static void test_post(int port) {
grpc_httpcli_post(&exec_ctx, &g_context, &g_pops, resource_quota, &req,
"hello", 5, n_seconds_time(15),
grpc_closure_create(on_finish, &response), &response);
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
gpr_mu_lock(g_mu);
while (!g_done) {
grpc_pollset_worker *worker = NULL;
diff --git a/test/core/internal_api_canaries/iomgr.c b/test/core/internal_api_canaries/iomgr.c
index de03c47c13..82eeb0e1bf 100644
--- a/test/core/internal_api_canaries/iomgr.c
+++ b/test/core/internal_api_canaries/iomgr.c
@@ -48,7 +48,7 @@
static void test_code(void) {
/* iomgr.h */
grpc_iomgr_init();
- grpc_iomgr_shutdown();
+ grpc_iomgr_shutdown(NULL);
/* closure.h */
grpc_closure closure;
@@ -100,7 +100,7 @@ static void test_code(void) {
/* executor.h */
grpc_executor_init();
grpc_executor_push(&closure, GRPC_ERROR_CREATE("Phi"));
- grpc_executor_shutdown();
+ grpc_executor_shutdown(NULL);
/* pollset.h */
grpc_pollset_size();
diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c
index 8186ea7e85..14991c9ad9 100644
--- a/test/core/iomgr/endpoint_tests.c
+++ b/test/core/iomgr/endpoint_tests.c
@@ -41,6 +41,8 @@
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include <grpc/support/useful.h>
+
+#include "src/core/lib/slice/slice_internal.h"
#include "test/core/util/test_config.h"
/*
@@ -249,8 +251,8 @@ static void read_and_write_test(grpc_endpoint_test_config config,
grpc_exec_ctx_flush(&exec_ctx);
end_test(config);
- grpc_slice_buffer_destroy(&state.outgoing);
- grpc_slice_buffer_destroy(&state.incoming);
+ grpc_slice_buffer_destroy_internal(&exec_ctx, &state.outgoing);
+ grpc_slice_buffer_destroy_internal(&exec_ctx, &state.incoming);
grpc_endpoint_destroy(&exec_ctx, state.read_ep);
grpc_endpoint_destroy(&exec_ctx, state.write_ep);
grpc_exec_ctx_finish(&exec_ctx);
@@ -304,7 +306,7 @@ static void multiple_shutdown_test(grpc_endpoint_test_config config) {
grpc_endpoint_shutdown(&exec_ctx, f.client_ep);
wait_for_fail_count(&exec_ctx, &fail_count, 3);
- grpc_slice_buffer_destroy(&slice_buffer);
+ grpc_slice_buffer_destroy_internal(&exec_ctx, &slice_buffer);
grpc_endpoint_destroy(&exec_ctx, f.client_ep);
grpc_endpoint_destroy(&exec_ctx, f.server_ep);
diff --git a/test/core/iomgr/ev_epoll_linux_test.c b/test/core/iomgr/ev_epoll_linux_test.c
index 564b05d7f4..81e9fe855e 100644
--- a/test/core/iomgr/ev_epoll_linux_test.c
+++ b/test/core/iomgr/ev_epoll_linux_test.c
@@ -236,7 +236,12 @@ int main(int argc, char **argv) {
"strategy. and the current strategy is: '%s'",
poll_strategy);
}
- grpc_iomgr_shutdown();
+
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_iomgr_shutdown(&exec_ctx);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
return 0;
}
#else /* defined(GRPC_LINUX_EPOLL) */
diff --git a/test/core/iomgr/fd_conservation_posix_test.c b/test/core/iomgr/fd_conservation_posix_test.c
index 652b37eb6f..3dffa02c3c 100644
--- a/test/core/iomgr/fd_conservation_posix_test.c
+++ b/test/core/iomgr/fd_conservation_posix_test.c
@@ -65,6 +65,10 @@ int main(int argc, char **argv) {
grpc_resource_quota_unref(resource_quota);
- grpc_iomgr_shutdown();
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_iomgr_shutdown(&exec_ctx);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
return 0;
}
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index 6166699fe6..951a247d02 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -548,9 +548,10 @@ int main(int argc, char **argv) {
test_grpc_fd_change();
grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
- grpc_exec_ctx_finish(&exec_ctx);
+ grpc_exec_ctx_flush(&exec_ctx);
gpr_free(g_pollset);
- grpc_iomgr_shutdown();
+ grpc_iomgr_shutdown(&exec_ctx);
+ grpc_exec_ctx_finish(&exec_ctx);
return 0;
}
diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c
index 2dd0d88b3f..36ee0db97a 100644
--- a/test/core/iomgr/resolve_address_test.c
+++ b/test/core/iomgr/resolve_address_test.c
@@ -172,7 +172,11 @@ int main(int argc, char **argv) {
test_ipv6_without_port();
test_invalid_ip_addresses();
test_unparseable_hostports();
- grpc_iomgr_shutdown();
- grpc_executor_shutdown();
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_executor_shutdown(&exec_ctx);
+ grpc_iomgr_shutdown(&exec_ctx);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
return 0;
}
diff --git a/test/core/iomgr/resource_quota_test.c b/test/core/iomgr/resource_quota_test.c
index a82d44f7f8..43fb838eb4 100644
--- a/test/core/iomgr/resource_quota_test.c
+++ b/test/core/iomgr/resource_quota_test.c
@@ -36,6 +36,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include "src/core/lib/slice/slice_internal.h"
#include "test/core/util/test_config.h"
static void inc_int_cb(grpc_exec_ctx *exec_ctx, void *a, grpc_error *error) {
@@ -631,7 +632,11 @@ static void test_one_slice(void) {
GPR_ASSERT(num_allocs == start_allocs + 1);
}
- grpc_slice_buffer_destroy(&buffer);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_slice_buffer_destroy_internal(&exec_ctx, &buffer);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
destroy_user(usr);
grpc_resource_quota_unref(q);
}
@@ -667,7 +672,11 @@ static void test_one_slice_deleted_late(void) {
}
grpc_resource_quota_unref(q);
- grpc_slice_buffer_destroy(&buffer);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_slice_buffer_destroy_internal(&exec_ctx, &buffer);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
}
int main(int argc, char **argv) {
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index 5eafa570bb..065064fe1e 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -50,6 +50,8 @@
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include <grpc/support/useful.h>
+
+#include "src/core/lib/slice/slice_internal.h"
#include "test/core/iomgr/endpoint_tests.h"
#include "test/core/util/test_config.h"
@@ -184,7 +186,7 @@ static void read_test(size_t num_bytes, size_t slice_size) {
grpc_resource_quota *resource_quota = grpc_resource_quota_create("read_test");
ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), resource_quota,
slice_size, "test");
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
written_bytes = fill_socket_partial(sv[0], num_bytes);
@@ -212,7 +214,7 @@ static void read_test(size_t num_bytes, size_t slice_size) {
GPR_ASSERT(state.read_bytes == state.target_read_bytes);
gpr_mu_unlock(g_mu);
- grpc_slice_buffer_destroy(&state.incoming);
+ grpc_slice_buffer_destroy_internal(&exec_ctx, &state.incoming);
grpc_endpoint_destroy(&exec_ctx, ep);
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -235,7 +237,7 @@ static void large_read_test(size_t slice_size) {
grpc_resource_quota_create("large_read_test");
ep = grpc_tcp_create(grpc_fd_create(sv[1], "large_read_test"), resource_quota,
slice_size, "test");
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
written_bytes = fill_socket(sv[0]);
@@ -263,7 +265,7 @@ static void large_read_test(size_t slice_size) {
GPR_ASSERT(state.read_bytes == state.target_read_bytes);
gpr_mu_unlock(g_mu);
- grpc_slice_buffer_destroy(&state.incoming);
+ grpc_slice_buffer_destroy_internal(&exec_ctx, &state.incoming);
grpc_endpoint_destroy(&exec_ctx, ep);
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -374,7 +376,7 @@ static void write_test(size_t num_bytes, size_t slice_size) {
grpc_resource_quota_create("write_test");
ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test"), resource_quota,
GRPC_TCP_DEFAULT_READ_SLICE_SIZE, "test");
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
state.ep = ep;
@@ -404,7 +406,7 @@ static void write_test(size_t num_bytes, size_t slice_size) {
}
gpr_mu_unlock(g_mu);
- grpc_slice_buffer_destroy(&outgoing);
+ grpc_slice_buffer_destroy_internal(&exec_ctx, &outgoing);
grpc_endpoint_destroy(&exec_ctx, ep);
gpr_free(slices);
grpc_exec_ctx_finish(&exec_ctx);
@@ -442,7 +444,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), resource_quota,
slice_size, "test");
GPR_ASSERT(grpc_tcp_fd(ep) == sv[1] && sv[1] >= 0);
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
written_bytes = fill_socket_partial(sv[0], num_bytes);
@@ -472,7 +474,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) {
GPR_ASSERT(state.read_bytes == state.target_read_bytes);
gpr_mu_unlock(g_mu);
- grpc_slice_buffer_destroy(&state.incoming);
+ grpc_slice_buffer_destroy_internal(&exec_ctx, &state.incoming);
grpc_tcp_destroy_and_release_fd(&exec_ctx, ep, &fd, &fd_released_cb);
grpc_exec_ctx_flush(&exec_ctx);
gpr_mu_lock(g_mu);
@@ -534,7 +536,7 @@ static grpc_endpoint_test_fixture create_fixture_tcp_socketpair(
resource_quota, slice_size, "test");
f.server_ep = grpc_tcp_create(grpc_fd_create(sv[1], "fixture:server"),
resource_quota, slice_size, "test");
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
grpc_endpoint_add_to_pollset(&exec_ctx, f.client_ep, g_pollset);
grpc_endpoint_add_to_pollset(&exec_ctx, f.server_ep, g_pollset);
diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c
index 9bea229466..6bd6d60604 100644
--- a/test/core/iomgr/udp_server_test.c
+++ b/test/core/iomgr/udp_server_test.c
@@ -238,7 +238,7 @@ int main(int argc, char **argv) {
grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
grpc_exec_ctx_finish(&exec_ctx);
gpr_free(g_pollset);
- grpc_iomgr_shutdown();
+ grpc_shutdown();
return 0;
}
diff --git a/test/core/security/b64_test.c b/test/core/security/b64_test.c
index af883f51e9..28af48075e 100644
--- a/test/core/security/b64_test.c
+++ b/test/core/security/b64_test.c
@@ -38,6 +38,8 @@
#include <grpc/slice.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "test/core/util/test_config.h"
static int buffers_are_equal(const unsigned char *buf1,
@@ -57,12 +59,14 @@ static void test_simple_encode_decode_b64(int url_safe, int multiline) {
const char *hello = "hello";
char *hello_b64 =
grpc_base64_encode(hello, strlen(hello), url_safe, multiline);
- grpc_slice hello_slice = grpc_base64_decode(hello_b64, url_safe);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_slice hello_slice = grpc_base64_decode(&exec_ctx, hello_b64, url_safe);
GPR_ASSERT(GRPC_SLICE_LENGTH(hello_slice) == strlen(hello));
GPR_ASSERT(strncmp((const char *)GRPC_SLICE_START_PTR(hello_slice), hello,
GRPC_SLICE_LENGTH(hello_slice)) == 0);
- grpc_slice_unref(hello_slice);
+ grpc_slice_unref_internal(&exec_ctx, hello_slice);
+ grpc_exec_ctx_finish(&exec_ctx);
gpr_free(hello_b64);
}
@@ -75,13 +79,15 @@ static void test_full_range_encode_decode_b64(int url_safe, int multiline) {
/* Try all the different paddings. */
for (i = 0; i < 3; i++) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
b64 = grpc_base64_encode(orig, sizeof(orig) - i, url_safe, multiline);
- orig_decoded = grpc_base64_decode(b64, url_safe);
+ orig_decoded = grpc_base64_decode(&exec_ctx, b64, url_safe);
GPR_ASSERT(GRPC_SLICE_LENGTH(orig_decoded) == (sizeof(orig) - i));
GPR_ASSERT(buffers_are_equal(orig, GRPC_SLICE_START_PTR(orig_decoded),
sizeof(orig) - i));
- grpc_slice_unref(orig_decoded);
+ grpc_slice_unref_internal(&exec_ctx, orig_decoded);
gpr_free(b64);
+ grpc_exec_ctx_finish(&exec_ctx);
}
}
@@ -117,7 +123,7 @@ static void test_full_range_encode_decode_b64_urlsafe_multiline(void) {
test_full_range_encode_decode_b64(1, 1);
}
-static void test_url_safe_unsafe_mismtach_failure(void) {
+static void test_url_safe_unsafe_mismatch_failure(void) {
unsigned char orig[256];
size_t i;
char *b64;
@@ -125,17 +131,19 @@ static void test_url_safe_unsafe_mismtach_failure(void) {
int url_safe = 1;
for (i = 0; i < sizeof(orig); i++) orig[i] = (uint8_t)i;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
b64 = grpc_base64_encode(orig, sizeof(orig), url_safe, 0);
- orig_decoded = grpc_base64_decode(b64, !url_safe);
+ orig_decoded = grpc_base64_decode(&exec_ctx, b64, !url_safe);
GPR_ASSERT(GRPC_SLICE_IS_EMPTY(orig_decoded));
gpr_free(b64);
- grpc_slice_unref(orig_decoded);
+ grpc_slice_unref_internal(&exec_ctx, orig_decoded);
b64 = grpc_base64_encode(orig, sizeof(orig), !url_safe, 0);
- orig_decoded = grpc_base64_decode(b64, url_safe);
+ orig_decoded = grpc_base64_decode(&exec_ctx, b64, url_safe);
GPR_ASSERT(GRPC_SLICE_IS_EMPTY(orig_decoded));
gpr_free(b64);
- grpc_slice_unref(orig_decoded);
+ grpc_slice_unref_internal(&exec_ctx, orig_decoded);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_rfc4648_test_vectors(void) {
@@ -173,38 +181,40 @@ static void test_rfc4648_test_vectors(void) {
static void test_unpadded_decode(void) {
grpc_slice decoded;
- decoded = grpc_base64_decode("Zm9vYmFy", 0);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ decoded = grpc_base64_decode(&exec_ctx, "Zm9vYmFy", 0);
GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
GPR_ASSERT(grpc_slice_str_cmp(decoded, "foobar") == 0);
grpc_slice_unref(decoded);
- decoded = grpc_base64_decode("Zm9vYmE", 0);
+ decoded = grpc_base64_decode(&exec_ctx, "Zm9vYmE", 0);
GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
GPR_ASSERT(grpc_slice_str_cmp(decoded, "fooba") == 0);
grpc_slice_unref(decoded);
- decoded = grpc_base64_decode("Zm9vYg", 0);
+ decoded = grpc_base64_decode(&exec_ctx, "Zm9vYg", 0);
GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
GPR_ASSERT(grpc_slice_str_cmp(decoded, "foob") == 0);
grpc_slice_unref(decoded);
- decoded = grpc_base64_decode("Zm9v", 0);
+ decoded = grpc_base64_decode(&exec_ctx, "Zm9v", 0);
GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
GPR_ASSERT(grpc_slice_str_cmp(decoded, "foo") == 0);
grpc_slice_unref(decoded);
- decoded = grpc_base64_decode("Zm8", 0);
+ decoded = grpc_base64_decode(&exec_ctx, "Zm8", 0);
GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
GPR_ASSERT(grpc_slice_str_cmp(decoded, "fo") == 0);
grpc_slice_unref(decoded);
- decoded = grpc_base64_decode("Zg", 0);
+ decoded = grpc_base64_decode(&exec_ctx, "Zg", 0);
GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(decoded));
GPR_ASSERT(grpc_slice_str_cmp(decoded, "f") == 0);
grpc_slice_unref(decoded);
- decoded = grpc_base64_decode("", 0);
+ decoded = grpc_base64_decode(&exec_ctx, "", 0);
GPR_ASSERT(GRPC_SLICE_IS_EMPTY(decoded));
+ grpc_exec_ctx_finish(&exec_ctx);
}
int main(int argc, char **argv) {
@@ -217,7 +227,7 @@ int main(int argc, char **argv) {
test_full_range_encode_decode_b64_multiline();
test_full_range_encode_decode_b64_urlsafe_no_multiline();
test_full_range_encode_decode_b64_urlsafe_multiline();
- test_url_safe_unsafe_mismtach_failure();
+ test_url_safe_unsafe_mismatch_failure();
test_rfc4648_test_vectors();
test_unpadded_decode();
return 0;
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index d4c755088d..c8c6eebd60 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -166,24 +166,29 @@ static grpc_httpcli_response http_response(int status, const char *body) {
/* -- Tests. -- */
static void test_empty_md_store(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
GPR_ASSERT(store->num_entries == 0);
GPR_ASSERT(store->allocated == 0);
- grpc_credentials_md_store_unref(store);
+ grpc_credentials_md_store_unref(&exec_ctx, store);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_ref_unref_empty_md_store(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
grpc_credentials_md_store_ref(store);
grpc_credentials_md_store_ref(store);
GPR_ASSERT(store->num_entries == 0);
GPR_ASSERT(store->allocated == 0);
- grpc_credentials_md_store_unref(store);
- grpc_credentials_md_store_unref(store);
- grpc_credentials_md_store_unref(store);
+ grpc_credentials_md_store_unref(&exec_ctx, store);
+ grpc_credentials_md_store_unref(&exec_ctx, store);
+ grpc_credentials_md_store_unref(&exec_ctx, store);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_add_to_empty_md_store(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
const char *key_str = "hello";
const char *value_str = "there blah blah blah blah blah blah blah";
@@ -195,10 +200,12 @@ static void test_add_to_empty_md_store(void) {
GPR_ASSERT(grpc_slice_cmp(value, store->entries[0].value) == 0);
grpc_slice_unref(key);
grpc_slice_unref(value);
- grpc_credentials_md_store_unref(store);
+ grpc_credentials_md_store_unref(&exec_ctx, store);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_add_cstrings_to_empty_md_store(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
const char *key_str = "hello";
const char *value_str = "there blah blah blah blah blah blah blah";
@@ -206,18 +213,22 @@ static void test_add_cstrings_to_empty_md_store(void) {
GPR_ASSERT(store->num_entries == 1);
GPR_ASSERT(grpc_slice_str_cmp(store->entries[0].key, key_str) == 0);
GPR_ASSERT(grpc_slice_str_cmp(store->entries[0].value, value_str) == 0);
- grpc_credentials_md_store_unref(store);
+ grpc_credentials_md_store_unref(&exec_ctx, store);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_empty_preallocated_md_store(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_credentials_md_store *store = grpc_credentials_md_store_create(4);
GPR_ASSERT(store->num_entries == 0);
GPR_ASSERT(store->allocated == 4);
GPR_ASSERT(store->entries != NULL);
- grpc_credentials_md_store_unref(store);
+ grpc_credentials_md_store_unref(&exec_ctx, store);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_add_abunch_to_md_store(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_credentials_md_store *store = grpc_credentials_md_store_create(4);
size_t num_entries = 1000;
const char *key_str = "hello";
@@ -230,16 +241,19 @@ static void test_add_abunch_to_md_store(void) {
GPR_ASSERT(grpc_slice_str_cmp(store->entries[i].key, key_str) == 0);
GPR_ASSERT(grpc_slice_str_cmp(store->entries[i].value, value_str) == 0);
}
- grpc_credentials_md_store_unref(store);
+ grpc_credentials_md_store_unref(&exec_ctx, store);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_oauth2_token_fetcher_creds_parsing_ok(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_credentials_md_store *token_md = NULL;
gpr_timespec token_lifetime;
grpc_httpcli_response response =
http_response(200, valid_oauth2_json_response);
GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
- &response, &token_md, &token_lifetime) == GRPC_CREDENTIALS_OK);
+ &exec_ctx, &response, &token_md, &token_lifetime) ==
+ GRPC_CREDENTIALS_OK);
GPR_ASSERT(token_lifetime.tv_sec == 3599);
GPR_ASSERT(token_lifetime.tv_nsec == 0);
GPR_ASSERT(token_md->num_entries == 1);
@@ -248,32 +262,38 @@ static void test_oauth2_token_fetcher_creds_parsing_ok(void) {
GPR_ASSERT(grpc_slice_str_cmp(token_md->entries[0].value,
"Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") ==
0);
- grpc_credentials_md_store_unref(token_md);
+ grpc_credentials_md_store_unref(&exec_ctx, token_md);
grpc_http_response_destroy(&response);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_oauth2_token_fetcher_creds_parsing_bad_http_status(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_credentials_md_store *token_md = NULL;
gpr_timespec token_lifetime;
grpc_httpcli_response response =
http_response(401, valid_oauth2_json_response);
GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
- &response, &token_md, &token_lifetime) ==
+ &exec_ctx, &response, &token_md, &token_lifetime) ==
GRPC_CREDENTIALS_ERROR);
grpc_http_response_destroy(&response);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_oauth2_token_fetcher_creds_parsing_empty_http_body(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_credentials_md_store *token_md = NULL;
gpr_timespec token_lifetime;
grpc_httpcli_response response = http_response(200, "");
GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
- &response, &token_md, &token_lifetime) ==
+ &exec_ctx, &response, &token_md, &token_lifetime) ==
GRPC_CREDENTIALS_ERROR);
grpc_http_response_destroy(&response);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_credentials_md_store *token_md = NULL;
gpr_timespec token_lifetime;
grpc_httpcli_response response =
@@ -282,12 +302,14 @@ static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) {
" \"expires_in\":3599, "
" \"token_type\":\"Bearer\"");
GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
- &response, &token_md, &token_lifetime) ==
+ &exec_ctx, &response, &token_md, &token_lifetime) ==
GRPC_CREDENTIALS_ERROR);
grpc_http_response_destroy(&response);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_oauth2_token_fetcher_creds_parsing_missing_token(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_credentials_md_store *token_md = NULL;
gpr_timespec token_lifetime;
grpc_httpcli_response response = http_response(200,
@@ -295,12 +317,14 @@ static void test_oauth2_token_fetcher_creds_parsing_missing_token(void) {
" \"expires_in\":3599, "
" \"token_type\":\"Bearer\"}");
GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
- &response, &token_md, &token_lifetime) ==
+ &exec_ctx, &response, &token_md, &token_lifetime) ==
GRPC_CREDENTIALS_ERROR);
grpc_http_response_destroy(&response);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_oauth2_token_fetcher_creds_parsing_missing_token_type(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_credentials_md_store *token_md = NULL;
gpr_timespec token_lifetime;
grpc_httpcli_response response =
@@ -309,13 +333,15 @@ static void test_oauth2_token_fetcher_creds_parsing_missing_token_type(void) {
" \"expires_in\":3599, "
"}");
GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
- &response, &token_md, &token_lifetime) ==
+ &exec_ctx, &response, &token_md, &token_lifetime) ==
GRPC_CREDENTIALS_ERROR);
grpc_http_response_destroy(&response);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime(
void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_credentials_md_store *token_md = NULL;
gpr_timespec token_lifetime;
grpc_httpcli_response response =
@@ -323,9 +349,10 @@ static void test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime(
"{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
" \"token_type\":\"Bearer\"}");
GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
- &response, &token_md, &token_lifetime) ==
+ &exec_ctx, &response, &token_md, &token_lifetime) ==
GRPC_CREDENTIALS_ERROR);
grpc_http_response_destroy(&response);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void check_metadata(expected_md *expected, grpc_credentials_md *md_elems,
@@ -361,7 +388,7 @@ static void check_google_iam_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
GPR_ASSERT(error_details == NULL);
GPR_ASSERT(num_md == 2);
check_metadata(emd, md_elems, num_md);
- grpc_call_credentials_unref(c);
+ grpc_call_credentials_unref(exec_ctx, c);
}
static void test_google_iam_creds(void) {
@@ -385,7 +412,7 @@ static void check_access_token_metadata(
GPR_ASSERT(error_details == NULL);
GPR_ASSERT(num_md == 1);
check_metadata(emd, md_elems, num_md);
- grpc_call_credentials_unref(c);
+ grpc_call_credentials_unref(exec_ctx, c);
}
static void test_access_token_creds(void) {
@@ -401,9 +428,10 @@ static void test_access_token_creds(void) {
}
static grpc_security_status check_channel_oauth2_create_security_connector(
- grpc_channel_credentials *c, grpc_call_credentials *call_creds,
- const char *target, const grpc_channel_args *args,
- grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+ grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c,
+ grpc_call_credentials *call_creds, const char *target,
+ const grpc_channel_args *args, grpc_channel_security_connector **sc,
+ grpc_channel_args **new_args) {
GPR_ASSERT(strcmp(c->type, "mock") == 0);
GPR_ASSERT(call_creds != NULL);
GPR_ASSERT(strcmp(call_creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
@@ -411,6 +439,7 @@ static grpc_security_status check_channel_oauth2_create_security_connector(
}
static void test_channel_oauth2_composite_creds(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_channel_args *new_args;
grpc_channel_credentials_vtable vtable = {
NULL, check_channel_oauth2_create_security_connector, NULL};
@@ -424,9 +453,10 @@ static void test_channel_oauth2_composite_creds(void) {
grpc_channel_credentials_release(channel_creds);
grpc_call_credentials_release(oauth2_creds);
GPR_ASSERT(grpc_channel_credentials_create_security_connector(
- channel_oauth2_creds, NULL, NULL, NULL, &new_args) ==
- GRPC_SECURITY_OK);
+ &exec_ctx, channel_oauth2_creds, NULL, NULL, NULL,
+ &new_args) == GRPC_SECURITY_OK);
grpc_channel_credentials_release(channel_oauth2_creds);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void check_oauth2_google_iam_composite_metadata(
@@ -443,7 +473,7 @@ static void check_oauth2_google_iam_composite_metadata(
GPR_ASSERT(error_details == NULL);
GPR_ASSERT(num_md == 3);
check_metadata(emd, md_elems, num_md);
- grpc_call_credentials_unref(c);
+ grpc_call_credentials_unref(exec_ctx, c);
}
static void test_oauth2_google_iam_composite_creds(void) {
@@ -459,8 +489,8 @@ static void test_oauth2_google_iam_composite_creds(void) {
grpc_call_credentials *composite_creds =
grpc_composite_call_credentials_create(oauth2_creds, google_iam_creds,
NULL);
- grpc_call_credentials_unref(oauth2_creds);
- grpc_call_credentials_unref(google_iam_creds);
+ grpc_call_credentials_unref(&exec_ctx, oauth2_creds);
+ grpc_call_credentials_unref(&exec_ctx, google_iam_creds);
GPR_ASSERT(
strcmp(composite_creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0);
creds_array =
@@ -478,9 +508,10 @@ static void test_oauth2_google_iam_composite_creds(void) {
static grpc_security_status
check_channel_oauth2_google_iam_create_security_connector(
- grpc_channel_credentials *c, grpc_call_credentials *call_creds,
- const char *target, const grpc_channel_args *args,
- grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+ grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c,
+ grpc_call_credentials *call_creds, const char *target,
+ const grpc_channel_args *args, grpc_channel_security_connector **sc,
+ grpc_channel_args **new_args) {
const grpc_call_credentials_array *creds_array;
GPR_ASSERT(strcmp(c->type, "mock") == 0);
GPR_ASSERT(call_creds != NULL);
@@ -495,6 +526,7 @@ check_channel_oauth2_google_iam_create_security_connector(
}
static void test_channel_oauth2_google_iam_composite_creds(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_channel_args *new_args;
grpc_channel_credentials_vtable vtable = {
NULL, check_channel_oauth2_google_iam_create_security_connector, NULL};
@@ -517,10 +549,11 @@ static void test_channel_oauth2_google_iam_composite_creds(void) {
grpc_call_credentials_release(google_iam_creds);
GPR_ASSERT(grpc_channel_credentials_create_security_connector(
- channel_oauth2_iam_creds, NULL, NULL, NULL, &new_args) ==
- GRPC_SECURITY_OK);
+ &exec_ctx, channel_oauth2_iam_creds, NULL, NULL, NULL,
+ &new_args) == GRPC_SECURITY_OK);
grpc_channel_credentials_release(channel_oauth2_iam_creds);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void on_oauth2_creds_get_metadata_success(
@@ -619,7 +652,7 @@ static void test_compute_engine_creds_success(void) {
on_oauth2_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_finish(&exec_ctx);
- grpc_call_credentials_unref(compute_engine_creds);
+ grpc_call_credentials_unref(&exec_ctx, compute_engine_creds);
grpc_httpcli_set_override(NULL, NULL);
}
@@ -634,7 +667,7 @@ static void test_compute_engine_creds_failure(void) {
grpc_call_credentials_get_request_metadata(
&exec_ctx, compute_engine_creds, NULL, auth_md_ctx,
on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
- grpc_call_credentials_unref(compute_engine_creds);
+ grpc_call_credentials_unref(&exec_ctx, compute_engine_creds);
grpc_httpcli_set_override(NULL, NULL);
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -706,7 +739,7 @@ static void test_refresh_token_creds_success(void) {
on_oauth2_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_flush(&exec_ctx);
- grpc_call_credentials_unref(refresh_token_creds);
+ grpc_call_credentials_unref(&exec_ctx, refresh_token_creds);
grpc_httpcli_set_override(NULL, NULL);
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -723,7 +756,7 @@ static void test_refresh_token_creds_failure(void) {
grpc_call_credentials_get_request_metadata(
&exec_ctx, refresh_token_creds, NULL, auth_md_ctx,
on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
- grpc_call_credentials_unref(refresh_token_creds);
+ grpc_call_credentials_unref(&exec_ctx, refresh_token_creds);
grpc_httpcli_set_override(NULL, NULL);
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -832,7 +865,7 @@ static void test_jwt_creds_success(void) {
grpc_exec_ctx_flush(&exec_ctx);
gpr_free(json_key_string);
- grpc_call_credentials_unref(jwt_creds);
+ grpc_call_credentials_unref(&exec_ctx, jwt_creds);
grpc_jwt_encode_and_sign_set_override(NULL);
}
@@ -851,7 +884,7 @@ static void test_jwt_creds_signing_failure(void) {
on_jwt_creds_get_metadata_failure, (void *)test_user_data);
gpr_free(json_key_string);
- grpc_call_credentials_unref(jwt_creds);
+ grpc_call_credentials_unref(&exec_ctx, jwt_creds);
grpc_jwt_encode_and_sign_set_override(NULL);
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -870,6 +903,7 @@ static void set_google_default_creds_env_var_with_file_contents(
}
static void test_google_default_creds_auth_key(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_service_account_jwt_access_credentials *jwt;
grpc_composite_channel_credentials *creds;
char *json_key = test_json_key_str();
@@ -885,11 +919,13 @@ static void test_google_default_creds_auth_key(void) {
strcmp(jwt->key.client_id,
"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent.com") ==
0);
- grpc_channel_credentials_unref(&creds->base);
+ grpc_channel_credentials_unref(&exec_ctx, &creds->base);
gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_google_default_creds_refresh_token(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_google_refresh_token_credentials *refresh;
grpc_composite_channel_credentials *creds;
grpc_flush_cached_google_default_credentials();
@@ -901,8 +937,9 @@ static void test_google_default_creds_refresh_token(void) {
refresh = (grpc_google_refresh_token_credentials *)creds->call_creds;
GPR_ASSERT(strcmp(refresh->refresh_token.client_id,
"32555999999.apps.googleusercontent.com") == 0);
- grpc_channel_credentials_unref(&creds->base);
+ grpc_channel_credentials_unref(&exec_ctx, &creds->base);
gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
+ grpc_exec_ctx_finish(&exec_ctx);
}
static int default_creds_gce_detection_httpcli_get_success_override(
@@ -1028,9 +1065,8 @@ static void plugin_get_metadata_success(void *state,
*s = PLUGIN_GET_METADATA_CALLED_STATE;
for (i = 0; i < GPR_ARRAY_SIZE(plugin_md); i++) {
memset(&md[i], 0, sizeof(grpc_metadata));
- md[i].key = plugin_md[i].key;
- md[i].value = plugin_md[i].value;
- md[i].value_length = strlen(plugin_md[i].value);
+ md[i].key = grpc_slice_from_copied_string(plugin_md[i].key);
+ md[i].value = grpc_slice_from_copied_string(plugin_md[i].value);
}
cb(user_data, md, GPR_ARRAY_SIZE(md), GRPC_STATUS_OK, NULL);
}
@@ -1142,6 +1178,8 @@ static void test_get_well_known_google_credentials_file_path(void) {
}
static void test_channel_creds_duplicate_without_call_creds(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
grpc_channel_credentials *channel_creds =
grpc_fake_transport_security_credentials_create();
@@ -1149,21 +1187,23 @@ static void test_channel_creds_duplicate_without_call_creds(void) {
grpc_channel_credentials_duplicate_without_call_credentials(
channel_creds);
GPR_ASSERT(dup == channel_creds);
- grpc_channel_credentials_unref(dup);
+ grpc_channel_credentials_unref(&exec_ctx, dup);
grpc_call_credentials *call_creds =
grpc_access_token_credentials_create("blah", NULL);
grpc_channel_credentials *composite_creds =
grpc_composite_channel_credentials_create(channel_creds, call_creds,
NULL);
- grpc_call_credentials_unref(call_creds);
+ grpc_call_credentials_unref(&exec_ctx, call_creds);
dup = grpc_channel_credentials_duplicate_without_call_credentials(
composite_creds);
GPR_ASSERT(dup == channel_creds);
- grpc_channel_credentials_unref(dup);
+ grpc_channel_credentials_unref(&exec_ctx, dup);
- grpc_channel_credentials_unref(channel_creds);
- grpc_channel_credentials_unref(composite_creds);
+ grpc_channel_credentials_unref(&exec_ctx, channel_creds);
+ grpc_channel_credentials_unref(&exec_ctx, composite_creds);
+
+ grpc_exec_ctx_finish(&exec_ctx);
}
int main(int argc, char **argv) {
diff --git a/test/core/security/json_token_test.c b/test/core/security/json_token_test.c
index 201655881f..5cebb09bb2 100644
--- a/test/core/security/json_token_test.c
+++ b/test/core/security/json_token_test.c
@@ -44,6 +44,7 @@
#include "src/core/lib/json/json.h"
#include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
#include "src/core/lib/security/util/b64.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "test/core/util/test_config.h"
/* This JSON key was generated with the GCE console and revoked immediately.
@@ -220,6 +221,7 @@ static void test_parse_json_key_failure_no_private_key(void) {
static grpc_json *parse_json_part_from_jwt(const char *str, size_t len,
char **scratchpad) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
char *b64;
char *decoded;
grpc_json *json;
@@ -227,7 +229,7 @@ static grpc_json *parse_json_part_from_jwt(const char *str, size_t len,
b64 = gpr_malloc(len + 1);
strncpy(b64, str, len);
b64[len] = '\0';
- slice = grpc_base64_decode(b64, 1);
+ slice = grpc_base64_decode(&exec_ctx, b64, 1);
GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(slice));
decoded = gpr_malloc(GRPC_SLICE_LENGTH(slice) + 1);
strncpy(decoded, (const char *)GRPC_SLICE_START_PTR(slice),
@@ -237,6 +239,7 @@ static grpc_json *parse_json_part_from_jwt(const char *str, size_t len,
gpr_free(b64);
*scratchpad = decoded;
grpc_slice_unref(slice);
+ grpc_exec_ctx_finish(&exec_ctx);
return json;
}
@@ -338,10 +341,12 @@ static void check_jwt_claim(grpc_json *claim, const char *expected_audience,
static void check_jwt_signature(const char *b64_signature, RSA *rsa_key,
const char *signed_data,
size_t signed_data_size) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
EVP_MD_CTX *md_ctx = EVP_MD_CTX_create();
EVP_PKEY *key = EVP_PKEY_new();
- grpc_slice sig = grpc_base64_decode(b64_signature, 1);
+ grpc_slice sig = grpc_base64_decode(&exec_ctx, b64_signature, 1);
GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(sig));
GPR_ASSERT(GRPC_SLICE_LENGTH(sig) == 128);
@@ -355,9 +360,11 @@ static void check_jwt_signature(const char *b64_signature, RSA *rsa_key,
GPR_ASSERT(EVP_DigestVerifyFinal(md_ctx, GRPC_SLICE_START_PTR(sig),
GRPC_SLICE_LENGTH(sig)) == 1);
- grpc_slice_unref(sig);
+ grpc_slice_unref_internal(&exec_ctx, sig);
if (key != NULL) EVP_PKEY_free(key);
if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx);
+
+ grpc_exec_ctx_finish(&exec_ctx);
}
static char *service_account_creds_jwt_encode_and_sign(
diff --git a/test/core/security/jwt_verifier_test.c b/test/core/security/jwt_verifier_test.c
index f8afba8d6d..71da935eeb 100644
--- a/test/core/security/jwt_verifier_test.c
+++ b/test/core/security/jwt_verifier_test.c
@@ -185,7 +185,8 @@ static void test_claims_success(void) {
grpc_json *json = grpc_json_parse_string_with_len(
(char *)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s));
GPR_ASSERT(json != NULL);
- claims = grpc_jwt_claims_from_json(json, s);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ claims = grpc_jwt_claims_from_json(&exec_ctx, json, s);
GPR_ASSERT(claims != NULL);
GPR_ASSERT(grpc_jwt_claims_json(claims) == json);
GPR_ASSERT(strcmp(grpc_jwt_claims_audience(claims), "https://foo.com") == 0);
@@ -194,7 +195,8 @@ static void test_claims_success(void) {
GPR_ASSERT(strcmp(grpc_jwt_claims_id(claims), "jwtuniqueid") == 0);
GPR_ASSERT(grpc_jwt_claims_check(claims, "https://foo.com") ==
GRPC_JWT_VERIFIER_OK);
- grpc_jwt_claims_destroy(claims);
+ grpc_jwt_claims_destroy(&exec_ctx, claims);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_expired_claims_failure(void) {
@@ -206,7 +208,8 @@ static void test_expired_claims_failure(void) {
gpr_timespec exp_exp = {120, 0, GPR_CLOCK_REALTIME};
gpr_timespec exp_nbf = {60, 0, GPR_CLOCK_REALTIME};
GPR_ASSERT(json != NULL);
- claims = grpc_jwt_claims_from_json(json, s);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ claims = grpc_jwt_claims_from_json(&exec_ctx, json, s);
GPR_ASSERT(claims != NULL);
GPR_ASSERT(grpc_jwt_claims_json(claims) == json);
GPR_ASSERT(strcmp(grpc_jwt_claims_audience(claims), "https://foo.com") == 0);
@@ -219,14 +222,17 @@ static void test_expired_claims_failure(void) {
GPR_ASSERT(grpc_jwt_claims_check(claims, "https://foo.com") ==
GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE);
- grpc_jwt_claims_destroy(claims);
+ grpc_jwt_claims_destroy(&exec_ctx, claims);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_invalid_claims_failure(void) {
grpc_slice s = grpc_slice_from_copied_string(invalid_claims);
grpc_json *json = grpc_json_parse_string_with_len(
(char *)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s));
- GPR_ASSERT(grpc_jwt_claims_from_json(json, s) == NULL);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ GPR_ASSERT(grpc_jwt_claims_from_json(&exec_ctx, json, s) == NULL);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_bad_audience_claims_failure(void) {
@@ -235,11 +241,13 @@ static void test_bad_audience_claims_failure(void) {
grpc_json *json = grpc_json_parse_string_with_len(
(char *)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s));
GPR_ASSERT(json != NULL);
- claims = grpc_jwt_claims_from_json(json, s);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ claims = grpc_jwt_claims_from_json(&exec_ctx, json, s);
GPR_ASSERT(claims != NULL);
GPR_ASSERT(grpc_jwt_claims_check(claims, "https://bar.com") ==
GRPC_JWT_VERIFIER_BAD_AUDIENCE);
- grpc_jwt_claims_destroy(claims);
+ grpc_jwt_claims_destroy(&exec_ctx, claims);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static char *json_key_str(const char *last_part) {
@@ -298,14 +306,14 @@ static int httpcli_get_google_keys_for_email(
return 1;
}
-static void on_verification_success(void *user_data,
+static void on_verification_success(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_jwt_verifier_status status,
grpc_jwt_claims *claims) {
GPR_ASSERT(status == GRPC_JWT_VERIFIER_OK);
GPR_ASSERT(claims != NULL);
GPR_ASSERT(user_data == (void *)expected_user_data);
GPR_ASSERT(strcmp(grpc_jwt_claims_audience(claims), expected_audience) == 0);
- grpc_jwt_claims_destroy(claims);
+ grpc_jwt_claims_destroy(exec_ctx, claims);
}
static void test_jwt_verifier_google_email_issuer_success(void) {
@@ -413,7 +421,8 @@ static void test_jwt_verifier_url_issuer_success(void) {
grpc_httpcli_set_override(NULL, NULL);
}
-static void on_verification_key_retrieval_error(void *user_data,
+static void on_verification_key_retrieval_error(grpc_exec_ctx *exec_ctx,
+ void *user_data,
grpc_jwt_verifier_status status,
grpc_jwt_claims *claims) {
GPR_ASSERT(status == GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR);
@@ -483,7 +492,11 @@ static void corrupt_jwt_sig(char *jwt) {
uint8_t *sig_bytes;
char *last_dot = strrchr(jwt, '.');
GPR_ASSERT(last_dot != NULL);
- sig = grpc_base64_decode(last_dot + 1, 1);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ sig = grpc_base64_decode(&exec_ctx, last_dot + 1, 1);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(sig));
sig_bytes = GRPC_SLICE_START_PTR(sig);
(*sig_bytes)++; /* Corrupt first byte. */
@@ -494,7 +507,8 @@ static void corrupt_jwt_sig(char *jwt) {
grpc_slice_unref(sig);
}
-static void on_verification_bad_signature(void *user_data,
+static void on_verification_bad_signature(grpc_exec_ctx *exec_ctx,
+ void *user_data,
grpc_jwt_verifier_status status,
grpc_jwt_claims *claims) {
GPR_ASSERT(status == GRPC_JWT_VERIFIER_BAD_SIGNATURE);
@@ -535,7 +549,7 @@ static int httpcli_get_should_not_be_called(grpc_exec_ctx *exec_ctx,
return 1;
}
-static void on_verification_bad_format(void *user_data,
+static void on_verification_bad_format(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_jwt_verifier_status status,
grpc_jwt_claims *claims) {
GPR_ASSERT(status == GRPC_JWT_VERIFIER_BAD_FORMAT);
diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c
index b5d95004fe..3a0c2bb272 100644
--- a/test/core/security/secure_endpoint_test.c
+++ b/test/core/security/secure_endpoint_test.c
@@ -42,6 +42,7 @@
#include "src/core/lib/iomgr/endpoint_pair.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/security/transport/secure_endpoint.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/tsi/fake_transport_security.h"
#include "test/core/util/test_config.h"
@@ -59,7 +60,7 @@ static grpc_endpoint_test_fixture secure_endpoint_create_fixture_tcp_socketpair(
grpc_resource_quota *resource_quota =
grpc_resource_quota_create("secure_endpoint_test");
tcp = grpc_iomgr_create_endpoint_pair("fixture", resource_quota, slice_size);
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
grpc_endpoint_add_to_pollset(&exec_ctx, tcp.client, g_pollset);
grpc_endpoint_add_to_pollset(&exec_ctx, tcp.server, g_pollset);
@@ -170,8 +171,8 @@ static void test_leftover(grpc_endpoint_test_config config, size_t slice_size) {
grpc_endpoint_destroy(&exec_ctx, f.client_ep);
grpc_endpoint_destroy(&exec_ctx, f.server_ep);
grpc_exec_ctx_finish(&exec_ctx);
- grpc_slice_unref(s);
- grpc_slice_buffer_destroy(&incoming);
+ grpc_slice_unref_internal(&exec_ctx, s);
+ grpc_slice_buffer_destroy_internal(&exec_ctx, &incoming);
clean_up();
}
diff --git a/test/core/security/ssl_server_fuzzer.c b/test/core/security/ssl_server_fuzzer.c
index 04969765f5..dd81c52762 100644
--- a/test/core/security/ssl_server_fuzzer.c
+++ b/test/core/security/ssl_server_fuzzer.c
@@ -82,7 +82,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
grpc_resource_quota_create("ssl_server_fuzzer");
grpc_endpoint *mock_endpoint =
grpc_mock_endpoint_create(discard_write, resource_quota);
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
grpc_mock_endpoint_put_read(
&exec_ctx, mock_endpoint,
@@ -106,7 +106,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// Create security connector
grpc_server_security_connector *sc = NULL;
grpc_security_status status =
- grpc_server_credentials_create_security_connector(creds, &sc);
+ grpc_server_credentials_create_security_connector(&exec_ctx, creds, &sc);
GPR_ASSERT(status == GRPC_SECURITY_OK);
sc->channel_args = NULL;
gpr_timespec deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
@@ -129,7 +129,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
GPR_ASSERT(state.done_callback_called);
- GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "test");
+ GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &sc->base, "test");
grpc_server_credentials_release(creds);
grpc_slice_unref(cert_slice);
grpc_slice_unref(key_slice);
diff --git a/test/core/security/verify_jwt.c b/test/core/security/verify_jwt.c
index 043d29e6bb..32169bb8d2 100644
--- a/test/core/security/verify_jwt.c
+++ b/test/core/security/verify_jwt.c
@@ -59,7 +59,7 @@ static void print_usage_and_exit(gpr_cmdline *cl, const char *argv0) {
exit(1);
}
-static void on_jwt_verification_done(void *user_data,
+static void on_jwt_verification_done(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_jwt_verifier_status status,
grpc_jwt_claims *claims) {
synchronizer *sync = user_data;
@@ -72,7 +72,7 @@ static void on_jwt_verification_done(void *user_data,
grpc_json_dump_to_string((grpc_json *)grpc_jwt_claims_json(claims), 2);
printf("Claims: \n\n%s\n", claims_str);
gpr_free(claims_str);
- grpc_jwt_claims_destroy(claims);
+ grpc_jwt_claims_destroy(exec_ctx, claims);
} else {
GPR_ASSERT(claims == NULL);
fprintf(stderr, "Verification failed with error %s\n",
diff --git a/test/core/slice/slice_test.c b/test/core/slice/slice_test.c
index ca44becfd0..d3d1659341 100644
--- a/test/core/slice/slice_test.c
+++ b/test/core/slice/slice_test.c
@@ -35,8 +35,12 @@
#include <string.h>
+#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+
+#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/transport/static_metadata.h"
#include "test/core/util/test_config.h"
#define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x);
@@ -61,8 +65,10 @@ static void test_slice_malloc_returns_something_sensible(void) {
GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == length);
/* If the slice has a refcount, it must be destroyable. */
if (slice.refcount) {
- GPR_ASSERT(slice.refcount->ref != NULL);
- GPR_ASSERT(slice.refcount->unref != NULL);
+ GPR_ASSERT(slice.refcount->vtable != NULL);
+ GPR_ASSERT(slice.refcount->vtable->ref != NULL);
+ GPR_ASSERT(slice.refcount->vtable->unref != NULL);
+ GPR_ASSERT(slice.refcount->vtable->hash != NULL);
}
/* We must be able to write to every byte of the data */
for (i = 0; i < length; i++) {
@@ -249,6 +255,55 @@ static void test_slice_from_copied_string_works(void) {
grpc_slice_unref(slice);
}
+static void test_slice_interning(void) {
+ LOG_TEST_NAME("test_slice_interning");
+
+ grpc_init();
+ grpc_slice src1 = grpc_slice_from_copied_string("hello");
+ grpc_slice src2 = grpc_slice_from_copied_string("hello");
+ GPR_ASSERT(GRPC_SLICE_START_PTR(src1) != GRPC_SLICE_START_PTR(src2));
+ grpc_slice interned1 = grpc_slice_intern(src1);
+ grpc_slice interned2 = grpc_slice_intern(src2);
+ GPR_ASSERT(GRPC_SLICE_START_PTR(interned1) ==
+ GRPC_SLICE_START_PTR(interned2));
+ GPR_ASSERT(GRPC_SLICE_START_PTR(interned1) != GRPC_SLICE_START_PTR(src1));
+ GPR_ASSERT(GRPC_SLICE_START_PTR(interned2) != GRPC_SLICE_START_PTR(src2));
+ grpc_slice_unref(src1);
+ grpc_slice_unref(src2);
+ grpc_slice_unref(interned1);
+ grpc_slice_unref(interned2);
+ grpc_shutdown();
+}
+
+static void test_static_slice_interning(void) {
+ LOG_TEST_NAME("test_static_slice_interning");
+
+ // grpc_init/grpc_shutdown deliberately omitted: they should not be necessary
+ // to intern a static slice
+
+ for (size_t i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) {
+ GPR_ASSERT(grpc_slice_is_equivalent(
+ grpc_static_slice_table[i],
+ grpc_slice_intern(grpc_static_slice_table[i])));
+ }
+}
+
+static void test_static_slice_copy_interning(void) {
+ LOG_TEST_NAME("test_static_slice_copy_interning");
+
+ grpc_init();
+
+ for (size_t i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) {
+ grpc_slice copy = grpc_slice_dup(grpc_static_slice_table[i]);
+ GPR_ASSERT(!grpc_slice_is_equivalent(grpc_static_slice_table[i], copy));
+ GPR_ASSERT(grpc_slice_is_equivalent(grpc_static_slice_table[i],
+ grpc_slice_intern(copy)));
+ grpc_slice_unref(copy);
+ }
+
+ grpc_shutdown();
+}
+
int main(int argc, char **argv) {
unsigned length;
grpc_test_init(argc, argv);
@@ -262,5 +317,8 @@ int main(int argc, char **argv) {
test_slice_split_tail_works(length);
}
test_slice_from_copied_string_works();
+ test_slice_interning();
+ test_static_slice_interning();
+ test_static_slice_copy_interning();
return 0;
}
diff --git a/test/core/surface/byte_buffer_reader_test.c b/test/core/surface/byte_buffer_reader_test.c
index d8d7a52d15..2f1f72f0e0 100644
--- a/test/core/surface/byte_buffer_reader_test.c
+++ b/test/core/surface/byte_buffer_reader_test.c
@@ -40,9 +40,10 @@
#include <grpc/support/log.h>
#include <grpc/support/thd.h>
#include <grpc/support/time.h>
-#include "test/core/util/test_config.h"
#include "src/core/lib/compression/message_compress.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "test/core/util/test_config.h"
#include <string.h>
@@ -145,7 +146,12 @@ static void read_compressed_slice(grpc_compression_algorithm algorithm,
input_slice = grpc_slice_malloc(input_size);
memset(GRPC_SLICE_START_PTR(input_slice), 'a', input_size);
grpc_slice_buffer_add(&sliceb_in, input_slice); /* takes ownership */
- GPR_ASSERT(grpc_msg_compress(algorithm, &sliceb_in, &sliceb_out));
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ GPR_ASSERT(
+ grpc_msg_compress(&exec_ctx, algorithm, &sliceb_in, &sliceb_out));
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
buffer = grpc_raw_compressed_byte_buffer_create(sliceb_out.slices,
sliceb_out.count, algorithm);
diff --git a/test/core/surface/lame_client_test.c b/test/core/surface/lame_client_test.c
index 6afcefca92..4ab8715f70 100644
--- a/test/core/surface/lame_client_test.c
+++ b/test/core/surface/lame_client_test.c
@@ -88,8 +88,7 @@ int main(int argc, char **argv) {
grpc_metadata_array trailing_metadata_recv;
grpc_status_code status;
grpc_call_error error;
- char *details = NULL;
- size_t details_capacity = 0;
+ grpc_slice details;
char *peer;
grpc_test_init(argc, argv);
@@ -109,8 +108,9 @@ int main(int argc, char **argv) {
cq = grpc_completion_queue_create(NULL);
+ grpc_slice host = grpc_slice_from_static_string("anywhere");
call = grpc_channel_create_call(chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
- "/Foo", "anywhere",
+ grpc_slice_from_static_string("/Foo"), &host,
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(100), NULL);
GPR_ASSERT(call);
cqv = cq_verifier_create(cq);
@@ -140,7 +140,6 @@ int main(int argc, char **argv) {
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
- op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op->reserved = NULL;
op++;
@@ -162,7 +161,7 @@ int main(int argc, char **argv) {
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
- gpr_free(details);
+ grpc_slice_unref(details);
grpc_shutdown();
diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c
index d4cfa25d44..610495377c 100644
--- a/test/core/surface/public_headers_must_be_c89.c
+++ b/test/core/surface/public_headers_must_be_c89.c
@@ -42,6 +42,7 @@
#include <grpc/impl/codegen/byte_buffer_reader.h>
#include <grpc/impl/codegen/compression_types.h>
#include <grpc/impl/codegen/connectivity_state.h>
+#include <grpc/impl/codegen/exec_ctx_fwd.h>
#include <grpc/impl/codegen/gpr_types.h>
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/impl/codegen/port_platform.h>
diff --git a/test/core/surface/secure_channel_create_test.c b/test/core/surface/secure_channel_create_test.c
index 444ebdc093..ab4067dbe1 100644
--- a/test/core/surface/secure_channel_create_test.c
+++ b/test/core/surface/secure_channel_create_test.c
@@ -51,7 +51,9 @@ void test_unknown_scheme_target(void) {
creds = grpc_fake_transport_security_credentials_create();
chan = grpc_secure_channel_create(creds, "blah://blah", NULL, NULL);
GPR_ASSERT(chan == NULL);
- grpc_channel_credentials_unref(creds);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_credentials_unref(&exec_ctx, creds);
+ grpc_exec_ctx_finish(&exec_ctx);
}
void test_security_connector_already_in_arg(void) {
diff --git a/test/core/surface/sequential_connectivity_test.c b/test/core/surface/sequential_connectivity_test.c
index fe87f119f2..3292718762 100644
--- a/test/core/surface/sequential_connectivity_test.c
+++ b/test/core/surface/sequential_connectivity_test.c
@@ -39,6 +39,7 @@
#include <grpc/support/thd.h>
#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
@@ -162,7 +163,11 @@ static grpc_channel *secure_test_create_channel(const char *addr) {
grpc_channel_args_copy_and_add(NULL, &ssl_name_override, 1);
grpc_channel *channel =
grpc_secure_channel_create(ssl_creds, addr, new_client_args, NULL);
- grpc_channel_args_destroy(new_client_args);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_channel_args_destroy(&exec_ctx, new_client_args);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
grpc_channel_credentials_release(ssl_creds);
return channel;
}
diff --git a/test/core/transport/chttp2/bin_decoder_test.c b/test/core/transport/chttp2/bin_decoder_test.c
index 7ddc30291a..221112ab21 100644
--- a/test/core/transport/chttp2/bin_decoder_test.c
+++ b/test/core/transport/chttp2/bin_decoder_test.c
@@ -38,13 +38,14 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
static int all_ok = 1;
-static void expect_slice_eq(grpc_slice expected, grpc_slice slice, char *debug,
- int line) {
+static void expect_slice_eq(grpc_exec_ctx *exec_ctx, grpc_slice expected,
+ grpc_slice slice, char *debug, int line) {
if (0 != grpc_slice_cmp(slice, expected)) {
char *hs = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
char *he = grpc_dump_slice(expected, GPR_DUMP_HEX | GPR_DUMP_ASCII);
@@ -54,92 +55,104 @@ static void expect_slice_eq(grpc_slice expected, grpc_slice slice, char *debug,
gpr_free(he);
all_ok = 0;
}
- grpc_slice_unref(expected);
- grpc_slice_unref(slice);
+ grpc_slice_unref_internal(exec_ctx, expected);
+ grpc_slice_unref_internal(exec_ctx, slice);
}
-static grpc_slice base64_encode(const char *s) {
+static grpc_slice base64_encode(grpc_exec_ctx *exec_ctx, const char *s) {
grpc_slice ss = grpc_slice_from_copied_string(s);
grpc_slice out = grpc_chttp2_base64_encode(ss);
- grpc_slice_unref(ss);
+ grpc_slice_unref_internal(exec_ctx, ss);
return out;
}
-static grpc_slice base64_decode(const char *s) {
+static grpc_slice base64_decode(grpc_exec_ctx *exec_ctx, const char *s) {
grpc_slice ss = grpc_slice_from_copied_string(s);
- grpc_slice out = grpc_chttp2_base64_decode(ss);
- grpc_slice_unref(ss);
+ grpc_slice out = grpc_chttp2_base64_decode(exec_ctx, ss);
+ grpc_slice_unref_internal(exec_ctx, ss);
return out;
}
-static grpc_slice base64_decode_with_length(const char *s,
+static grpc_slice base64_decode_with_length(grpc_exec_ctx *exec_ctx,
+ const char *s,
size_t output_length) {
grpc_slice ss = grpc_slice_from_copied_string(s);
- grpc_slice out = grpc_chttp2_base64_decode_with_length(ss, output_length);
- grpc_slice_unref(ss);
+ grpc_slice out =
+ grpc_chttp2_base64_decode_with_length(exec_ctx, ss, output_length);
+ grpc_slice_unref_internal(exec_ctx, ss);
return out;
}
-#define EXPECT_SLICE_EQ(expected, slice) \
- expect_slice_eq( \
- grpc_slice_from_copied_buffer(expected, sizeof(expected) - 1), slice, \
- #slice, __LINE__);
+#define EXPECT_SLICE_EQ(exec_ctx, expected, slice) \
+ expect_slice_eq( \
+ exec_ctx, grpc_slice_from_copied_buffer(expected, sizeof(expected) - 1), \
+ slice, #slice, __LINE__);
-#define ENCODE_AND_DECODE(s) \
- EXPECT_SLICE_EQ( \
- s, grpc_chttp2_base64_decode_with_length(base64_encode(s), strlen(s)));
+#define ENCODE_AND_DECODE(exec_ctx, s) \
+ EXPECT_SLICE_EQ(exec_ctx, s, \
+ grpc_chttp2_base64_decode_with_length( \
+ exec_ctx, base64_encode(exec_ctx, s), strlen(s)));
int main(int argc, char **argv) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
/* ENCODE_AND_DECODE tests grpc_chttp2_base64_decode_with_length(), which
takes encoded base64 strings without pad chars, but output length is
required. */
/* Base64 test vectors from RFC 4648 */
- ENCODE_AND_DECODE("");
- ENCODE_AND_DECODE("f");
- ENCODE_AND_DECODE("foo");
- ENCODE_AND_DECODE("fo");
- ENCODE_AND_DECODE("foob");
- ENCODE_AND_DECODE("fooba");
- ENCODE_AND_DECODE("foobar");
+ ENCODE_AND_DECODE(&exec_ctx, "");
+ ENCODE_AND_DECODE(&exec_ctx, "f");
+ ENCODE_AND_DECODE(&exec_ctx, "foo");
+ ENCODE_AND_DECODE(&exec_ctx, "fo");
+ ENCODE_AND_DECODE(&exec_ctx, "foob");
+ ENCODE_AND_DECODE(&exec_ctx, "fooba");
+ ENCODE_AND_DECODE(&exec_ctx, "foobar");
- ENCODE_AND_DECODE("\xc0\xc1\xc2\xc3\xc4\xc5");
+ ENCODE_AND_DECODE(&exec_ctx, "\xc0\xc1\xc2\xc3\xc4\xc5");
/* Base64 test vectors from RFC 4648, with pad chars */
/* BASE64("") = "" */
- EXPECT_SLICE_EQ("", base64_decode(""));
+ EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, ""));
/* BASE64("f") = "Zg==" */
- EXPECT_SLICE_EQ("f", base64_decode("Zg=="));
+ EXPECT_SLICE_EQ(&exec_ctx, "f", base64_decode(&exec_ctx, "Zg=="));
/* BASE64("fo") = "Zm8=" */
- EXPECT_SLICE_EQ("fo", base64_decode("Zm8="));
+ EXPECT_SLICE_EQ(&exec_ctx, "fo", base64_decode(&exec_ctx, "Zm8="));
/* BASE64("foo") = "Zm9v" */
- EXPECT_SLICE_EQ("foo", base64_decode("Zm9v"));
+ EXPECT_SLICE_EQ(&exec_ctx, "foo", base64_decode(&exec_ctx, "Zm9v"));
/* BASE64("foob") = "Zm9vYg==" */
- EXPECT_SLICE_EQ("foob", base64_decode("Zm9vYg=="));
+ EXPECT_SLICE_EQ(&exec_ctx, "foob", base64_decode(&exec_ctx, "Zm9vYg=="));
/* BASE64("fooba") = "Zm9vYmE=" */
- EXPECT_SLICE_EQ("fooba", base64_decode("Zm9vYmE="));
+ EXPECT_SLICE_EQ(&exec_ctx, "fooba", base64_decode(&exec_ctx, "Zm9vYmE="));
/* BASE64("foobar") = "Zm9vYmFy" */
- EXPECT_SLICE_EQ("foobar", base64_decode("Zm9vYmFy"));
+ EXPECT_SLICE_EQ(&exec_ctx, "foobar", base64_decode(&exec_ctx, "Zm9vYmFy"));
- EXPECT_SLICE_EQ("\xc0\xc1\xc2\xc3\xc4\xc5", base64_decode("wMHCw8TF"));
+ EXPECT_SLICE_EQ(&exec_ctx, "\xc0\xc1\xc2\xc3\xc4\xc5",
+ base64_decode(&exec_ctx, "wMHCw8TF"));
// Test illegal input length in grpc_chttp2_base64_decode
- EXPECT_SLICE_EQ("", base64_decode("a"));
- EXPECT_SLICE_EQ("", base64_decode("ab"));
- EXPECT_SLICE_EQ("", base64_decode("abc"));
+ EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, "a"));
+ EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, "ab"));
+ EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, "abc"));
// Test illegal charactors in grpc_chttp2_base64_decode
- EXPECT_SLICE_EQ("", base64_decode("Zm:v"));
- EXPECT_SLICE_EQ("", base64_decode("Zm=v"));
+ EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, "Zm:v"));
+ EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode(&exec_ctx, "Zm=v"));
// Test output_length longer than max possible output length in
// grpc_chttp2_base64_decode_with_length
- EXPECT_SLICE_EQ("", base64_decode_with_length("Zg", 2));
- EXPECT_SLICE_EQ("", base64_decode_with_length("Zm8", 3));
- EXPECT_SLICE_EQ("", base64_decode_with_length("Zm9v", 4));
+ EXPECT_SLICE_EQ(&exec_ctx, "", base64_decode_with_length(&exec_ctx, "Zg", 2));
+ EXPECT_SLICE_EQ(&exec_ctx, "",
+ base64_decode_with_length(&exec_ctx, "Zm8", 3));
+ EXPECT_SLICE_EQ(&exec_ctx, "",
+ base64_decode_with_length(&exec_ctx, "Zm9v", 4));
// Test illegal charactors in grpc_chttp2_base64_decode_with_length
- EXPECT_SLICE_EQ("", base64_decode_with_length("Zm:v", 3));
- EXPECT_SLICE_EQ("", base64_decode_with_length("Zm=v", 3));
+ EXPECT_SLICE_EQ(&exec_ctx, "",
+ base64_decode_with_length(&exec_ctx, "Zm:v", 3));
+ EXPECT_SLICE_EQ(&exec_ctx, "",
+ base64_decode_with_length(&exec_ctx, "Zm=v", 3));
+
+ grpc_exec_ctx_finish(&exec_ctx);
return all_ok ? 0 : 1;
}
diff --git a/test/core/transport/chttp2/bin_encoder_test.c b/test/core/transport/chttp2/bin_encoder_test.c
index 53b55a301e..778606a78c 100644
--- a/test/core/transport/chttp2/bin_encoder_test.c
+++ b/test/core/transport/chttp2/bin_encoder_test.c
@@ -84,7 +84,7 @@ static void expect_combined_equiv(const char *s, size_t len, int line) {
grpc_slice input = grpc_slice_from_copied_buffer(s, len);
grpc_slice base64 = grpc_chttp2_base64_encode(input);
grpc_slice expect = grpc_chttp2_huffman_compress(base64);
- grpc_slice got = grpc_chttp2_base64_encode_and_huffman_compress_impl(input);
+ grpc_slice got = grpc_chttp2_base64_encode_and_huffman_compress(input);
if (0 != grpc_slice_cmp(expect, got)) {
char *t = grpc_dump_slice(input, GPR_DUMP_HEX | GPR_DUMP_ASCII);
char *e = grpc_dump_slice(expect, GPR_DUMP_HEX | GPR_DUMP_ASCII);
@@ -106,7 +106,7 @@ static void expect_combined_equiv(const char *s, size_t len, int line) {
expect_combined_equiv(x, sizeof(x) - 1, __LINE__)
static void expect_binary_header(const char *hdr, int binary) {
- if (grpc_is_binary_header(hdr, strlen(hdr)) != binary) {
+ if (grpc_is_binary_header(grpc_slice_from_static_string(hdr)) != binary) {
gpr_log(GPR_ERROR, "FAILED: expected header '%s' to be %s", hdr,
binary ? "binary" : "not binary");
all_ok = 0;
diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c
index 91421e18f4..862966cc38 100644
--- a/test/core/transport/chttp2/hpack_encoder_test.c
+++ b/test/core/transport/chttp2/hpack_encoder_test.c
@@ -41,6 +41,7 @@
#include <grpc/support/string_util.h>
#include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/transport/metadata.h"
@@ -59,8 +60,9 @@ size_t cap_to_delete = 0;
/* verify that the output generated by encoding the stream matches the
hexstring passed in */
-static void verify(size_t window_available, int eof, size_t expect_window_used,
- const char *expected, size_t nheaders, ...) {
+static void verify(grpc_exec_ctx *exec_ctx, size_t window_available, int eof,
+ size_t expect_window_used, const char *expected,
+ size_t nheaders, ...) {
grpc_slice_buffer output;
grpc_slice merged;
grpc_slice expect = parse_hexstring(expected);
@@ -79,7 +81,9 @@ static void verify(size_t window_available, int eof, size_t expect_window_used,
e[i - 1].next = &e[i];
e[i].prev = &e[i - 1];
}
- e[i].md = grpc_mdelem_from_strings(key, value);
+ e[i].md =
+ grpc_mdelem_from_slices(exec_ctx, grpc_slice_from_copied_string(key),
+ grpc_slice_from_copied_string(value));
}
e[0].prev = NULL;
e[nheaders - 1].next = NULL;
@@ -98,11 +102,11 @@ static void verify(size_t window_available, int eof, size_t expect_window_used,
grpc_transport_one_way_stats stats;
memset(&stats, 0, sizeof(stats));
- grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, eof, 16384, &stats,
- &output);
+ grpc_chttp2_encode_header(exec_ctx, &g_compressor, 0xdeadbeef, &b, eof, 16384,
+ &stats, &output);
merged = grpc_slice_merge(output.slices, output.count);
- grpc_slice_buffer_destroy(&output);
- grpc_metadata_batch_destroy(&b);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &output);
+ grpc_metadata_batch_destroy(exec_ctx, &b);
if (0 != grpc_slice_cmp(merged, expect)) {
char *expect_str = grpc_dump_slice(expect, GPR_DUMP_HEX | GPR_DUMP_ASCII);
@@ -115,31 +119,32 @@ static void verify(size_t window_available, int eof, size_t expect_window_used,
g_failure = 1;
}
- grpc_slice_unref(merged);
- grpc_slice_unref(expect);
+ grpc_slice_unref_internal(exec_ctx, merged);
+ grpc_slice_unref_internal(exec_ctx, expect);
}
-static void test_basic_headers(void) {
+static void test_basic_headers(grpc_exec_ctx *exec_ctx) {
int i;
- verify(0, 0, 0, "000005 0104 deadbeef 40 0161 0161", 1, "a", "a");
- verify(0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a");
- verify(0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a");
- verify(0, 0, 0, "000006 0104 deadbeef be 40 0162 0163", 2, "a", "a", "b",
+ verify(exec_ctx, 0, 0, 0, "000005 0104 deadbeef 40 0161 0161", 1, "a", "a");
+ verify(exec_ctx, 0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a");
+ verify(exec_ctx, 0, 0, 0, "000001 0104 deadbeef be", 1, "a", "a");
+ verify(exec_ctx, 0, 0, 0, "000006 0104 deadbeef be 40 0162 0163", 2, "a", "a",
+ "b", "c");
+ verify(exec_ctx, 0, 0, 0, "000002 0104 deadbeef bf be", 2, "a", "a", "b",
"c");
- verify(0, 0, 0, "000002 0104 deadbeef bf be", 2, "a", "a", "b", "c");
- verify(0, 0, 0, "000004 0104 deadbeef 7f 00 0164", 1, "a", "d");
+ verify(exec_ctx, 0, 0, 0, "000004 0104 deadbeef 7f 00 0164", 1, "a", "d");
/* flush out what's there to make a few values look very popular */
for (i = 0; i < 350; i++) {
- verify(0, 0, 0, "000003 0104 deadbeef c0 bf be", 3, "a", "a", "b", "c", "a",
- "d");
+ verify(exec_ctx, 0, 0, 0, "000003 0104 deadbeef c0 bf be", 3, "a", "a", "b",
+ "c", "a", "d");
}
- verify(0, 0, 0, "000006 0104 deadbeef c0 00 016b 0176", 2, "a", "a", "k",
- "v");
+ verify(exec_ctx, 0, 0, 0, "000006 0104 deadbeef c0 00 016b 0176", 2, "a", "a",
+ "k", "v");
/* this could be 000004 0104 deadbeef 0f 30 0176 also */
- verify(0, 0, 0, "000004 0104 deadbeef 0f 2f 0176", 1, "a", "v");
+ verify(exec_ctx, 0, 0, 0, "000004 0104 deadbeef 0f 2f 0176", 1, "a", "v");
}
static void encode_int_to_str(int i, char *p) {
@@ -150,7 +155,7 @@ static void encode_int_to_str(int i, char *p) {
p[2] = 0;
}
-static void test_decode_table_overflow(void) {
+static void test_decode_table_overflow(grpc_exec_ctx *exec_ctx) {
int i;
char key[3], value[3];
char *expect;
@@ -173,22 +178,26 @@ static void test_decode_table_overflow(void) {
}
if (i > 0) {
- verify(0, 0, 0, expect, 2, "aa", "ba", key, value);
+ verify(exec_ctx, 0, 0, 0, expect, 2, "aa", "ba", key, value);
} else {
- verify(0, 0, 0, expect, 1, key, value);
+ verify(exec_ctx, 0, 0, 0, expect, 1, key, value);
}
gpr_free(expect);
}
/* if the above passes, then we must have just knocked this pair out of the
decoder stack, and so we'll be forced to re-encode it */
- verify(0, 0, 0, "000007 0104 deadbeef 40 026161 026261", 1, "aa", "ba");
+ verify(exec_ctx, 0, 0, 0, "000007 0104 deadbeef 40 026161 026261", 1, "aa",
+ "ba");
}
-static void verify_table_size_change_match_elem_size(const char *key,
+static void verify_table_size_change_match_elem_size(grpc_exec_ctx *exec_ctx,
+ const char *key,
const char *value) {
grpc_slice_buffer output;
- grpc_mdelem *elem = grpc_mdelem_from_strings(key, value);
+ grpc_mdelem elem =
+ grpc_mdelem_from_slices(exec_ctx, grpc_slice_from_copied_string(key),
+ grpc_slice_from_copied_string(value));
size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem);
size_t initial_table_size = g_compressor.table_size;
grpc_linked_mdelem *e = gpr_malloc(sizeof(*e));
@@ -203,30 +212,32 @@ static void verify_table_size_change_match_elem_size(const char *key,
grpc_transport_one_way_stats stats;
memset(&stats, 0, sizeof(stats));
- grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, 0, 16384, &stats,
- &output);
- grpc_slice_buffer_destroy(&output);
- grpc_metadata_batch_destroy(&b);
+ grpc_chttp2_encode_header(exec_ctx, &g_compressor, 0xdeadbeef, &b, 0, 16384,
+ &stats, &output);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &output);
+ grpc_metadata_batch_destroy(exec_ctx, &b);
GPR_ASSERT(g_compressor.table_size == elem_size + initial_table_size);
gpr_free(e);
}
-static void test_encode_header_size(void) {
- verify_table_size_change_match_elem_size("hello", "world");
- verify_table_size_change_match_elem_size("hello-bin", "world");
+static void test_encode_header_size(grpc_exec_ctx *exec_ctx) {
+ verify_table_size_change_match_elem_size(exec_ctx, "hello", "world");
+ verify_table_size_change_match_elem_size(exec_ctx, "hello-bin", "world");
}
-static void run_test(void (*test)(), const char *name) {
+static void run_test(void (*test)(grpc_exec_ctx *exec_ctx), const char *name) {
gpr_log(GPR_INFO, "RUN TEST: %s", name);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_chttp2_hpack_compressor_init(&g_compressor);
- test();
- grpc_chttp2_hpack_compressor_destroy(&g_compressor);
+ test(&exec_ctx);
+ grpc_chttp2_hpack_compressor_destroy(&exec_ctx, &g_compressor);
+ grpc_exec_ctx_finish(&exec_ctx);
}
int main(int argc, char **argv) {
size_t i;
- grpc_test_only_set_metadata_hash_seed(0);
+ grpc_test_only_set_slice_hash_seed(0);
grpc_test_init(argc, argv);
grpc_init();
TEST(test_basic_headers);
diff --git a/test/core/transport/chttp2/hpack_parser_fuzzer_test.c b/test/core/transport/chttp2/hpack_parser_fuzzer_test.c
index 95acbf1a68..cfa3c5c088 100644
--- a/test/core/transport/chttp2/hpack_parser_fuzzer_test.c
+++ b/test/core/transport/chttp2/hpack_parser_fuzzer_test.c
@@ -39,27 +39,28 @@
#include <grpc/support/log.h>
#include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
+#include "src/core/lib/slice/slice_internal.h"
bool squelch = true;
bool leak_check = true;
-static void onhdr(grpc_exec_ctx *exec_ctx, void *ud, grpc_mdelem *md) {
- GRPC_MDELEM_UNREF(md);
+static void onhdr(grpc_exec_ctx *exec_ctx, void *ud, grpc_mdelem md) {
+ GRPC_MDELEM_UNREF(exec_ctx, md);
}
static void dont_log(gpr_log_func_args *args) {}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
- grpc_test_only_set_metadata_hash_seed(0);
+ grpc_test_only_set_slice_hash_seed(0);
if (squelch) gpr_set_log_function(dont_log);
grpc_init();
grpc_chttp2_hpack_parser parser;
- grpc_chttp2_hpack_parser_init(&parser);
- parser.on_header = onhdr;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
+ parser.on_header = onhdr;
GRPC_ERROR_UNREF(
grpc_chttp2_hpack_parser_parse(&exec_ctx, &parser, data, data + size));
+ grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
grpc_exec_ctx_finish(&exec_ctx);
- grpc_chttp2_hpack_parser_destroy(&parser);
grpc_shutdown();
return 0;
}
diff --git a/test/core/transport/chttp2/hpack_parser_test.c b/test/core/transport/chttp2/hpack_parser_test.c
index e2813df70c..b7f35a5e44 100644
--- a/test/core/transport/chttp2/hpack_parser_test.c
+++ b/test/core/transport/chttp2/hpack_parser_test.c
@@ -45,16 +45,16 @@
typedef struct { va_list args; } test_checker;
-static void onhdr(grpc_exec_ctx *exec_ctx, void *ud, grpc_mdelem *md) {
+static void onhdr(grpc_exec_ctx *exec_ctx, void *ud, grpc_mdelem md) {
const char *ekey, *evalue;
test_checker *chk = ud;
ekey = va_arg(chk->args, char *);
GPR_ASSERT(ekey);
evalue = va_arg(chk->args, char *);
GPR_ASSERT(evalue);
- GPR_ASSERT(grpc_slice_str_cmp(md->key->slice, ekey) == 0);
- GPR_ASSERT(grpc_slice_str_cmp(md->value->slice, evalue) == 0);
- GRPC_MDELEM_UNREF(md);
+ GPR_ASSERT(grpc_slice_str_cmp(GRPC_MDKEY(md), ekey) == 0);
+ GPR_ASSERT(grpc_slice_str_cmp(GRPC_MDVALUE(md), evalue) == 0);
+ GRPC_MDELEM_UNREF(exec_ctx, md);
}
static void test_vector(grpc_chttp2_hpack_parser *parser,
@@ -94,8 +94,9 @@ static void test_vector(grpc_chttp2_hpack_parser *parser,
static void test_vectors(grpc_slice_split_mode mode) {
grpc_chttp2_hpack_parser parser;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- grpc_chttp2_hpack_parser_init(&parser);
+ grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
/* D.2.1 */
test_vector(&parser, mode,
"400a 6375 7374 6f6d 2d6b 6579 0d63 7573"
@@ -111,9 +112,9 @@ static void test_vectors(grpc_slice_split_mode mode) {
"password", "secret", NULL);
/* D.2.4 */
test_vector(&parser, mode, "82", ":method", "GET", NULL);
- grpc_chttp2_hpack_parser_destroy(&parser);
+ grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
- grpc_chttp2_hpack_parser_init(&parser);
+ grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
/* D.3.1 */
test_vector(&parser, mode,
"8286 8441 0f77 7777 2e65 7861 6d70 6c65"
@@ -131,9 +132,9 @@ static void test_vectors(grpc_slice_split_mode mode) {
":method", "GET", ":scheme", "https", ":path", "/index.html",
":authority", "www.example.com", "custom-key", "custom-value",
NULL);
- grpc_chttp2_hpack_parser_destroy(&parser);
+ grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
- grpc_chttp2_hpack_parser_init(&parser);
+ grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
/* D.4.1 */
test_vector(&parser, mode,
"8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4"
@@ -151,11 +152,11 @@ static void test_vectors(grpc_slice_split_mode mode) {
":method", "GET", ":scheme", "https", ":path", "/index.html",
":authority", "www.example.com", "custom-key", "custom-value",
NULL);
- grpc_chttp2_hpack_parser_destroy(&parser);
+ grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
- grpc_chttp2_hpack_parser_init(&parser);
- grpc_chttp2_hptbl_set_max_bytes(&parser.table, 256);
- grpc_chttp2_hptbl_set_current_table_size(&parser.table, 256);
+ grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
+ grpc_chttp2_hptbl_set_max_bytes(&exec_ctx, &parser.table, 256);
+ grpc_chttp2_hptbl_set_current_table_size(&exec_ctx, &parser.table, 256);
/* D.5.1 */
test_vector(&parser, mode,
"4803 3330 3258 0770 7269 7661 7465 611d"
@@ -185,11 +186,11 @@ static void test_vectors(grpc_slice_split_mode mode) {
"https://www.example.com", "content-encoding", "gzip",
"set-cookie",
"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", NULL);
- grpc_chttp2_hpack_parser_destroy(&parser);
+ grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
- grpc_chttp2_hpack_parser_init(&parser);
- grpc_chttp2_hptbl_set_max_bytes(&parser.table, 256);
- grpc_chttp2_hptbl_set_current_table_size(&parser.table, 256);
+ grpc_chttp2_hpack_parser_init(&exec_ctx, &parser);
+ grpc_chttp2_hptbl_set_max_bytes(&exec_ctx, &parser.table, 256);
+ grpc_chttp2_hptbl_set_current_table_size(&exec_ctx, &parser.table, 256);
/* D.6.1 */
test_vector(&parser, mode,
"4882 6402 5885 aec3 771a 4b61 96d0 7abe"
@@ -216,7 +217,9 @@ static void test_vectors(grpc_slice_split_mode mode) {
"https://www.example.com", "content-encoding", "gzip",
"set-cookie",
"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", NULL);
- grpc_chttp2_hpack_parser_destroy(&parser);
+ grpc_chttp2_hpack_parser_destroy(&exec_ctx, &parser);
+
+ grpc_exec_ctx_finish(&exec_ctx);
}
int main(int argc, char **argv) {
diff --git a/test/core/transport/chttp2/hpack_table_test.c b/test/core/transport/chttp2/hpack_table_test.c
index 1a7e2442ca..d2f6d5dc5b 100644
--- a/test/core/transport/chttp2/hpack_table_test.c
+++ b/test/core/transport/chttp2/hpack_table_test.c
@@ -46,22 +46,23 @@
#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x)
-static void assert_str(const grpc_chttp2_hptbl *tbl, grpc_mdstr *mdstr,
+static void assert_str(const grpc_chttp2_hptbl *tbl, grpc_slice mdstr,
const char *str) {
- GPR_ASSERT(grpc_slice_str_cmp(mdstr->slice, str) == 0);
+ GPR_ASSERT(grpc_slice_str_cmp(mdstr, str) == 0);
}
static void assert_index(const grpc_chttp2_hptbl *tbl, uint32_t idx,
const char *key, const char *value) {
- grpc_mdelem *md = grpc_chttp2_hptbl_lookup(tbl, idx);
- assert_str(tbl, md->key, key);
- assert_str(tbl, md->value, value);
+ grpc_mdelem md = grpc_chttp2_hptbl_lookup(tbl, idx);
+ assert_str(tbl, GRPC_MDKEY(md), key);
+ assert_str(tbl, GRPC_MDVALUE(md), value);
}
static void test_static_lookup(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_chttp2_hptbl tbl;
- grpc_chttp2_hptbl_init(&tbl);
+ grpc_chttp2_hptbl_init(&exec_ctx, &tbl);
LOG_TEST("test_static_lookup");
assert_index(&tbl, 1, ":authority", "");
@@ -126,7 +127,8 @@ static void test_static_lookup(void) {
assert_index(&tbl, 60, "via", "");
assert_index(&tbl, 61, "www-authenticate", "");
- grpc_chttp2_hptbl_destroy(&tbl);
+ grpc_chttp2_hptbl_destroy(&exec_ctx, &tbl);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static void test_many_additions(void) {
@@ -137,15 +139,18 @@ static void test_many_additions(void) {
LOG_TEST("test_many_additions");
- grpc_chttp2_hptbl_init(&tbl);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_chttp2_hptbl_init(&exec_ctx, &tbl);
for (i = 0; i < 100000; i++) {
- grpc_mdelem *elem;
+ grpc_mdelem elem;
gpr_asprintf(&key, "K:%d", i);
gpr_asprintf(&value, "VALUE:%d", i);
- elem = grpc_mdelem_from_strings(key, value);
- GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE);
- GRPC_MDELEM_UNREF(elem);
+ elem =
+ grpc_mdelem_from_slices(&exec_ctx, grpc_slice_from_copied_string(key),
+ grpc_slice_from_copied_string(value));
+ GPR_ASSERT(grpc_chttp2_hptbl_add(&exec_ctx, &tbl, elem) == GRPC_ERROR_NONE);
+ GRPC_MDELEM_UNREF(&exec_ctx, elem);
assert_index(&tbl, 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY, key, value);
gpr_free(key);
gpr_free(value);
@@ -158,37 +163,48 @@ static void test_many_additions(void) {
}
}
- grpc_chttp2_hptbl_destroy(&tbl);
+ grpc_chttp2_hptbl_destroy(&exec_ctx, &tbl);
+ grpc_exec_ctx_finish(&exec_ctx);
}
static grpc_chttp2_hptbl_find_result find_simple(grpc_chttp2_hptbl *tbl,
const char *key,
const char *value) {
- grpc_mdelem *md = grpc_mdelem_from_strings(key, value);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_mdelem md =
+ grpc_mdelem_from_slices(&exec_ctx, grpc_slice_from_copied_string(key),
+ grpc_slice_from_copied_string(value));
grpc_chttp2_hptbl_find_result r = grpc_chttp2_hptbl_find(tbl, md);
- GRPC_MDELEM_UNREF(md);
+ GRPC_MDELEM_UNREF(&exec_ctx, md);
+ grpc_exec_ctx_finish(&exec_ctx);
return r;
}
static void test_find(void) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_chttp2_hptbl tbl;
uint32_t i;
char buffer[32];
- grpc_mdelem *elem;
+ grpc_mdelem elem;
grpc_chttp2_hptbl_find_result r;
LOG_TEST("test_find");
- grpc_chttp2_hptbl_init(&tbl);
- elem = grpc_mdelem_from_strings("abc", "xyz");
- GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE);
- GRPC_MDELEM_UNREF(elem);
- elem = grpc_mdelem_from_strings("abc", "123");
- GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE);
- GRPC_MDELEM_UNREF(elem);
- elem = grpc_mdelem_from_strings("x", "1");
- GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE);
- GRPC_MDELEM_UNREF(elem);
+ grpc_chttp2_hptbl_init(&exec_ctx, &tbl);
+ elem =
+ grpc_mdelem_from_slices(&exec_ctx, grpc_slice_from_static_string("abc"),
+ grpc_slice_from_static_string("xyz"));
+ GPR_ASSERT(grpc_chttp2_hptbl_add(&exec_ctx, &tbl, elem) == GRPC_ERROR_NONE);
+ GRPC_MDELEM_UNREF(&exec_ctx, elem);
+ elem =
+ grpc_mdelem_from_slices(&exec_ctx, grpc_slice_from_static_string("abc"),
+ grpc_slice_from_static_string("123"));
+ GPR_ASSERT(grpc_chttp2_hptbl_add(&exec_ctx, &tbl, elem) == GRPC_ERROR_NONE);
+ GRPC_MDELEM_UNREF(&exec_ctx, elem);
+ elem = grpc_mdelem_from_slices(&exec_ctx, grpc_slice_from_static_string("x"),
+ grpc_slice_from_static_string("1"));
+ GPR_ASSERT(grpc_chttp2_hptbl_add(&exec_ctx, &tbl, elem) == GRPC_ERROR_NONE);
+ GRPC_MDELEM_UNREF(&exec_ctx, elem);
r = find_simple(&tbl, "abc", "123");
GPR_ASSERT(r.index == 2 + GRPC_CHTTP2_LAST_STATIC_ENTRY);
@@ -237,9 +253,11 @@ static void test_find(void) {
/* overflow the string buffer, check find still works */
for (i = 0; i < 10000; i++) {
int64_ttoa(i, buffer);
- elem = grpc_mdelem_from_strings("test", buffer);
- GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE);
- GRPC_MDELEM_UNREF(elem);
+ elem = grpc_mdelem_from_slices(&exec_ctx,
+ grpc_slice_from_static_string("test"),
+ grpc_slice_from_copied_string(buffer));
+ GPR_ASSERT(grpc_chttp2_hptbl_add(&exec_ctx, &tbl, elem) == GRPC_ERROR_NONE);
+ GRPC_MDELEM_UNREF(&exec_ctx, elem);
}
r = find_simple(&tbl, "abc", "123");
@@ -267,7 +285,8 @@ static void test_find(void) {
GPR_ASSERT(r.index != 0);
GPR_ASSERT(r.has_value == 0);
- grpc_chttp2_hptbl_destroy(&tbl);
+ grpc_chttp2_hptbl_destroy(&exec_ctx, &tbl);
+ grpc_exec_ctx_finish(&exec_ctx);
}
int main(int argc, char **argv) {
diff --git a/test/core/transport/metadata_test.c b/test/core/transport/metadata_test.c
index 5c89d8530a..ce8f1813ff 100644
--- a/test/core/transport/metadata_test.c
+++ b/test/core/transport/metadata_test.c
@@ -42,114 +42,198 @@
#include <grpc/support/string_util.h>
#include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/transport/static_metadata.h"
#include "test/core/util/test_config.h"
-#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x)
-
/* a large number */
#define MANY 10000
static void test_no_op(void) {
- LOG_TEST("test_no_op");
+ gpr_log(GPR_INFO, "test_no_op");
grpc_init();
grpc_shutdown();
}
-static void test_create_string(void) {
- grpc_mdstr *s1, *s2, *s3;
-
- LOG_TEST("test_create_string");
+static grpc_slice maybe_intern(grpc_slice in, bool intern) {
+ grpc_slice out = intern ? grpc_slice_intern(in) : grpc_slice_ref(in);
+ grpc_slice_unref(in);
+ return out;
+}
- grpc_init();
- s1 = grpc_mdstr_from_string("hello");
- s2 = grpc_mdstr_from_string("hello");
- s3 = grpc_mdstr_from_string("very much not hello");
- GPR_ASSERT(s1 == s2);
- GPR_ASSERT(s3 != s1);
- GPR_ASSERT(grpc_slice_str_cmp(s1->slice, "hello") == 0);
- GPR_ASSERT(grpc_slice_str_cmp(s3->slice, "very much not hello") == 0);
- GRPC_MDSTR_UNREF(s1);
- GRPC_MDSTR_UNREF(s2);
- GRPC_MDSTR_UNREF(s3);
- grpc_shutdown();
+static grpc_slice maybe_dup(grpc_slice in, bool dup) {
+ grpc_slice out = dup ? grpc_slice_dup(in) : grpc_slice_ref(in);
+ grpc_slice_unref(in);
+ return out;
}
-static void test_create_metadata(void) {
- grpc_mdelem *m1, *m2, *m3;
+static void test_create_metadata(bool intern_keys, bool intern_values) {
+ grpc_mdelem m1, m2, m3;
- LOG_TEST("test_create_metadata");
+ gpr_log(GPR_INFO, "test_create_metadata: intern_keys=%d intern_values=%d",
+ intern_keys, intern_values);
grpc_init();
- m1 = grpc_mdelem_from_strings("a", "b");
- m2 = grpc_mdelem_from_strings("a", "b");
- m3 = grpc_mdelem_from_strings("a", "c");
- GPR_ASSERT(m1 == m2);
- GPR_ASSERT(m3 != m1);
- GPR_ASSERT(m3->key == m1->key);
- GPR_ASSERT(m3->value != m1->value);
- GPR_ASSERT(grpc_slice_str_cmp(m1->key->slice, "a") == 0);
- GPR_ASSERT(grpc_slice_str_cmp(m1->value->slice, "b") == 0);
- GPR_ASSERT(grpc_slice_str_cmp(m3->value->slice, "c") == 0);
- GRPC_MDELEM_UNREF(m1);
- GRPC_MDELEM_UNREF(m2);
- GRPC_MDELEM_UNREF(m3);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ m1 = grpc_mdelem_from_slices(
+ &exec_ctx, maybe_intern(grpc_slice_from_static_string("a"), intern_keys),
+ maybe_intern(grpc_slice_from_static_string("b"), intern_values));
+ m2 = grpc_mdelem_from_slices(
+ &exec_ctx, maybe_intern(grpc_slice_from_static_string("a"), intern_keys),
+ maybe_intern(grpc_slice_from_static_string("b"), intern_values));
+ m3 = grpc_mdelem_from_slices(
+ &exec_ctx, maybe_intern(grpc_slice_from_static_string("a"), intern_keys),
+ maybe_intern(grpc_slice_from_static_string("c"), intern_values));
+ GPR_ASSERT(grpc_mdelem_eq(m1, m2));
+ GPR_ASSERT(!grpc_mdelem_eq(m3, m1));
+ GPR_ASSERT(grpc_slice_cmp(GRPC_MDKEY(m3), GRPC_MDKEY(m1)) == 0);
+ GPR_ASSERT(grpc_slice_cmp(GRPC_MDVALUE(m3), GRPC_MDVALUE(m1)) != 0);
+ GPR_ASSERT(grpc_slice_str_cmp(GRPC_MDKEY(m1), "a") == 0);
+ GPR_ASSERT(grpc_slice_str_cmp(GRPC_MDVALUE(m1), "b") == 0);
+ GPR_ASSERT(grpc_slice_str_cmp(GRPC_MDVALUE(m3), "c") == 0);
+ GRPC_MDELEM_UNREF(&exec_ctx, m1);
+ GRPC_MDELEM_UNREF(&exec_ctx, m2);
+ GRPC_MDELEM_UNREF(&exec_ctx, m3);
+ grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
}
-static void test_create_many_ephemeral_metadata(void) {
+static void test_create_many_ephemeral_metadata(bool intern_keys,
+ bool intern_values) {
char buffer[GPR_LTOA_MIN_BUFSIZE];
long i;
- LOG_TEST("test_create_many_ephemeral_metadata");
+ gpr_log(
+ GPR_INFO,
+ "test_create_many_ephemeral_metadata: intern_keys=%d intern_values=%d",
+ intern_keys, intern_values);
grpc_init();
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
/* add, and immediately delete a bunch of different elements */
for (i = 0; i < MANY; i++) {
gpr_ltoa(i, buffer);
- GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", buffer));
+ GRPC_MDELEM_UNREF(
+ &exec_ctx,
+ grpc_mdelem_from_slices(
+ &exec_ctx,
+ maybe_intern(grpc_slice_from_static_string("a"), intern_keys),
+ maybe_intern(grpc_slice_from_copied_string(buffer),
+ intern_values)));
}
+ grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
}
static void test_create_many_persistant_metadata(void) {
char buffer[GPR_LTOA_MIN_BUFSIZE];
long i;
- grpc_mdelem **created = gpr_malloc(sizeof(grpc_mdelem *) * MANY);
- grpc_mdelem *md;
+ grpc_mdelem *created = gpr_malloc(sizeof(grpc_mdelem) * MANY);
+ grpc_mdelem md;
- LOG_TEST("test_create_many_persistant_metadata");
+ gpr_log(GPR_INFO, "test_create_many_persistant_metadata");
grpc_init();
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
/* add phase */
for (i = 0; i < MANY; i++) {
gpr_ltoa(i, buffer);
- created[i] = grpc_mdelem_from_strings("a", buffer);
+ created[i] = grpc_mdelem_from_slices(
+ &exec_ctx, grpc_slice_intern(grpc_slice_from_static_string("a")),
+ grpc_slice_intern(grpc_slice_from_copied_string(buffer)));
}
/* verify phase */
for (i = 0; i < MANY; i++) {
gpr_ltoa(i, buffer);
- md = grpc_mdelem_from_strings("a", buffer);
- GPR_ASSERT(md == created[i]);
- GRPC_MDELEM_UNREF(md);
+ md = grpc_mdelem_from_slices(
+ &exec_ctx, grpc_slice_intern(grpc_slice_from_static_string("a")),
+ grpc_slice_intern(grpc_slice_from_copied_string(buffer)));
+ GPR_ASSERT(grpc_mdelem_eq(md, created[i]));
+ GRPC_MDELEM_UNREF(&exec_ctx, md);
}
/* cleanup phase */
for (i = 0; i < MANY; i++) {
- GRPC_MDELEM_UNREF(created[i]);
+ GRPC_MDELEM_UNREF(&exec_ctx, created[i]);
}
+ grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
gpr_free(created);
}
-static void test_spin_creating_the_same_thing(void) {
- LOG_TEST("test_spin_creating_the_same_thing");
+static void test_spin_creating_the_same_thing(bool intern_keys,
+ bool intern_values) {
+ gpr_log(GPR_INFO,
+ "test_spin_creating_the_same_thing: intern_keys=%d intern_values=%d",
+ intern_keys, intern_values);
+
+ grpc_init();
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_mdelem a, b, c;
+ GRPC_MDELEM_UNREF(
+ &exec_ctx,
+ a = grpc_mdelem_from_slices(
+ &exec_ctx,
+ maybe_intern(grpc_slice_from_static_string("a"), intern_keys),
+ maybe_intern(grpc_slice_from_static_string("b"), intern_values)));
+ GRPC_MDELEM_UNREF(
+ &exec_ctx,
+ b = grpc_mdelem_from_slices(
+ &exec_ctx,
+ maybe_intern(grpc_slice_from_static_string("a"), intern_keys),
+ maybe_intern(grpc_slice_from_static_string("b"), intern_values)));
+ GRPC_MDELEM_UNREF(
+ &exec_ctx,
+ c = grpc_mdelem_from_slices(
+ &exec_ctx,
+ maybe_intern(grpc_slice_from_static_string("a"), intern_keys),
+ maybe_intern(grpc_slice_from_static_string("b"), intern_values)));
+ if (intern_keys && intern_values) {
+ GPR_ASSERT(a.payload == b.payload);
+ GPR_ASSERT(a.payload == c.payload);
+ }
+ grpc_exec_ctx_finish(&exec_ctx);
+ grpc_shutdown();
+}
+
+static void test_identity_laws(bool intern_keys, bool intern_values) {
+ gpr_log(GPR_INFO, "test_identity_laws: intern_keys=%d intern_values=%d",
+ intern_keys, intern_values);
grpc_init();
- GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", "b"));
- GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", "b"));
- GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", "b"));
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_mdelem a, b, c;
+ a = grpc_mdelem_from_slices(
+ &exec_ctx, maybe_intern(grpc_slice_from_static_string("a"), intern_keys),
+ maybe_intern(grpc_slice_from_static_string("b"), intern_values));
+ b = grpc_mdelem_from_slices(
+ &exec_ctx, maybe_intern(grpc_slice_from_static_string("a"), intern_keys),
+ maybe_intern(grpc_slice_from_static_string("b"), intern_values));
+ c = grpc_mdelem_from_slices(
+ &exec_ctx, maybe_intern(grpc_slice_from_static_string("a"), intern_keys),
+ maybe_intern(grpc_slice_from_static_string("b"), intern_values));
+ GPR_ASSERT(grpc_mdelem_eq(a, a));
+ GPR_ASSERT(grpc_mdelem_eq(b, b));
+ GPR_ASSERT(grpc_mdelem_eq(c, c));
+ GPR_ASSERT(grpc_mdelem_eq(a, b));
+ GPR_ASSERT(grpc_mdelem_eq(b, c));
+ GPR_ASSERT(grpc_mdelem_eq(a, c));
+ GPR_ASSERT(grpc_mdelem_eq(b, a));
+ GPR_ASSERT(grpc_mdelem_eq(c, b));
+ GPR_ASSERT(grpc_mdelem_eq(c, a));
+ if (intern_keys && intern_values) {
+ GPR_ASSERT(a.payload == b.payload);
+ GPR_ASSERT(a.payload == c.payload);
+ } else {
+ GPR_ASSERT(a.payload != b.payload);
+ GPR_ASSERT(a.payload != c.payload);
+ GPR_ASSERT(b.payload != c.payload);
+ }
+ GRPC_MDELEM_UNREF(&exec_ctx, a);
+ GRPC_MDELEM_UNREF(&exec_ctx, b);
+ GRPC_MDELEM_UNREF(&exec_ctx, c);
+ grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
}
@@ -157,24 +241,25 @@ static void test_things_stick_around(void) {
size_t i, j;
char *buffer;
size_t nstrs = 1000;
- grpc_mdstr **strs = gpr_malloc(sizeof(grpc_mdstr *) * nstrs);
+ grpc_slice *strs = gpr_malloc(sizeof(grpc_slice) * nstrs);
size_t *shuf = gpr_malloc(sizeof(size_t) * nstrs);
- grpc_mdstr *test;
+ grpc_slice test;
- LOG_TEST("test_things_stick_around");
+ gpr_log(GPR_INFO, "test_things_stick_around");
grpc_init();
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
for (i = 0; i < nstrs; i++) {
gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%" PRIuPTR "x", i);
- strs[i] = grpc_mdstr_from_string(buffer);
+ strs[i] = grpc_slice_intern(grpc_slice_from_static_string(buffer));
shuf[i] = i;
gpr_free(buffer);
}
for (i = 0; i < nstrs; i++) {
- GRPC_MDSTR_REF(strs[i]);
- GRPC_MDSTR_UNREF(strs[i]);
+ grpc_slice_ref_internal(strs[i]);
+ grpc_slice_unref_internal(&exec_ctx, strs[i]);
}
for (i = 0; i < nstrs; i++) {
@@ -186,143 +271,145 @@ static void test_things_stick_around(void) {
}
for (i = 0; i < nstrs; i++) {
- GRPC_MDSTR_UNREF(strs[shuf[i]]);
+ grpc_slice_unref_internal(&exec_ctx, strs[shuf[i]]);
for (j = i + 1; j < nstrs; j++) {
gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%" PRIuPTR "x",
shuf[j]);
- test = grpc_mdstr_from_string(buffer);
- GPR_ASSERT(test == strs[shuf[j]]);
- GRPC_MDSTR_UNREF(test);
+ test = grpc_slice_intern(grpc_slice_from_static_string(buffer));
+ GPR_ASSERT(grpc_slice_is_equivalent(test, strs[shuf[j]]));
+ grpc_slice_unref_internal(&exec_ctx, test);
gpr_free(buffer);
}
}
+ grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
gpr_free(strs);
gpr_free(shuf);
}
-static void test_slices_work(void) {
- /* ensure no memory leaks when switching representation from mdstr to slice */
- grpc_mdstr *str;
- grpc_slice slice;
-
- LOG_TEST("test_slices_work");
-
- grpc_init();
-
- str = grpc_mdstr_from_string(
- "123456789012345678901234567890123456789012345678901234567890");
- slice = grpc_slice_ref(str->slice);
- GRPC_MDSTR_UNREF(str);
- grpc_slice_unref(slice);
-
- str = grpc_mdstr_from_string(
- "123456789012345678901234567890123456789012345678901234567890");
- slice = grpc_slice_ref(str->slice);
- grpc_slice_unref(slice);
- GRPC_MDSTR_UNREF(str);
-
- grpc_shutdown();
-}
-
-static void test_base64_and_huffman_works(void) {
- grpc_mdstr *str;
- grpc_slice slice1;
- grpc_slice slice2;
-
- LOG_TEST("test_base64_and_huffman_works");
-
- grpc_init();
- str = grpc_mdstr_from_string("abcdefg");
- slice1 = grpc_mdstr_as_base64_encoded_and_huffman_compressed(str);
- slice2 = grpc_chttp2_base64_encode_and_huffman_compress(str->slice);
- GPR_ASSERT(0 == grpc_slice_cmp(slice1, slice2));
-
- grpc_slice_unref(slice2);
- GRPC_MDSTR_UNREF(str);
- grpc_shutdown();
-}
-
static void test_user_data_works(void) {
int *ud1;
int *ud2;
- grpc_mdelem *md;
- LOG_TEST("test_user_data_works");
+ grpc_mdelem md;
+ gpr_log(GPR_INFO, "test_user_data_works");
grpc_init();
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
ud1 = gpr_malloc(sizeof(int));
*ud1 = 1;
ud2 = gpr_malloc(sizeof(int));
*ud2 = 2;
- md = grpc_mdelem_from_strings("abc", "123");
+ md = grpc_mdelem_from_slices(
+ &exec_ctx, grpc_slice_intern(grpc_slice_from_static_string("abc")),
+ grpc_slice_intern(grpc_slice_from_static_string("123")));
grpc_mdelem_set_user_data(md, gpr_free, ud1);
grpc_mdelem_set_user_data(md, gpr_free, ud2);
GPR_ASSERT(grpc_mdelem_get_user_data(md, gpr_free) == ud1);
- GRPC_MDELEM_UNREF(md);
+ GRPC_MDELEM_UNREF(&exec_ctx, md);
+ grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
}
-static void verify_ascii_header_size(const char *key, const char *value) {
- grpc_mdelem *elem = grpc_mdelem_from_strings(key, value);
+static void verify_ascii_header_size(grpc_exec_ctx *exec_ctx, const char *key,
+ const char *value, bool intern_key,
+ bool intern_value) {
+ grpc_mdelem elem = grpc_mdelem_from_slices(
+ exec_ctx, maybe_intern(grpc_slice_from_static_string(key), intern_key),
+ maybe_intern(grpc_slice_from_static_string(value), intern_value));
size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem);
size_t expected_size = 32 + strlen(key) + strlen(value);
GPR_ASSERT(expected_size == elem_size);
- GRPC_MDELEM_UNREF(elem);
+ GRPC_MDELEM_UNREF(exec_ctx, elem);
}
-static void verify_binary_header_size(const char *key, const uint8_t *value,
- size_t value_len) {
- grpc_mdelem *elem = grpc_mdelem_from_string_and_buffer(key, value, value_len);
- GPR_ASSERT(grpc_is_binary_header(key, strlen(key)));
+static void verify_binary_header_size(grpc_exec_ctx *exec_ctx, const char *key,
+ const uint8_t *value, size_t value_len,
+ bool intern_key, bool intern_value) {
+ grpc_mdelem elem = grpc_mdelem_from_slices(
+ exec_ctx, maybe_intern(grpc_slice_from_static_string(key), intern_key),
+ maybe_intern(grpc_slice_from_static_buffer(value, value_len),
+ intern_value));
+ GPR_ASSERT(grpc_is_binary_header(GRPC_MDKEY(elem)));
size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem);
grpc_slice value_slice =
grpc_slice_from_copied_buffer((const char *)value, value_len);
grpc_slice base64_encoded = grpc_chttp2_base64_encode(value_slice);
size_t expected_size = 32 + strlen(key) + GRPC_SLICE_LENGTH(base64_encoded);
GPR_ASSERT(expected_size == elem_size);
- grpc_slice_unref(value_slice);
- grpc_slice_unref(base64_encoded);
- GRPC_MDELEM_UNREF(elem);
+ grpc_slice_unref_internal(exec_ctx, value_slice);
+ grpc_slice_unref_internal(exec_ctx, base64_encoded);
+ GRPC_MDELEM_UNREF(exec_ctx, elem);
}
#define BUFFER_SIZE 64
-static void test_mdelem_sizes_in_hpack(void) {
- LOG_TEST("test_mdelem_size");
+static void test_mdelem_sizes_in_hpack(bool intern_key, bool intern_value) {
+ gpr_log(GPR_INFO, "test_mdelem_size: intern_key=%d intern_value=%d",
+ intern_key, intern_value);
grpc_init();
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
uint8_t binary_value[BUFFER_SIZE] = {0};
for (uint8_t i = 0; i < BUFFER_SIZE; i++) {
binary_value[i] = i;
}
- verify_ascii_header_size("hello", "world");
- verify_ascii_header_size("hello", "worldxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- verify_ascii_header_size(":scheme", "http");
+ verify_ascii_header_size(&exec_ctx, "hello", "world", intern_key,
+ intern_value);
+ verify_ascii_header_size(&exec_ctx, "hello",
+ "worldxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", intern_key,
+ intern_value);
+ verify_ascii_header_size(&exec_ctx, ":scheme", "http", intern_key,
+ intern_value);
for (uint8_t i = 0; i < BUFFER_SIZE; i++) {
- verify_binary_header_size("hello-bin", binary_value, i);
+ verify_binary_header_size(&exec_ctx, "hello-bin", binary_value, i,
+ intern_key, intern_value);
}
- const char *static_metadata = grpc_static_metadata_strings[0];
- memcpy(binary_value, static_metadata, strlen(static_metadata));
- verify_binary_header_size("hello-bin", binary_value, strlen(static_metadata));
+ grpc_exec_ctx_finish(&exec_ctx);
+ grpc_shutdown();
+}
+static void test_copied_static_metadata(bool dup_key, bool dup_value) {
+ gpr_log(GPR_INFO, "test_static_metadata: dup_key=%d dup_value=%d", dup_key,
+ dup_value);
+ grpc_init();
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
+ for (size_t i = 0; i < GRPC_STATIC_MDELEM_COUNT; i++) {
+ grpc_mdelem p = GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[i],
+ GRPC_MDELEM_STORAGE_STATIC);
+ grpc_mdelem q =
+ grpc_mdelem_from_slices(&exec_ctx, maybe_dup(GRPC_MDKEY(p), dup_key),
+ maybe_dup(GRPC_MDVALUE(p), dup_value));
+ GPR_ASSERT(grpc_mdelem_eq(p, q));
+ if (dup_key || dup_value) {
+ GPR_ASSERT(p.payload != q.payload);
+ } else {
+ GPR_ASSERT(p.payload == q.payload);
+ }
+ }
+
+ grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
test_no_op();
- test_create_string();
- test_create_metadata();
- test_create_many_ephemeral_metadata();
+ for (int k = 0; k <= 1; k++) {
+ for (int v = 0; v <= 1; v++) {
+ test_create_metadata(k, v);
+ test_create_many_ephemeral_metadata(k, v);
+ test_identity_laws(k, v);
+ test_spin_creating_the_same_thing(k, v);
+ test_mdelem_sizes_in_hpack(k, v);
+ test_copied_static_metadata(k, v);
+ }
+ }
test_create_many_persistant_metadata();
- test_spin_creating_the_same_thing();
test_things_stick_around();
- test_slices_work();
- test_base64_and_huffman_works();
test_user_data_works();
- test_mdelem_sizes_in_hpack();
return 0;
}
diff --git a/test/core/transport/timeout_encoding_test.c b/test/core/transport/timeout_encoding_test.c
index b6004af7b4..10e1804995 100644
--- a/test/core/transport/timeout_encoding_test.c
+++ b/test/core/transport/timeout_encoding_test.c
@@ -88,7 +88,8 @@ void test_encoding(void) {
static void assert_decodes_as(const char *buffer, gpr_timespec expected) {
gpr_timespec got;
gpr_log(GPR_INFO, "check decoding '%s'", buffer);
- GPR_ASSERT(1 == grpc_http2_decode_timeout(buffer, &got));
+ GPR_ASSERT(1 == grpc_http2_decode_timeout(
+ grpc_slice_from_static_string(buffer), &got));
GPR_ASSERT(0 == gpr_time_cmp(got, expected));
}
@@ -134,18 +135,23 @@ void test_decoding(void) {
assert_decodes_as("9999999999S", gpr_inf_future(GPR_TIMESPAN));
}
-void test_decoding_fails(void) {
+static void assert_decoding_fails(const char *s) {
gpr_timespec x;
+ GPR_ASSERT(0 ==
+ grpc_http2_decode_timeout(grpc_slice_from_static_string(s), &x));
+}
+
+void test_decoding_fails(void) {
LOG_TEST("test_decoding_fails");
- GPR_ASSERT(0 == grpc_http2_decode_timeout("", &x));
- GPR_ASSERT(0 == grpc_http2_decode_timeout(" ", &x));
- GPR_ASSERT(0 == grpc_http2_decode_timeout("x", &x));
- GPR_ASSERT(0 == grpc_http2_decode_timeout("1", &x));
- GPR_ASSERT(0 == grpc_http2_decode_timeout("1x", &x));
- GPR_ASSERT(0 == grpc_http2_decode_timeout("1ux", &x));
- GPR_ASSERT(0 == grpc_http2_decode_timeout("!", &x));
- GPR_ASSERT(0 == grpc_http2_decode_timeout("n1", &x));
- GPR_ASSERT(0 == grpc_http2_decode_timeout("-1u", &x));
+ assert_decoding_fails("");
+ assert_decoding_fails(" ");
+ assert_decoding_fails("x");
+ assert_decoding_fails("1");
+ assert_decoding_fails("1x");
+ assert_decoding_fails("1ux");
+ assert_decoding_fails("!");
+ assert_decoding_fails("n1");
+ assert_decoding_fails("-1u");
}
int main(int argc, char **argv) {
diff --git a/test/core/util/passthru_endpoint.c b/test/core/util/passthru_endpoint.c
index b3405f02e9..ecffe35e9e 100644
--- a/test/core/util/passthru_endpoint.c
+++ b/test/core/util/passthru_endpoint.c
@@ -39,6 +39,8 @@
#include <grpc/support/string_util.h>
#include "src/core/lib/iomgr/sockaddr.h"
+#include "src/core/lib/slice/slice_internal.h"
+
typedef struct passthru_endpoint passthru_endpoint;
typedef struct {
@@ -133,8 +135,8 @@ static void me_destroy(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
if (0 == --p->halves) {
gpr_mu_unlock(&p->mu);
gpr_mu_destroy(&p->mu);
- grpc_slice_buffer_destroy(&p->client.read_buffer);
- grpc_slice_buffer_destroy(&p->server.read_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &p->client.read_buffer);
+ grpc_slice_buffer_destroy_internal(exec_ctx, &p->server.read_buffer);
grpc_resource_user_unref(exec_ctx, p->client.resource_user);
grpc_resource_user_unref(exec_ctx, p->server.resource_user);
gpr_free(p);
diff --git a/test/core/util/port_server_client.c b/test/core/util/port_server_client.c
index b2342feeb4..384a158c47 100644
--- a/test/core/util/port_server_client.c
+++ b/test/core/util/port_server_client.c
@@ -104,7 +104,7 @@ void grpc_free_port_using_server(char *server, int port) {
grpc_httpcli_get(&exec_ctx, &context, &pr.pops, resource_quota, &req,
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
grpc_closure_create(freed_port_from_server, &pr), &rsp);
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
gpr_mu_lock(pr.mu);
while (!pr.done) {
grpc_pollset_worker *worker = NULL;
@@ -176,7 +176,7 @@ static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
grpc_closure_create(got_port_from_server, pr),
&pr->response);
- grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
return;
}
GPR_ASSERT(response);
@@ -223,7 +223,7 @@ int grpc_pick_port_using_server(char *server) {
GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10),
grpc_closure_create(got_port_from_server, &pr),
&pr.response);
- grpc_resource_quota_internal_unref(&exec_ctx, resource_quota);
+ grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
grpc_exec_ctx_finish(&exec_ctx);
gpr_mu_lock(pr.mu);
while (pr.port == -1) {
diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py
index cf3762dbb8..b1b7840cfd 100755
--- a/tools/codegen/core/gen_static_metadata.py
+++ b/tools/codegen/core/gen_static_metadata.py
@@ -31,8 +31,11 @@
import hashlib
import itertools
+import collections
import os
import sys
+import subprocess
+import re
# configuration: a list of either strings or 2-tuples of strings
# a single string represents a static grpc_mdstr
@@ -40,6 +43,7 @@ import sys
# also be created)
CONFIG = [
+ # metadata strings
'grpc-timeout',
'grpc-internal-encoding-request',
'grpc-payload-bin',
@@ -54,6 +58,14 @@ CONFIG = [
'grpc-tracing-bin',
'grpc-stats-bin',
'',
+ # channel arg keys
+ 'grpc.wait_for_ready',
+ 'grpc.timeout',
+ 'grpc.max_request_message_bytes',
+ 'grpc.max_response_message_bytes',
+ # well known method names
+ '/grpc.lb.v1.LoadBalancer/BalanceLoad',
+ # metadata elements
('grpc-status', '0'),
('grpc-status', '1'),
('grpc-status', '2'),
@@ -181,24 +193,30 @@ def put_banner(files, banner):
print >>f
# build a list of all the strings we need
-all_strs = set()
-all_elems = set()
+all_strs = list()
+all_elems = list()
static_userdata = {}
for elem in CONFIG:
if isinstance(elem, tuple):
- all_strs.add(elem[0])
- all_strs.add(elem[1])
- all_elems.add(elem)
+ if elem[0] not in all_strs:
+ all_strs.append(elem[0])
+ if elem[1] not in all_strs:
+ all_strs.append(elem[1])
+ if elem not in all_elems:
+ all_elems.append(elem)
else:
- all_strs.add(elem)
+ if elem not in all_strs:
+ all_strs.append(elem)
compression_elems = []
for mask in range(1, 1<<len(COMPRESSION_ALGORITHMS)):
val = ','.join(COMPRESSION_ALGORITHMS[alg]
for alg in range(0, len(COMPRESSION_ALGORITHMS))
if (1 << alg) & mask)
elem = ('grpc-accept-encoding', val)
- all_strs.add(val)
- all_elems.add(elem)
+ if val not in all_strs:
+ all_strs.append(val)
+ if elem not in all_elems:
+ all_elems.append(elem)
compression_elems.append(elem)
static_userdata[elem] = 1 + (mask | 1)
all_strs = sorted(list(all_strs), key=mangle)
@@ -279,14 +297,54 @@ print >>H
print >>C, '#include "src/core/lib/transport/static_metadata.h"'
print >>C
+print >>C, '#include "src/core/lib/slice/slice_internal.h"'
+print >>C
print >>H, '#define GRPC_STATIC_MDSTR_COUNT %d' % len(all_strs)
-print >>H, 'extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];'
+print >>H, 'extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];'
for i, elem in enumerate(all_strs):
print >>H, '/* "%s" */' % elem
- print >>H, '#define %s (&grpc_static_mdstr_table[%d])' % (mangle(elem).upper(), i)
+ print >>H, '#define %s (grpc_static_slice_table[%d])' % (mangle(elem).upper(), i)
+print >>H
+print >>H, 'bool grpc_is_static_metadata_string(grpc_slice slice);'
print >>H
-print >>C, 'grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];'
+print >>C, 'static uint8_t g_raw_bytes[] = {%s};' % (','.join('%d' % ord(c) for c in ''.join(all_strs)))
+print >>C
+print >>C, 'static void static_ref(void *unused) {}'
+print >>C, 'static void static_unref(grpc_exec_ctx *exec_ctx, void *unused) {}'
+print >>C, 'static const grpc_slice_refcount_vtable static_vtable = {static_ref, static_unref, grpc_static_slice_hash};';
+print >>C, 'static grpc_slice_refcount g_refcnt = {&static_vtable};'
+print >>C
+print >>C, 'bool grpc_is_static_metadata_string(grpc_slice slice) {'
+print >>C, ' return slice.refcount != NULL && slice.refcount->vtable == &static_vtable;'
+print >>C, '}'
+print >>C
+print >>C, 'const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {'
+str_ofs = 0
+revmap = {}
+zero_length_idx = None
+id2strofs = {}
+def slice_def(i):
+ return '{.refcount = &g_refcnt, .data.refcounted = {.bytes = g_raw_bytes+%d, .length=%d}}' % (id2strofs[i], len(all_strs[i]))
+for i, elem in enumerate(all_strs):
+ id2strofs[i] = str_ofs
+ print >>C, slice_def(i) + ','
+ revmap[str_ofs] = i
+ if len(elem) == 0: zero_length_idx = i
+ str_ofs += len(elem);
+print >>C, '};'
+print >>C
+print >>C, 'static const uint8_t g_revmap[] = {%s};' % ','.join('%d' % (revmap[i] if i in revmap else 255) for i in range(0, str_ofs))
+print >>C
+print >>H, 'int grpc_static_metadata_index(grpc_slice slice);'
+print >>C, 'int grpc_static_metadata_index(grpc_slice slice) {'
+print >>C, ' if (GRPC_SLICE_LENGTH(slice) == 0) return %d;' % zero_length_idx
+print >>C, ' if (slice.refcount != &g_refcnt) return -1;'
+print >>C, ' size_t ofs = (size_t)(slice.data.refcounted.bytes - g_raw_bytes);'
+print >>C, ' if (ofs > sizeof(g_revmap)) return -1;'
+print >>C, ' uint8_t id = g_revmap[ofs];'
+print >>C, ' return id == 255 ? -1 : (grpc_static_slice_table[id].data.refcounted.length == slice.data.refcounted.length? id : -1);'
+print >>C, '}'
print >>C
print >>D, '# hpack fuzzing dictionary'
@@ -297,13 +355,12 @@ for i, elem in enumerate(all_elems):
[len(elem[1])] + [ord(c) for c in elem[1]]))
print >>H, '#define GRPC_STATIC_MDELEM_COUNT %d' % len(all_elems)
-print >>H, 'extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];'
+print >>H, 'extern grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];'
print >>H, 'extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];'
for i, elem in enumerate(all_elems):
print >>H, '/* "%s": "%s" */' % elem
- print >>H, '#define %s (&grpc_static_mdelem_table[%d])' % (mangle(elem).upper(), i)
+ print >>H, '#define %s (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[%d], GRPC_MDELEM_STORAGE_STATIC))' % (mangle(elem).upper(), i)
print >>H
-print >>C, 'grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];'
print >>C, 'uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {'
print >>C, ' %s' % ','.join('%d' % static_userdata.get(elem, 0) for elem in all_elems)
print >>C, '};'
@@ -319,25 +376,86 @@ def md_idx(m):
if m == m2:
return i
-print >>H, 'extern const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT*2];'
-print >>C, 'const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT*2] = {'
-print >>C, ','.join('%d' % str_idx(x) for x in itertools.chain.from_iterable([a,b] for a, b in all_elems))
-print >>C, '};'
+def perfect_hash(keys, name):
+ ok = False
+ cmd = '%s/perfect/build.sh' % (os.path.dirname(sys.argv[0]))
+ subprocess.check_call(cmd, shell=True)
+ for offset in reversed(range(0, min(keys))):
+ tmp = open('/tmp/keys.txt', 'w')
+ tmp.write(''.join('%d\n' % (x - offset) for x in keys))
+ tmp.close()
+ cmd = '%s/perfect/run.sh %s -dms' % (os.path.dirname(sys.argv[0]), tmp.name)
+ out = subprocess.check_output(cmd, shell=True)
+ if 'fatal error' not in out:
+ ok = True
+ break
+ assert ok, "Failed to find hash of keys in /tmp/keys.txt"
+
+ code = ''
+
+ results = {}
+ with open('%s/perfect/phash.h' % os.path.dirname(sys.argv[0])) as f:
+ txt = f.read()
+ for var in ('PHASHLEN', 'PHASHNKEYS', 'PHASHRANGE', 'PHASHSALT'):
+ val = re.search(r'#define %s ([0-9a-zA-Z]+)' % var, txt).group(1)
+ code += '#define %s_%s %s\n' % (name.upper(), var, val)
+ results[var] = val
+ code += '\n'
+ pycode = 'def f(val):\n'
+ pycode += ' val -= %d\n' % offset
+ with open('%s/perfect/phash.c' % os.path.dirname(sys.argv[0])) as f:
+ txt = f.read()
+ tabdata = re.search(r'ub1 tab\[\] = \{([^}]+)\}', txt, re.MULTILINE).group(1)
+ code += 'static const uint8_t %s_tab[] = {%s};\n\n' % (name, tabdata)
+ func_body = re.search(r'ub4 phash\(val\)\nub4 val;\n\{([^}]+)\}', txt, re.MULTILINE).group(1).replace('ub4', 'uint32_t')
+ code += 'static uint32_t %s_phash(uint32_t val) {\nval -= %d;\n%s}\n' % (name,
+ offset, func_body.replace('tab', '%s_tab' % name))
+ pycode += ' tab=(%s)' % tabdata.replace('\n', '')
+ pycode += '\n'.join(' %s' % s.strip() for s in func_body.splitlines()[2:])
+ g = {}
+ exec pycode in g
+ pyfunc = g['f']
+
+ results['code'] = code
+ results['pyfunc'] = pyfunc
+ return results
+
+elem_keys = [str_idx(elem[0]) * len(all_strs) + str_idx(elem[1]) for elem in all_elems]
+elem_hash = perfect_hash(elem_keys, "elems")
+print >>C, elem_hash['code']
+
+keys = [0] * int(elem_hash['PHASHRANGE'])
+idxs = [-1] * int(elem_hash['PHASHNKEYS'])
+for i, k in enumerate(elem_keys):
+ h = elem_hash['pyfunc'](k)
+ assert keys[h] == 0
+ keys[h] = k
+ idxs[h] = i
+print >>C, 'static const uint16_t elem_keys[] = {%s};' % ','.join('%d' % k for k in keys)
+print >>C, 'static const uint8_t elem_idxs[] = {%s};' % ','.join('%d' % i for i in idxs)
print >>C
-print >>H, 'extern const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT];'
-print >>C, 'const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = {'
-print >>C, '%s' % ',\n'.join(' "%s"' % s for s in all_strs)
-print >>C, '};'
+print >>H, 'grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b);'
+print >>C, 'grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {'
+print >>C, ' if (a == -1 || b == -1) return GRPC_MDNULL;'
+print >>C, ' uint32_t k = (uint32_t)(a * %d + b);' % len(all_strs)
+print >>C, ' uint32_t h = elems_phash(k);'
+print >>C, ' return elem_keys[h] == k ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], GRPC_MDELEM_STORAGE_STATIC) : GRPC_MDNULL;'
+print >>C, '}'
print >>C
+print >>C, 'grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {'
+for a, b in all_elems:
+ print >>C, '{%s,%s},' % (slice_def(str_idx(a)), slice_def(str_idx(b)))
+print >>C, '};'
+
print >>H, 'extern const uint8_t grpc_static_accept_encoding_metadata[%d];' % (1 << len(COMPRESSION_ALGORITHMS))
print >>C, 'const uint8_t grpc_static_accept_encoding_metadata[%d] = {' % (1 << len(COMPRESSION_ALGORITHMS))
print >>C, '0,%s' % ','.join('%d' % md_idx(elem) for elem in compression_elems)
print >>C, '};'
print >>C
-print >>H, '#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]])'
+print >>H, '#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC))'
print >>H, '#endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */'
diff --git a/tools/codegen/core/perfect/.gitignore b/tools/codegen/core/perfect/.gitignore
new file mode 100644
index 0000000000..c1489f0819
--- /dev/null
+++ b/tools/codegen/core/perfect/.gitignore
@@ -0,0 +1,7 @@
+perfect
+*.o
+phash.h
+phash.c
+compile.txt
+hash.txt
+
diff --git a/tools/codegen/core/perfect/build.sh b/tools/codegen/core/perfect/build.sh
new file mode 100755
index 0000000000..139556ea48
--- /dev/null
+++ b/tools/codegen/core/perfect/build.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -e
+cd $(dirname $0)
+gcc -o perfect perfect.c recycle.c lookupa.c perfhex.c 2> compile.txt
diff --git a/tools/codegen/core/perfect/lookupa.c b/tools/codegen/core/perfect/lookupa.c
new file mode 100644
index 0000000000..c122c4f107
--- /dev/null
+++ b/tools/codegen/core/perfect/lookupa.c
@@ -0,0 +1,240 @@
+/*
+--------------------------------------------------------------------
+lookupa.c, by Bob Jenkins, December 1996. Same as lookup2.c
+Use this code however you wish. Public Domain. No warranty.
+Source is http://burtleburtle.net/bob/c/lookupa.c
+--------------------------------------------------------------------
+*/
+#ifndef STANDARD
+#include "standard.h"
+#endif
+#ifndef LOOKUPA
+#include "lookupa.h"
+#endif
+
+/*
+--------------------------------------------------------------------
+mix -- mix 3 32-bit values reversibly.
+For every delta with one or two bit set, and the deltas of all three
+ high bits or all three low bits, whether the original value of a,b,c
+ is almost all zero or is uniformly distributed,
+* If mix() is run forward or backward, at least 32 bits in a,b,c
+ have at least 1/4 probability of changing.
+* If mix() is run forward, every bit of c will change between 1/3 and
+ 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.)
+mix() was built out of 36 single-cycle latency instructions in a
+ structure that could supported 2x parallelism, like so:
+ a -= b;
+ a -= c; x = (c>>13);
+ b -= c; a ^= x;
+ b -= a; x = (a<<8);
+ c -= a; b ^= x;
+ c -= b; x = (b>>13);
+ ...
+ Unfortunately, superscalar Pentiums and Sparcs can't take advantage
+ of that parallelism. They've also turned some of those single-cycle
+ latency instructions into multi-cycle latency instructions. Still,
+ this is the fastest good hash I could find. There were about 2^^68
+ to choose from. I only looked at a billion or so.
+--------------------------------------------------------------------
+*/
+#define mix(a,b,c) \
+{ \
+ a -= b; a -= c; a ^= (c>>13); \
+ b -= c; b -= a; b ^= (a<<8); \
+ c -= a; c -= b; c ^= (b>>13); \
+ a -= b; a -= c; a ^= (c>>12); \
+ b -= c; b -= a; b ^= (a<<16); \
+ c -= a; c -= b; c ^= (b>>5); \
+ a -= b; a -= c; a ^= (c>>3); \
+ b -= c; b -= a; b ^= (a<<10); \
+ c -= a; c -= b; c ^= (b>>15); \
+}
+
+/*
+--------------------------------------------------------------------
+lookup() -- hash a variable-length key into a 32-bit value
+ k : the key (the unaligned variable-length array of bytes)
+ len : the length of the key, counting by bytes
+ level : can be any 4-byte value
+Returns a 32-bit value. Every bit of the key affects every bit of
+the return value. Every 1-bit and 2-bit delta achieves avalanche.
+About 6len+35 instructions.
+
+The best hash table sizes are powers of 2. There is no need to do
+mod a prime (mod is sooo slow!). If you need less than 32 bits,
+use a bitmask. For example, if you need only 10 bits, do
+ h = (h & hashmask(10));
+In which case, the hash table should have hashsize(10) elements.
+
+If you are hashing n strings (ub1 **)k, do it like this:
+ for (i=0, h=0; i<n; ++i) h = lookup( k[i], len[i], h);
+
+By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this
+code any way you wish, private, educational, or commercial.
+
+See http://burtleburtle.net/bob/hash/evahash.html
+Use for hash table lookup, or anything where one collision in 2^32 is
+acceptable. Do NOT use for cryptographic purposes.
+--------------------------------------------------------------------
+*/
+
+ub4 lookup( k, length, level)
+register ub1 *k; /* the key */
+register ub4 length; /* the length of the key */
+register ub4 level; /* the previous hash, or an arbitrary value */
+{
+ register ub4 a,b,c,len;
+
+ /* Set up the internal state */
+ len = length;
+ a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
+ c = level; /* the previous hash value */
+
+ /*---------------------------------------- handle most of the key */
+ while (len >= 12)
+ {
+ a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
+ b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
+ c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
+ mix(a,b,c);
+ k += 12; len -= 12;
+ }
+
+ /*------------------------------------- handle the last 11 bytes */
+ c += length;
+ switch(len) /* all the case statements fall through */
+ {
+ case 11: c+=((ub4)k[10]<<24);
+ case 10: c+=((ub4)k[9]<<16);
+ case 9 : c+=((ub4)k[8]<<8);
+ /* the first byte of c is reserved for the length */
+ case 8 : b+=((ub4)k[7]<<24);
+ case 7 : b+=((ub4)k[6]<<16);
+ case 6 : b+=((ub4)k[5]<<8);
+ case 5 : b+=k[4];
+ case 4 : a+=((ub4)k[3]<<24);
+ case 3 : a+=((ub4)k[2]<<16);
+ case 2 : a+=((ub4)k[1]<<8);
+ case 1 : a+=k[0];
+ /* case 0: nothing left to add */
+ }
+ mix(a,b,c);
+ /*-------------------------------------------- report the result */
+ return c;
+}
+
+
+/*
+--------------------------------------------------------------------
+mixc -- mixc 8 4-bit values as quickly and thoroughly as possible.
+Repeating mix() three times achieves avalanche.
+Repeating mix() four times eliminates all funnels and all
+ characteristics stronger than 2^{-11}.
+--------------------------------------------------------------------
+*/
+#define mixc(a,b,c,d,e,f,g,h) \
+{ \
+ a^=b<<11; d+=a; b+=c; \
+ b^=c>>2; e+=b; c+=d; \
+ c^=d<<8; f+=c; d+=e; \
+ d^=e>>16; g+=d; e+=f; \
+ e^=f<<10; h+=e; f+=g; \
+ f^=g>>4; a+=f; g+=h; \
+ g^=h<<8; b+=g; h+=a; \
+ h^=a>>9; c+=h; a+=b; \
+}
+
+/*
+--------------------------------------------------------------------
+checksum() -- hash a variable-length key into a 256-bit value
+ k : the key (the unaligned variable-length array of bytes)
+ len : the length of the key, counting by bytes
+ state : an array of CHECKSTATE 4-byte values (256 bits)
+The state is the checksum. Every bit of the key affects every bit of
+the state. There are no funnels. About 112+6.875len instructions.
+
+If you are hashing n strings (ub1 **)k, do it like this:
+ for (i=0; i<8; ++i) state[i] = 0x9e3779b9;
+ for (i=0, h=0; i<n; ++i) checksum( k[i], len[i], state);
+
+See http://burtleburtle.net/bob/hash/evahash.html
+Use to detect changes between revisions of documents, assuming nobody
+is trying to cause collisions. Do NOT use for cryptography.
+--------------------------------------------------------------------
+*/
+void checksum( k, len, state)
+register ub1 *k;
+register ub4 len;
+register ub4 *state;
+{
+ register ub4 a,b,c,d,e,f,g,h,length;
+
+ /* Use the length and level; add in the golden ratio. */
+ length = len;
+ a=state[0]; b=state[1]; c=state[2]; d=state[3];
+ e=state[4]; f=state[5]; g=state[6]; h=state[7];
+
+ /*---------------------------------------- handle most of the key */
+ while (len >= 32)
+ {
+ a += (k[0] +(k[1]<<8) +(k[2]<<16) +(k[3]<<24));
+ b += (k[4] +(k[5]<<8) +(k[6]<<16) +(k[7]<<24));
+ c += (k[8] +(k[9]<<8) +(k[10]<<16)+(k[11]<<24));
+ d += (k[12]+(k[13]<<8)+(k[14]<<16)+(k[15]<<24));
+ e += (k[16]+(k[17]<<8)+(k[18]<<16)+(k[19]<<24));
+ f += (k[20]+(k[21]<<8)+(k[22]<<16)+(k[23]<<24));
+ g += (k[24]+(k[25]<<8)+(k[26]<<16)+(k[27]<<24));
+ h += (k[28]+(k[29]<<8)+(k[30]<<16)+(k[31]<<24));
+ mixc(a,b,c,d,e,f,g,h);
+ mixc(a,b,c,d,e,f,g,h);
+ mixc(a,b,c,d,e,f,g,h);
+ mixc(a,b,c,d,e,f,g,h);
+ k += 32; len -= 32;
+ }
+
+ /*------------------------------------- handle the last 31 bytes */
+ h += length;
+ switch(len)
+ {
+ case 31: h+=(k[30]<<24);
+ case 30: h+=(k[29]<<16);
+ case 29: h+=(k[28]<<8);
+ case 28: g+=(k[27]<<24);
+ case 27: g+=(k[26]<<16);
+ case 26: g+=(k[25]<<8);
+ case 25: g+=k[24];
+ case 24: f+=(k[23]<<24);
+ case 23: f+=(k[22]<<16);
+ case 22: f+=(k[21]<<8);
+ case 21: f+=k[20];
+ case 20: e+=(k[19]<<24);
+ case 19: e+=(k[18]<<16);
+ case 18: e+=(k[17]<<8);
+ case 17: e+=k[16];
+ case 16: d+=(k[15]<<24);
+ case 15: d+=(k[14]<<16);
+ case 14: d+=(k[13]<<8);
+ case 13: d+=k[12];
+ case 12: c+=(k[11]<<24);
+ case 11: c+=(k[10]<<16);
+ case 10: c+=(k[9]<<8);
+ case 9 : c+=k[8];
+ case 8 : b+=(k[7]<<24);
+ case 7 : b+=(k[6]<<16);
+ case 6 : b+=(k[5]<<8);
+ case 5 : b+=k[4];
+ case 4 : a+=(k[3]<<24);
+ case 3 : a+=(k[2]<<16);
+ case 2 : a+=(k[1]<<8);
+ case 1 : a+=k[0];
+ }
+ mixc(a,b,c,d,e,f,g,h);
+ mixc(a,b,c,d,e,f,g,h);
+ mixc(a,b,c,d,e,f,g,h);
+ mixc(a,b,c,d,e,f,g,h);
+
+ /*-------------------------------------------- report the result */
+ state[0]=a; state[1]=b; state[2]=c; state[3]=d;
+ state[4]=e; state[5]=f; state[6]=g; state[7]=h;
+}
diff --git a/tools/codegen/core/perfect/lookupa.h b/tools/codegen/core/perfect/lookupa.h
new file mode 100644
index 0000000000..0b27db680d
--- /dev/null
+++ b/tools/codegen/core/perfect/lookupa.h
@@ -0,0 +1,24 @@
+/*
+------------------------------------------------------------------------------
+By Bob Jenkins, September 1996.
+lookupa.h, a hash function for table lookup, same function as lookup.c.
+Use this code in any way you wish. Public Domain. It has no warranty.
+Source is http://burtleburtle.net/bob/c/lookupa.h
+------------------------------------------------------------------------------
+*/
+
+#ifndef STANDARD
+#include "standard.h"
+#endif
+
+#ifndef LOOKUPA
+#define LOOKUPA
+
+#define CHECKSTATE 8
+#define hashsize(n) ((ub4)1<<(n))
+#define hashmask(n) (hashsize(n)-1)
+
+ub4 lookup(/*_ ub1 *k, ub4 length, ub4 level _*/);
+void checksum(/*_ ub1 *k, ub4 length, ub4 *state _*/);
+
+#endif /* LOOKUPA */
diff --git a/tools/codegen/core/perfect/perfect.c b/tools/codegen/core/perfect/perfect.c
new file mode 100644
index 0000000000..67fd2fd262
--- /dev/null
+++ b/tools/codegen/core/perfect/perfect.c
@@ -0,0 +1,1367 @@
+/*
+------------------------------------------------------------------------------
+perfect.c: code to generate code for a hash for perfect hashing.
+(c) Bob Jenkins, September 1996, December 1999
+You may use this code in any way you wish, and it is free. No warranty.
+I hereby place this in the public domain.
+Source is http://burtleburtle.net/bob/c/perfect.c
+
+This generates a minimal perfect hash function. That means, given a
+set of n keys, this determines a hash function that maps each of
+those keys into a value in 0..n-1 with no collisions.
+
+The perfect hash function first uses a normal hash function on the key
+to determine (a,b) such that the pair (a,b) is distinct for all
+keys, then it computes a^scramble[tab[b]] to get the final perfect hash.
+tab[] is an array of 1-byte values and scramble[] is a 256-term array of
+2-byte or 4-byte values. If there are n keys, the length of tab[] is a
+power of two between n/3 and n.
+
+I found the idea of computing distinct (a,b) values in "Practical minimal
+perfect hash functions for large databases", Fox, Heath, Chen, and Daoud,
+Communications of the ACM, January 1992. They found the idea in Chichelli
+(CACM Jan 1980). Beyond that, our methods differ.
+
+The key is hashed to a pair (a,b) where a in 0..*alen*-1 and b in
+0..*blen*-1. A fast hash function determines both a and b
+simultaneously. Any decent hash function is likely to produce
+hashes so that (a,b) is distinct for all pairs. I try the hash
+using different values of *salt* until all pairs are distinct.
+
+The final hash is (a XOR scramble[tab[b]]). *scramble* is a
+predetermined mapping of 0..255 into 0..smax-1. *tab* is an
+array that we fill in in such a way as to make the hash perfect.
+
+First we fill in all values of *tab* that are used by more than one
+key. We try all possible values for each position until one works.
+
+This leaves m unmapped keys and m values that something could hash to.
+If you treat unmapped keys as lefthand nodes and unused hash values
+as righthand nodes, and draw a line connecting each key to each hash
+value it could map to, you get a bipartite graph. We attempt to
+find a perfect matching in this graph. If we succeed, we have
+determined a perfect hash for the whole set of keys.
+
+*scramble* is used because (a^tab[i]) clusters keys around *a*.
+------------------------------------------------------------------------------
+*/
+
+#ifndef STANDARD
+#include "standard.h"
+#endif
+#ifndef LOOKUPA
+#include "lookupa.h"
+#endif
+#ifndef RECYCLE
+#include "recycle.h"
+#endif
+#ifndef PERFECT
+#include "perfect.h"
+#endif
+
+/*
+------------------------------------------------------------------------------
+Find the mapping that will produce a perfect hash
+------------------------------------------------------------------------------
+*/
+
+/* return the ceiling of the log (base 2) of val */
+ub4 mylog2(val)
+ub4 val;
+{
+ ub4 i;
+ for (i=0; ((ub4)1<<i) < val; ++i)
+ ;
+ return i;
+}
+
+/* compute p(x), where p is a permutation of 0..(1<<nbits)-1 */
+/* permute(0)=0. This is intended and useful. */
+static ub4 permute(x, nbits)
+ub4 x; /* input, a value in some range */
+ub4 nbits; /* input, number of bits in range */
+{
+ int i;
+ int mask = ((ub4)1<<nbits)-1; /* all ones */
+ int const2 = 1+nbits/2;
+ int const3 = 1+nbits/3;
+ int const4 = 1+nbits/4;
+ int const5 = 1+nbits/5;
+ for (i=0; i<20; ++i)
+ {
+ x = (x+(x<<const2)) & mask;
+ x = (x^(x>>const3));
+ x = (x+(x<<const4)) & mask;
+ x = (x^(x>>const5));
+ }
+ return x;
+}
+
+/* initialize scramble[] with distinct random values in 0..smax-1 */
+static void scrambleinit(scramble, smax)
+ub4 *scramble; /* hash is a^scramble[tab[b]] */
+ub4 smax; /* scramble values should be in 0..smax-1 */
+{
+ ub4 i;
+
+ /* fill scramble[] with distinct random integers in 0..smax-1 */
+ for (i=0; i<SCRAMBLE_LEN; ++i)
+ {
+ scramble[i] = permute(i, mylog2(smax));
+ }
+}
+
+/*
+ * Check if key1 and key2 are the same.
+ * We already checked (a,b) are the same.
+ */
+static void checkdup(key1, key2, form)
+key *key1;
+key *key2;
+hashform *form;
+{
+ switch(form->hashtype)
+ {
+ case STRING_HT:
+ if ((key1->len_k == key2->len_k) &&
+ !memcmp(key1->name_k, key2->name_k, (size_t)key1->len_k))
+ {
+ fprintf(stderr, "perfect.c: Duplicates keys! %.*s\n",
+ key1->len_k, key1->name_k);
+ exit(SUCCESS);
+ }
+ break;
+ case INT_HT:
+ if (key1->hash_k == key2->hash_k)
+ {
+ fprintf(stderr, "perfect.c: Duplicate keys! %.8lx\n", key1->hash_k);
+ exit(SUCCESS);
+ }
+ break;
+ case AB_HT:
+ fprintf(stderr, "perfect.c: Duplicate keys! %.8lx %.8lx\n",
+ key1->a_k, key1->b_k);
+ exit(SUCCESS);
+ break;
+ default:
+ fprintf(stderr, "perfect.c: Illegal hash type %ld\n", (ub4)form->hashtype);
+ exit(SUCCESS);
+ break;
+ }
+}
+
+
+/*
+ * put keys in tabb according to key->b_k
+ * check if the initial hash might work
+ */
+static int inittab(tabb, blen, keys, form, complete)
+bstuff *tabb; /* output, list of keys with b for (a,b) */
+ub4 blen; /* length of tabb */
+key *keys; /* list of keys already hashed */
+hashform *form; /* user directives */
+int complete; /* TRUE means to complete init despite collisions */
+{
+ int nocollision = TRUE;
+ key *mykey;
+
+ memset((void *)tabb, 0, (size_t)(sizeof(bstuff)*blen));
+
+ /* Two keys with the same (a,b) guarantees a collision */
+ for (mykey=keys; mykey; mykey=mykey->next_k)
+ {
+ key *otherkey;
+
+ for (otherkey=tabb[mykey->b_k].list_b;
+ otherkey;
+ otherkey=otherkey->nextb_k)
+ {
+ if (mykey->a_k == otherkey->a_k)
+ {
+ nocollision = FALSE;
+ checkdup(mykey, otherkey, form);
+ if (!complete)
+ return FALSE;
+ }
+ }
+ ++tabb[mykey->b_k].listlen_b;
+ mykey->nextb_k = tabb[mykey->b_k].list_b;
+ tabb[mykey->b_k].list_b = mykey;
+ }
+
+ /* no two keys have the same (a,b) pair */
+ return nocollision;
+}
+
+
+/* Do the initial hash for normal mode (use lookup and checksum) */
+static void initnorm(keys, alen, blen, smax, salt, final)
+key *keys; /* list of all keys */
+ub4 alen; /* (a,b) has a in 0..alen-1, a power of 2 */
+ub4 blen; /* (a,b) has b in 0..blen-1, a power of 2 */
+ub4 smax; /* maximum range of computable hash values */
+ub4 salt; /* used to initialize the hash function */
+gencode *final; /* output, code for the final hash */
+{
+ key *mykey;
+ if (mylog2(alen)+mylog2(blen) > UB4BITS)
+ {
+ ub4 initlev = salt*0x9e3779b9; /* the golden ratio; an arbitrary value */
+
+ for (mykey=keys; mykey; mykey=mykey->next_k)
+ {
+ ub4 i, state[CHECKSTATE];
+ for (i=0; i<CHECKSTATE; ++i) state[i] = initlev;
+ checksum( mykey->name_k, mykey->len_k, state);
+ mykey->a_k = state[0]&(alen-1);
+ mykey->b_k = state[1]&(blen-1);
+ }
+ final->used = 4;
+ sprintf(final->line[0],
+ " ub4 i,state[CHECKSTATE],rsl;\n");
+ sprintf(final->line[1],
+ " for (i=0; i<CHECKSTATE; ++i) state[i]=0x%lx;\n",initlev);
+ sprintf(final->line[2],
+ " checksum(key, len, state);\n");
+ sprintf(final->line[3],
+ " rsl = ((state[0]&0x%x)^scramble[tab[state[1]&0x%x]]);\n",
+ alen-1, blen-1);
+ }
+ else
+ {
+ ub4 loga = mylog2(alen); /* log based 2 of blen */
+ ub4 initlev = salt*0x9e3779b9; /* the golden ratio; an arbitrary value */
+
+ for (mykey=keys; mykey; mykey=mykey->next_k)
+ {
+ ub4 hash = lookup(mykey->name_k, mykey->len_k, initlev);
+ mykey->a_k = (loga > 0) ? hash>>(UB4BITS-loga) : 0;
+ mykey->b_k = (blen > 1) ? hash&(blen-1) : 0;
+ }
+ final->used = 2;
+ sprintf(final->line[0],
+ " ub4 rsl, val = lookup(key, len, 0x%lx);\n", initlev);
+ if (smax <= 1)
+ {
+ sprintf(final->line[1], " rsl = 0;\n");
+ }
+ else if (mylog2(alen) == 0)
+ {
+ sprintf(final->line[1], " rsl = tab[val&0x%x];\n", blen-1);
+ }
+ else if (blen < USE_SCRAMBLE)
+ {
+ sprintf(final->line[1], " rsl = ((val>>%ld)^tab[val&0x%x]);\n",
+ UB4BITS-mylog2(alen), blen-1);
+ }
+ else
+ {
+ sprintf(final->line[1], " rsl = ((val>>%ld)^scramble[tab[val&0x%x]]);\n",
+ UB4BITS-mylog2(alen), blen-1);
+ }
+ }
+}
+
+
+
+/* Do initial hash for inline mode */
+static void initinl(keys, alen, blen, smax, salt, final)
+key *keys; /* list of all keys */
+ub4 alen; /* (a,b) has a in 0..alen-1, a power of 2 */
+ub4 blen; /* (a,b) has b in 0..blen-1, a power of 2 */
+ub4 smax; /* range of computable hash values */
+ub4 salt; /* used to initialize the hash function */
+gencode *final; /* generated code for final hash */
+{
+ key *mykey;
+ ub4 amask = alen-1;
+ ub4 blog = mylog2(blen);
+ ub4 initval = salt*0x9e3779b9; /* the golden ratio; an arbitrary value */
+
+ /* It's more important to have b uniform than a, so b is the low bits */
+ for (mykey = keys; mykey != (key *)0; mykey = mykey->next_k)
+ {
+ ub4 hash = initval;
+ ub4 i;
+ for (i=0; i<mykey->len_k; ++i)
+ {
+ hash = (mykey->name_k[i] ^ hash) + ((hash<<(UB4BITS-6))+(hash>>6));
+ }
+ mykey->hash_k = hash;
+ mykey->a_k = (alen > 1) ? (hash & amask) : 0;
+ mykey->b_k = (blen > 1) ? (hash >> (UB4BITS-blog)) : 0;
+ }
+ final->used = 1;
+ if (smax <= 1)
+ {
+ sprintf(final->line[0], " ub4 rsl = 0;\n");
+ }
+ else if (blen < USE_SCRAMBLE)
+ {
+ sprintf(final->line[0], " ub4 rsl = ((val & 0x%lx) ^ tab[val >> %ld]);\n",
+ amask, UB4BITS-blog);
+ }
+ else
+ {
+ sprintf(final->line[0], " ub4 rsl = ((val & 0x%lx) ^ scramble[tab[val >> %ld]]);\n",
+ amask, UB4BITS-blog);
+ }
+}
+
+
+/*
+ * Run a hash function on the key to get a and b
+ * Returns:
+ * 0: didn't find distinct (a,b) for all keys
+ * 1: found distinct (a,b) for all keys, put keys in tabb[]
+ * 2: found a perfect hash, no need to do any more work
+ */
+static ub4 initkey(keys, nkeys, tabb, alen, blen, smax, salt, form, final)
+key *keys; /* list of all keys */
+ub4 nkeys; /* total number of keys */
+bstuff *tabb; /* stuff indexed by b */
+ub4 alen; /* (a,b) has a in 0..alen-1, a power of 2 */
+ub4 blen; /* (a,b) has b in 0..blen-1, a power of 2 */
+ub4 smax; /* range of computable hash values */
+ub4 salt; /* used to initialize the hash function */
+hashform *form; /* user directives */
+gencode *final; /* code for final hash */
+{
+ ub4 finished;
+
+ /* Do the initial hash of the keys */
+ switch(form->mode)
+ {
+ case NORMAL_HM:
+ initnorm(keys, alen, blen, smax, salt, final);
+ break;
+ case INLINE_HM:
+ initinl(keys, alen, blen, smax, salt, final);
+ break;
+ case HEX_HM:
+ case DECIMAL_HM:
+ finished = inithex(keys, nkeys, alen, blen, smax, salt, final, form);
+ if (finished) return 2;
+ break;
+ default:
+ fprintf(stderr, "fatal error: illegal mode\n");
+ exit(1);
+ }
+
+ if (nkeys <= 1)
+ {
+ final->used = 1;
+ sprintf(final->line[0], " ub4 rsl = 0;\n");
+ return 2;
+ }
+
+ return inittab(tabb, blen, keys, form, FALSE);
+}
+
+/* Print an error message and exit if there are duplicates */
+static void duplicates(tabb, blen, keys, form)
+bstuff *tabb; /* array of lists of keys with the same b */
+ub4 blen; /* length of tabb, a power of 2 */
+key *keys;
+hashform *form; /* user directives */
+{
+ ub4 i;
+ key *key1;
+ key *key2;
+
+ (void)inittab(tabb, blen, keys, form, TRUE);
+
+ /* for each b, do nested loops through key list looking for duplicates */
+ for (i=0; i<blen; ++i)
+ for (key1=tabb[i].list_b; key1; key1=key1->nextb_k)
+ for (key2=key1->nextb_k; key2; key2=key2->nextb_k)
+ checkdup(key1, key2, form);
+}
+
+
+/* Try to apply an augmenting list */
+static int apply(tabb, tabh, tabq, blen, scramble, tail, rollback)
+bstuff *tabb;
+hstuff *tabh;
+qstuff *tabq;
+ub4 blen;
+ub4 *scramble;
+ub4 tail;
+int rollback; /* FALSE applies augmenting path, TRUE rolls back */
+{
+ ub4 hash;
+ key *mykey;
+ bstuff *pb;
+ ub4 child;
+ ub4 parent;
+ ub4 stabb; /* scramble[tab[b]] */
+
+ /* walk from child to parent */
+ for (child=tail-1; child; child=parent)
+ {
+ parent = tabq[child].parent_q; /* find child's parent */
+ pb = tabq[parent].b_q; /* find parent's list of siblings */
+
+ /* erase old hash values */
+ stabb = scramble[pb->val_b];
+ for (mykey=pb->list_b; mykey; mykey=mykey->nextb_k)
+ {
+ hash = mykey->a_k^stabb;
+ if (mykey == tabh[hash].key_h)
+ { /* erase hash for all of child's siblings */
+ tabh[hash].key_h = (key *)0;
+ }
+ }
+
+ /* change pb->val_b, which will change the hashes of all parent siblings */
+ pb->val_b = (rollback ? tabq[child].oldval_q : tabq[child].newval_q);
+
+ /* set new hash values */
+ stabb = scramble[pb->val_b];
+ for (mykey=pb->list_b; mykey; mykey=mykey->nextb_k)
+ {
+ hash = mykey->a_k^stabb;
+ if (rollback)
+ {
+ if (parent == 0) continue; /* root never had a hash */
+ }
+ else if (tabh[hash].key_h)
+ {
+ /* very rare: roll back any changes */
+ (void *)apply(tabb, tabh, tabq, blen, scramble, tail, TRUE);
+ return FALSE; /* failure, collision */
+ }
+ tabh[hash].key_h = mykey;
+ }
+ }
+ return TRUE;
+}
+
+
+/*
+-------------------------------------------------------------------------------
+augment(): Add item to the mapping.
+
+Construct a spanning tree of *b*s with *item* as root, where each
+parent can have all its hashes changed (by some new val_b) with
+at most one collision, and each child is the b of that collision.
+
+I got this from Tarjan's "Data Structures and Network Algorithms". The
+path from *item* to a *b* that can be remapped with no collision is
+an "augmenting path". Change values of tab[b] along the path so that
+the unmapped key gets mapped and the unused hash value gets used.
+
+Assuming 1 key per b, if m out of n hash values are still unused,
+you should expect the transitive closure to cover n/m nodes before
+an unused node is found. Sum(i=1..n)(n/i) is about nlogn, so expect
+this approach to take about nlogn time to map all single-key b's.
+-------------------------------------------------------------------------------
+*/
+static int augment(tabb, tabh, tabq, blen, scramble, smax, item, nkeys,
+ highwater, form)
+bstuff *tabb; /* stuff indexed by b */
+hstuff *tabh; /* which key is associated with which hash, indexed by hash */
+qstuff *tabq; /* queue of *b* values, this is the spanning tree */
+ub4 blen; /* length of tabb */
+ub4 *scramble; /* final hash is a^scramble[tab[b]] */
+ub4 smax; /* highest value in scramble */
+bstuff *item; /* &tabb[b] for the b to be mapped */
+ub4 nkeys; /* final hash must be in 0..nkeys-1 */
+ub4 highwater; /* a value higher than any now in tabb[].water_b */
+hashform *form; /* TRUE if we should do a minimal perfect hash */
+{
+ ub4 q; /* current position walking through the queue */
+ ub4 tail; /* tail of the queue. 0 is the head of the queue. */
+ ub4 limit=((blen < USE_SCRAMBLE) ? smax : UB1MAXVAL+1);
+ ub4 highhash = ((form->perfect == MINIMAL_HP) ? nkeys : smax);
+ int trans = (form->speed == SLOW_HS || form->perfect == MINIMAL_HP);
+
+ /* initialize the root of the spanning tree */
+ tabq[0].b_q = item;
+ tail = 1;
+
+ /* construct the spanning tree by walking the queue, add children to tail */
+ for (q=0; q<tail; ++q)
+ {
+ bstuff *myb = tabq[q].b_q; /* the b for this node */
+ ub4 i; /* possible value for myb->val_b */
+
+ if (!trans && (q == 1))
+ break; /* don't do transitive closure */
+
+ for (i=0; i<limit; ++i)
+ {
+ bstuff *childb = (bstuff *)0; /* the b that this i maps to */
+ key *mykey; /* for walking through myb's keys */
+
+ for (mykey = myb->list_b; mykey; mykey=mykey->nextb_k)
+ {
+ key *childkey;
+ ub4 hash = mykey->a_k^scramble[i];
+
+ if (hash >= highhash) break; /* out of bounds */
+ childkey = tabh[hash].key_h;
+
+ if (childkey)
+ {
+ bstuff *hitb = &tabb[childkey->b_k];
+
+ if (childb)
+ {
+ if (childb != hitb) break; /* hit at most one child b */
+ }
+ else
+ {
+ childb = hitb; /* remember this as childb */
+ if (childb->water_b == highwater) break; /* already explored */
+ }
+ }
+ }
+ if (mykey) continue; /* myb with i has multiple collisions */
+
+ /* add childb to the queue of reachable things */
+ if (childb) childb->water_b = highwater;
+ tabq[tail].b_q = childb;
+ tabq[tail].newval_q = i; /* how to make parent (myb) use this hash */
+ tabq[tail].oldval_q = myb->val_b; /* need this for rollback */
+ tabq[tail].parent_q = q;
+ ++tail;
+
+ if (!childb)
+ { /* found an *i* with no collisions? */
+ /* try to apply the augmenting path */
+ if (apply(tabb, tabh, tabq, blen, scramble, tail, FALSE))
+ return TRUE; /* success, item was added to the perfect hash */
+
+ --tail; /* don't know how to handle such a child! */
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+/* find a mapping that makes this a perfect hash */
+static int perfect(tabb, tabh, tabq, blen, smax, scramble, nkeys, form)
+bstuff *tabb;
+hstuff *tabh;
+qstuff *tabq;
+ub4 blen;
+ub4 smax;
+ub4 *scramble;
+ub4 nkeys;
+hashform *form;
+{
+ ub4 maxkeys; /* maximum number of keys for any b */
+ ub4 i, j;
+
+ /* clear any state from previous attempts */
+ memset((void *)tabh, 0,
+ (size_t)(sizeof(hstuff)*
+ ((form->perfect == MINIMAL_HP) ? nkeys : smax)));
+ memset((void *)tabq, 0, (size_t)(sizeof(qstuff)*(blen+1)));
+
+ for (maxkeys=0,i=0; i<blen; ++i)
+ if (tabb[i].listlen_b > maxkeys)
+ maxkeys = tabb[i].listlen_b;
+
+ /* In descending order by number of keys, map all *b*s */
+ for (j=maxkeys; j>0; --j)
+ for (i=0; i<blen; ++i)
+ if (tabb[i].listlen_b == j)
+ if (!augment(tabb, tabh, tabq, blen, scramble, smax, &tabb[i], nkeys,
+ i+1, form))
+ {
+ printf("fail to map group of size %ld for tab size %ld\n", j, blen);
+ return FALSE;
+ }
+
+ /* Success! We found a perfect hash of all keys into 0..nkeys-1. */
+ return TRUE;
+}
+
+
+/*
+ * Simple case: user gave (a,b). No more mixing, no guessing alen or blen.
+ * This assumes a,b reside in (key->a_k, key->b_k), and final->form == AB_HK.
+ */
+static void hash_ab(tabb, alen, blen, salt, final,
+ scramble, smax, keys, nkeys, form)
+bstuff **tabb; /* output, tab[] of the perfect hash, length *blen */
+ub4 *alen; /* output, 0..alen-1 is range for a of (a,b) */
+ub4 *blen; /* output, 0..blen-1 is range for b of (a,b) */
+ub4 *salt; /* output, initializes initial hash */
+gencode *final; /* code for final hash */
+ub4 *scramble; /* input, hash = a^scramble[tab[b]] */
+ub4 *smax; /* input, scramble[i] in 0..smax-1 */
+key *keys; /* input, keys to hash */
+ub4 nkeys; /* input, number of keys being hashed */
+hashform *form; /* user directives */
+{
+ hstuff *tabh;
+ qstuff *tabq;
+ key *mykey;
+ ub4 i;
+ int used_tab;
+
+ /* initially make smax the first power of two bigger than nkeys */
+ *smax = ((ub4)1<<mylog2(nkeys));
+ scrambleinit(scramble, *smax);
+
+ /* set *alen and *blen based on max A and B from user */
+ *alen = 1;
+ *blen = 1;
+ for (mykey = keys; mykey != (key *)0; mykey = mykey->next_k)
+ {
+ while (*alen <= mykey->a_k) *alen *= 2;
+ while (*blen <= mykey->b_k) *blen *= 2;
+ }
+ if (*alen > 2**smax)
+ {
+ fprintf(stderr,
+ "perfect.c: Can't deal with (A,B) having A bigger than twice \n");
+ fprintf(stderr,
+ " the smallest power of two greater or equal to any legal hash.\n");
+ exit(SUCCESS);
+ }
+
+ /* allocate working memory */
+ *tabb = (bstuff *)malloc((size_t)(sizeof(bstuff)*(*blen)));
+ tabq = (qstuff *)remalloc(sizeof(qstuff)*(*blen+1), "perfect.c, tabq");
+ tabh = (hstuff *)remalloc(sizeof(hstuff)*(form->perfect == MINIMAL_HP ?
+ nkeys : *smax),
+ "perfect.c, tabh");
+
+ /* check that (a,b) are distinct and put them in tabb indexed by b */
+ (void)inittab(*tabb, *blen, keys, form, FALSE);
+
+ /* try with smax */
+ if (!perfect(*tabb, tabh, tabq, *blen, *smax, scramble, nkeys, form))
+ {
+ if (form->perfect == MINIMAL_HP)
+ {
+ printf("fatal error: Cannot find perfect hash for user (A,B) pairs\n");
+ exit(SUCCESS);
+ }
+ else
+ {
+ /* try with 2*smax */
+ free((void *)tabh);
+ *smax = *smax * 2;
+ scrambleinit(scramble, *smax);
+ tabh = (hstuff *)remalloc(sizeof(hstuff)*(form->perfect == MINIMAL_HP ?
+ nkeys : *smax),
+ "perfect.c, tabh");
+ if (!perfect(*tabb, tabh, tabq, *blen, *smax, scramble, nkeys, form))
+ {
+ printf("fatal error: Cannot find perfect hash for user (A,B) pairs\n");
+ exit(SUCCESS);
+ }
+ }
+ }
+
+ /* check if tab[] was really needed */
+ for (i=0; i<*blen; ++i)
+ {
+ if ((*tabb)[i].val_b != 0) break; /* assumes permute(0) == 0 */
+ }
+ used_tab = (i < *blen);
+
+ /* write the code for the perfect hash */
+ *salt = 1;
+ final->used = 1;
+ if (!used_tab)
+ {
+ sprintf(final->line[0], " ub4 rsl = a;\n");
+ }
+ else if (*blen < USE_SCRAMBLE)
+ {
+ sprintf(final->line[0], " ub4 rsl = (a ^ tab[b]);\n");
+ }
+ else
+ {
+ sprintf(final->line[0], " ub4 rsl = (a ^ scramble[tab[b]]);\n");
+ }
+
+ printf("success, found a perfect hash\n");
+
+ free((void *)tabq);
+ free((void *)tabh);
+}
+
+
+/* guess initial values for alen and blen */
+static void initalen(alen, blen, smax, nkeys, form)
+ub4 *alen; /* output, initial alen */
+ub4 *blen; /* output, initial blen */
+ub4 *smax; /* input, power of two greater or equal to max hash value */
+ub4 nkeys; /* number of keys being hashed */
+hashform *form; /* user directives */
+{
+ /*
+ * Find initial *alen, *blen
+ * Initial alen and blen values were found empirically. Some factors:
+ *
+ * If smax<256 there is no scramble, so tab[b] needs to cover 0..smax-1.
+ *
+ * alen and blen must be powers of 2 because the values in 0..alen-1 and
+ * 0..blen-1 are produced by applying a bitmask to the initial hash function.
+ *
+ * alen must be less than smax, in fact less than nkeys, because otherwise
+ * there would often be no i such that a^scramble[i] is in 0..nkeys-1 for
+ * all the *a*s associated with a given *b*, so there would be no legal
+ * value to assign to tab[b]. This only matters when we're doing a minimal
+ * perfect hash.
+ *
+ * It takes around 800 trials to find distinct (a,b) with nkey=smax*(5/8)
+ * and alen*blen = smax*smax/32.
+ *
+ * Values of blen less than smax/4 never work, and smax/2 always works.
+ *
+ * We want blen as small as possible because it is the number of bytes in
+ * the huge array we must create for the perfect hash.
+ *
+ * When nkey <= smax*(5/8), blen=smax/4 works much more often with
+ * alen=smax/8 than with alen=smax/4. Above smax*(5/8), blen=smax/4
+ * doesn't seem to care whether alen=smax/8 or alen=smax/4. I think it
+ * has something to do with 5/8 = 1/8 * 5. For example examine 80000,
+ * 85000, and 90000 keys with different values of alen. This only matters
+ * if we're doing a minimal perfect hash.
+ *
+ * When alen*blen <= 1<<UB4BITS, the initial hash must produce one integer.
+ * Bigger than that it must produce two integers, which increases the
+ * cost of the hash per character hashed.
+ */
+ if (form->perfect == NORMAL_HP)
+ {
+ if ((form->speed == FAST_HS) && (nkeys > *smax*0.8))
+ {
+ *smax = *smax * 2;
+ }
+
+ *alen = ((form->hashtype==INT_HT) && *smax>131072) ?
+ ((ub4)1<<(UB4BITS-mylog2(*blen))) : /* distinct keys => distinct (A,B) */
+ *smax; /* no reason to restrict alen to smax/2 */
+ if ((form->hashtype == INT_HT) && *smax < 32)
+ *blen = *smax; /* go for function speed not space */
+ else if (*smax/4 <= (1<<14))
+ *blen = ((nkeys <= *smax*0.56) ? *smax/32 :
+ (nkeys <= *smax*0.74) ? *smax/16 : *smax/8);
+ else
+ *blen = ((nkeys <= *smax*0.6) ? *smax/16 :
+ (nkeys <= *smax*0.8) ? *smax/8 : *smax/4);
+
+ if ((form->speed == FAST_HS) && (*blen < *smax/8))
+ *blen = *smax/8;
+
+ if (*alen < 1) *alen = 1;
+ if (*blen < 1) *blen = 1;
+ }
+ else
+ {
+ switch(mylog2(*smax))
+ {
+ case 0:
+ *alen = 1;
+ *blen = 1;
+ case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
+ *alen = (form->perfect == NORMAL_HP) ? *smax : *smax/2;
+ *blen = *smax/2;
+ break;
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ case 17:
+ if (form->speed == FAST_HS)
+ {
+ *alen = *smax/2;
+ *blen = *smax/4;
+ }
+ else if (*smax/4 < USE_SCRAMBLE)
+ {
+ *alen = ((nkeys <= *smax*0.52) ? *smax/8 : *smax/4);
+ *blen = ((nkeys <= *smax*0.52) ? *smax/8 : *smax/4);
+ }
+ else
+ {
+ *alen = ((nkeys <= *smax*(5.0/8.0)) ? *smax/8 :
+ (nkeys <= *smax*(3.0/4.0)) ? *smax/4 : *smax/2);
+ *blen = *smax/4; /* always give the small size a shot */
+ }
+ break;
+ case 18:
+ if (form->speed == FAST_HS)
+ {
+ *alen = *smax/2;
+ *blen = *smax/2;
+ }
+ else
+ {
+ *alen = *smax/8; /* never require the multiword hash */
+ *blen = (nkeys <= *smax*(5.0/8.0)) ? *smax/4 : *smax/2;
+ }
+ break;
+ case 19:
+ case 20:
+ *alen = (nkeys <= *smax*(5.0/8.0)) ? *smax/8 : *smax/2;
+ *blen = (nkeys <= *smax*(5.0/8.0)) ? *smax/4 : *smax/2;
+ break;
+ default:
+ *alen = *smax/2; /* just find a hash as quick as possible */
+ *blen = *smax/2; /* we'll be thrashing virtual memory at this size */
+ break;
+ }
+ }
+}
+
+/*
+** Try to find a perfect hash function.
+** Return the successful initializer for the initial hash.
+** Return 0 if no perfect hash could be found.
+*/
+void findhash(tabb, alen, blen, salt, final,
+ scramble, smax, keys, nkeys, form)
+bstuff **tabb; /* output, tab[] of the perfect hash, length *blen */
+ub4 *alen; /* output, 0..alen-1 is range for a of (a,b) */
+ub4 *blen; /* output, 0..blen-1 is range for b of (a,b) */
+ub4 *salt; /* output, initializes initial hash */
+gencode *final; /* code for final hash */
+ub4 *scramble; /* input, hash = a^scramble[tab[b]] */
+ub4 *smax; /* input, scramble[i] in 0..smax-1 */
+key *keys; /* input, keys to hash */
+ub4 nkeys; /* input, number of keys being hashed */
+hashform *form; /* user directives */
+{
+ ub4 bad_initkey; /* how many times did initkey fail? */
+ ub4 bad_perfect; /* how many times did perfect fail? */
+ ub4 trysalt; /* trial initializer for initial hash */
+ ub4 maxalen;
+ hstuff *tabh; /* table of keys indexed by hash value */
+ qstuff *tabq; /* table of stuff indexed by queue value, used by augment */
+
+ /* The case of (A,B) supplied by the user is a special case */
+ if (form->hashtype == AB_HT)
+ {
+ hash_ab(tabb, alen, blen, salt, final,
+ scramble, smax, keys, nkeys, form);
+ return;
+ }
+
+ /* guess initial values for smax, alen and blen */
+ *smax = ((ub4)1<<mylog2(nkeys));
+ initalen(alen, blen, smax, nkeys, form);
+
+ scrambleinit(scramble, *smax);
+
+ maxalen = (form->perfect == MINIMAL_HP) ? *smax/2 : *smax;
+
+ /* allocate working memory */
+ *tabb = (bstuff *)remalloc((size_t)(sizeof(bstuff)*(*blen)),
+ "perfect.c, tabb");
+ tabq = (qstuff *)remalloc(sizeof(qstuff)*(*blen+1), "perfect.c, tabq");
+ tabh = (hstuff *)remalloc(sizeof(hstuff)*(form->perfect == MINIMAL_HP ?
+ nkeys : *smax),
+ "perfect.c, tabh");
+
+ /* Actually find the perfect hash */
+ *salt = 0;
+ bad_initkey = 0;
+ bad_perfect = 0;
+ for (trysalt=1; ; ++trysalt)
+ {
+ ub4 rslinit;
+ /* Try to find distinct (A,B) for all keys */
+
+ rslinit = initkey(keys, nkeys, *tabb, *alen, *blen, *smax, trysalt,
+ form, final);
+
+ if (rslinit == 2)
+ { /* initkey actually found a perfect hash, not just distinct (a,b) */
+ *salt = 1;
+ *blen = 0;
+ break;
+ }
+ else if (rslinit == 0)
+ {
+ /* didn't find distinct (a,b) */
+ if (++bad_initkey >= RETRY_INITKEY)
+ {
+ /* Try to put more bits in (A,B) to make distinct (A,B) more likely */
+ if (*alen < maxalen)
+ {
+ *alen *= 2;
+ }
+ else if (*blen < *smax)
+ {
+ *blen *= 2;
+ free(tabq);
+ free(*tabb);
+ *tabb = (bstuff *)malloc((size_t)(sizeof(bstuff)*(*blen)));
+ tabq = (qstuff *)malloc((size_t)(sizeof(qstuff)*(*blen+1)));
+ }
+ else
+ {
+ duplicates(*tabb, *blen, keys, form); /* check for duplicates */
+ printf("fatal error: Cannot perfect hash: cannot find distinct (A,B)\n");
+ exit(SUCCESS);
+ }
+ bad_initkey = 0;
+ bad_perfect = 0;
+ }
+ continue; /* two keys have same (a,b) pair */
+ }
+
+ printf("found distinct (A,B) on attempt %ld\n", trysalt);
+
+ /* Given distinct (A,B) for all keys, build a perfect hash */
+ if (!perfect(*tabb, tabh, tabq, *blen, *smax, scramble, nkeys, form))
+ {
+ if ((form->hashtype != INT_HT && ++bad_perfect >= RETRY_PERFECT) ||
+ (form->hashtype == INT_HT && ++bad_perfect >= RETRY_HEX))
+ {
+ if (*blen < *smax)
+ {
+ *blen *= 2;
+ free(*tabb);
+ free(tabq);
+ *tabb = (bstuff *)malloc((size_t)(sizeof(bstuff)*(*blen)));
+ tabq = (qstuff *)malloc((size_t)(sizeof(qstuff)*(*blen+1)));
+ --trysalt; /* we know this salt got distinct (A,B) */
+ }
+ else
+ {
+ printf("fatal error: Cannot perfect hash: cannot build tab[]\n");
+ exit(SUCCESS);
+ }
+ bad_perfect = 0;
+ }
+ continue;
+ }
+
+ *salt = trysalt;
+ break;
+ }
+
+ printf("built perfect hash table of size %ld\n", *blen);
+
+ /* free working memory */
+ free((void *)tabh);
+ free((void *)tabq);
+}
+
+/*
+------------------------------------------------------------------------------
+Input/output type routines
+------------------------------------------------------------------------------
+*/
+
+/* get the list of keys */
+static void getkeys(keys, nkeys, textroot, keyroot, form)
+key **keys; /* list of all keys */
+ub4 *nkeys; /* number of keys */
+reroot *textroot; /* get space to store key text */
+reroot *keyroot; /* get space for keys */
+hashform *form; /* user directives */
+{
+ key *mykey;
+ char *mytext;
+ mytext = (char *)renew(textroot);
+ *keys = 0;
+ *nkeys = 0;
+ while (fgets(mytext, MAXKEYLEN, stdin))
+ {
+ mykey = (key *)renew(keyroot);
+ if (form->mode == AB_HM)
+ {
+ sscanf(mytext, "%lx %lx ", &mykey->a_k, &mykey->b_k);
+ }
+ else if (form->mode == ABDEC_HM)
+ {
+ sscanf(mytext, "%ld %ld ", &mykey->a_k, &mykey->b_k);
+ }
+ else if (form->mode == HEX_HM)
+ {
+ sscanf(mytext, "%lx ", &mykey->hash_k);
+ }
+ else if (form->mode == DECIMAL_HM)
+ {
+ sscanf(mytext, "%ld ", &mykey->hash_k);
+ }
+ else
+ {
+ mykey->name_k = (ub1 *)mytext;
+ mytext = (char *)renew(textroot);
+ mykey->len_k = (ub4)(strlen((char *)mykey->name_k)-1);
+ }
+ mykey->next_k = *keys;
+ *keys = mykey;
+ ++*nkeys;
+ }
+ redel(textroot, mytext);
+}
+
+/* make the .h file */
+static void make_h(blen, smax, nkeys, salt)
+ub4 blen;
+ub4 smax;
+ub4 nkeys;
+ub4 salt;
+{
+ FILE *f;
+ f = fopen("phash.h", "w");
+ fprintf(f, "/* Perfect hash definitions */\n");
+ fprintf(f, "#ifndef STANDARD\n");
+ fprintf(f, "#include \"standard.h\"\n");
+ fprintf(f, "#endif /* STANDARD */\n");
+ fprintf(f, "#ifndef PHASH\n");
+ fprintf(f, "#define PHASH\n");
+ fprintf(f, "\n");
+ if (blen > 0)
+ {
+ if (smax <= UB1MAXVAL+1 || blen >= USE_SCRAMBLE)
+ fprintf(f, "extern ub1 tab[];\n");
+ else
+ {
+ fprintf(f, "extern ub2 tab[];\n");
+ if (blen >= USE_SCRAMBLE)
+ {
+ if (smax <= UB2MAXVAL+1)
+ fprintf(f, "extern ub2 scramble[];\n");
+ else
+ fprintf(f, "extern ub4 scramble[];\n");
+ }
+ }
+ fprintf(f, "#define PHASHLEN 0x%lx /* length of hash mapping table */\n",
+ blen);
+ }
+ fprintf(f, "#define PHASHNKEYS %ld /* How many keys were hashed */\n",
+ nkeys);
+ fprintf(f, "#define PHASHRANGE %ld /* Range any input might map to */\n",
+ smax);
+ fprintf(f, "#define PHASHSALT 0x%.8lx /* internal, initialize normal hash */\n",
+ salt*0x9e3779b9);
+ fprintf(f, "\n");
+ fprintf(f, "ub4 phash();\n");
+ fprintf(f, "\n");
+ fprintf(f, "#endif /* PHASH */\n");
+ fprintf(f, "\n");
+ fclose(f);
+}
+
+/* make the .c file */
+static void make_c(tab, smax, blen, scramble, final, form)
+bstuff *tab; /* table indexed by b */
+ub4 smax; /* range of scramble[] */
+ub4 blen; /* b in 0..blen-1, power of 2 */
+ub4 *scramble; /* used in final hash */
+gencode *final; /* code for the final hash */
+hashform *form; /* user directives */
+{
+ ub4 i;
+ FILE *f;
+ f = fopen("phash.c", "w");
+ fprintf(f, "/* table for the mapping for the perfect hash */\n");
+ fprintf(f, "#ifndef STANDARD\n");
+ fprintf(f, "#include \"standard.h\"\n");
+ fprintf(f, "#endif /* STANDARD */\n");
+ fprintf(f, "#ifndef PHASH\n");
+ fprintf(f, "#include \"phash.h\"\n");
+ fprintf(f, "#endif /* PHASH */\n");
+ fprintf(f, "#ifndef LOOKUPA\n");
+ fprintf(f, "#include \"lookupa.h\"\n");
+ fprintf(f, "#endif /* LOOKUPA */\n");
+ fprintf(f, "\n");
+ if (blen >= USE_SCRAMBLE)
+ {
+ fprintf(f, "/* A way to make the 1-byte values in tab bigger */\n");
+ if (smax > UB2MAXVAL+1)
+ {
+ fprintf(f, "ub4 scramble[] = {\n");
+ for (i=0; i<=UB1MAXVAL; i+=4)
+ fprintf(f, "0x%.8lx, 0x%.8lx, 0x%.8lx, 0x%.8lx,\n",
+ scramble[i+0], scramble[i+1], scramble[i+2], scramble[i+3]);
+ }
+ else
+ {
+ fprintf(f, "ub2 scramble[] = {\n");
+ for (i=0; i<=UB1MAXVAL; i+=8)
+ fprintf(f,
+"0x%.4lx, 0x%.4lx, 0x%.4lx, 0x%.4lx, 0x%.4lx, 0x%.4lx, 0x%.4lx, 0x%.4lx,\n",
+ scramble[i+0], scramble[i+1], scramble[i+2], scramble[i+3],
+ scramble[i+4], scramble[i+5], scramble[i+6], scramble[i+7]);
+ }
+ fprintf(f, "};\n");
+ fprintf(f, "\n");
+ }
+ if (blen > 0)
+ {
+ fprintf(f, "/* small adjustments to _a_ to make values distinct */\n");
+
+ if (smax <= UB1MAXVAL+1 || blen >= USE_SCRAMBLE)
+ fprintf(f, "ub1 tab[] = {\n");
+ else
+ fprintf(f, "ub2 tab[] = {\n");
+
+ if (blen < 16)
+ {
+ for (i=0; i<blen; ++i) fprintf(f, "%3d,", scramble[tab[i].val_b]);
+ }
+ else if (blen <= 1024)
+ {
+ for (i=0; i<blen; i+=16)
+ fprintf(f, "%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,\n",
+ scramble[tab[i+0].val_b], scramble[tab[i+1].val_b],
+ scramble[tab[i+2].val_b], scramble[tab[i+3].val_b],
+ scramble[tab[i+4].val_b], scramble[tab[i+5].val_b],
+ scramble[tab[i+6].val_b], scramble[tab[i+7].val_b],
+ scramble[tab[i+8].val_b], scramble[tab[i+9].val_b],
+ scramble[tab[i+10].val_b], scramble[tab[i+11].val_b],
+ scramble[tab[i+12].val_b], scramble[tab[i+13].val_b],
+ scramble[tab[i+14].val_b], scramble[tab[i+15].val_b]);
+ }
+ else if (blen < USE_SCRAMBLE)
+ {
+ for (i=0; i<blen; i+=8)
+ fprintf(f, "%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,\n",
+ scramble[tab[i+0].val_b], scramble[tab[i+1].val_b],
+ scramble[tab[i+2].val_b], scramble[tab[i+3].val_b],
+ scramble[tab[i+4].val_b], scramble[tab[i+5].val_b],
+ scramble[tab[i+6].val_b], scramble[tab[i+7].val_b]);
+ }
+ else
+ {
+ for (i=0; i<blen; i+=16)
+ fprintf(f, "%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,\n",
+ tab[i+0].val_b, tab[i+1].val_b,
+ tab[i+2].val_b, tab[i+3].val_b,
+ tab[i+4].val_b, tab[i+5].val_b,
+ tab[i+6].val_b, tab[i+7].val_b,
+ tab[i+8].val_b, tab[i+9].val_b,
+ tab[i+10].val_b, tab[i+11].val_b,
+ tab[i+12].val_b, tab[i+13].val_b,
+ tab[i+14].val_b, tab[i+15].val_b);
+ }
+ fprintf(f, "};\n");
+ fprintf(f, "\n");
+ }
+ fprintf(f, "/* The hash function */\n");
+ switch(form->mode)
+ {
+ case NORMAL_HM:
+ fprintf(f, "ub4 phash(key, len)\n");
+ fprintf(f, "char *key;\n");
+ fprintf(f, "int len;\n");
+ break;
+ case INLINE_HM:
+ case HEX_HM:
+ case DECIMAL_HM:
+ fprintf(f, "ub4 phash(val)\n");
+ fprintf(f, "ub4 val;\n");
+ break;
+ case AB_HM:
+ case ABDEC_HM:
+ fprintf(f, "ub4 phash(a,b)\n");
+ fprintf(f, "ub4 a;\n");
+ fprintf(f, "ub4 b;\n");
+ break;
+ }
+ fprintf(f, "{\n");
+ for (i=0; i<final->used; ++i)
+ fprintf(f, final->line[i]);
+ fprintf(f, " return rsl;\n");
+ fprintf(f, "}\n");
+ fprintf(f, "\n");
+ fclose(f);
+}
+
+/*
+------------------------------------------------------------------------------
+Read in the keys, find the hash, and write the .c and .h files
+------------------------------------------------------------------------------
+*/
+static void driver(form)
+hashform *form; /* user directives */
+{
+ ub4 nkeys; /* number of keys */
+ key *keys; /* head of list of keys */
+ bstuff *tab; /* table indexed by b */
+ ub4 smax; /* scramble[] values in 0..smax-1, a power of 2 */
+ ub4 alen; /* a in 0..alen-1, a power of 2 */
+ ub4 blen; /* b in 0..blen-1, a power of 2 */
+ ub4 salt; /* a parameter to the hash function */
+ reroot *textroot; /* MAXKEYLEN-character text lines */
+ reroot *keyroot; /* source of keys */
+ gencode final; /* code for final hash */
+ ub4 i;
+ ub4 scramble[SCRAMBLE_LEN]; /* used in final hash function */
+ char buf[10][80]; /* buffer for generated code */
+ char *buf2[10]; /* also for generated code */
+
+ /* set up memory sources */
+ textroot = remkroot((size_t)MAXKEYLEN);
+ keyroot = remkroot(sizeof(key));
+
+ /* set up code for final hash */
+ final.line = buf2;
+ final.used = 0;
+ final.len = 10;
+ for (i=0; i<10; ++i) final.line[i] = buf[i];
+
+ /* read in the list of keywords */
+ getkeys(&keys, &nkeys, textroot, keyroot, form);
+ printf("Read in %ld keys\n",nkeys);
+
+ /* find the hash */
+ findhash(&tab, &alen, &blen, &salt, &final,
+ scramble, &smax, keys, nkeys, form);
+
+ /* generate the phash.h file */
+ make_h(blen, smax, nkeys, salt);
+ printf("Wrote phash.h\n");
+
+ /* generate the phash.c file */
+ make_c(tab, smax, blen, scramble, &final, form);
+ printf("Wrote phash.c\n");
+
+ /* clean up memory sources */
+ refree(textroot);
+ refree(keyroot);
+ free((void *)tab);
+ printf("Cleaned up\n");
+}
+
+
+/* Describe how to use this utility */
+static void usage_error()
+{
+ printf("Usage: perfect [-{NnIiHhDdAaBb}{MmPp}{FfSs}] < key.txt \n");
+ printf("The input is a list of keys, one key per line.\n");
+ printf("Only one of NnIiHhDdAa and one of MmPp may be specified.\n");
+ printf(" N,n: normal mode, key is any string string (default).\n");
+ printf(" I,i: initial hash for ASCII char strings.\n");
+ printf("The initial hash must be\n");
+ printf(" hash = PHASHSALT;\n");
+ printf(" for (i=0; i<keylength; ++i) {\n");
+ printf(" hash = (hash ^ key[i]) + ((hash<<26)+(hash>>6));\n");
+ printf(" }\n");
+ printf("Note that this can be inlined in any user loop that walks\n");
+ printf("through the key anyways, eliminating the loop overhead.\n");
+ printf(" H,h: Keys are 4-byte integers in hex in this format:\n");
+ printf("ffffffff\n");
+ printf("This is good for optimizing switch statement compilation.\n");
+ printf(" D,d: Same as H,h, except in decimal not hexidecimal\n");
+ printf(" A,a: An (A,B) pair is supplied in hex in this format:\n");
+ printf("aaa bbb\n");
+ printf(" B,b: Same as A,a, except in decimal not hexidecimal\n");
+ printf("This mode does nothing but find the values of tab[].\n");
+ printf("*A* must be less than the total number of keys.\n");
+ printf(" M,m: Minimal perfect hash. Hash will be in 0..nkeys-1 (default)\n");
+ printf(" P,p: Perfect hash. Hash will be in 0..n-1, where n >= nkeys\n");
+ printf("and n is a power of 2. Will probably use a smaller tab[].");
+ printf(" F,f: Fast mode. Generate the perfect hash fast.\n");
+ printf(" S,s: Slow mode. Spend time finding a good perfect hash.\n");
+
+ exit(SUCCESS);
+}
+
+
+/* Interpret arguments and call the driver */
+/* See usage_error for the expected arguments */
+int main(argc, argv)
+int argc;
+char **argv;
+{
+ int mode_given = FALSE;
+ int minimal_given = FALSE;
+ int speed_given = FALSE;
+ hashform form;
+ char *c;
+
+ /* default behavior */
+ form.mode = NORMAL_HM;
+ form.hashtype = STRING_HT;
+ form.perfect = MINIMAL_HP;
+ form.speed = SLOW_HS;
+
+ /* let the user override the default behavior */
+ switch (argc)
+ {
+ case 1:
+ break;
+ case 2:
+ if (argv[1][0] != '-')
+ {
+ usage_error();
+ break;
+ }
+ for (c = &argv[1][1]; *c != '\0'; ++c) switch(*c)
+ {
+ case 'n': case 'N':
+ case 'i': case 'I':
+ case 'h': case 'H':
+ case 'd': case 'D':
+ case 'a': case 'A':
+ case 'b': case 'B':
+ if (mode_given == TRUE)
+ usage_error();
+ switch(*c)
+ {
+ case 'n': case 'N':
+ form.mode = NORMAL_HM; form.hashtype = STRING_HT; break;
+ case 'i': case 'I':
+ form.mode = INLINE_HM; form.hashtype = STRING_HT; break;
+ case 'h': case 'H':
+ form.mode = HEX_HM; form.hashtype = INT_HT; break;
+ case 'd': case 'D':
+ form.mode = DECIMAL_HM; form.hashtype = INT_HT; break;
+ case 'a': case 'A':
+ form.mode = AB_HM; form.hashtype = AB_HT; break;
+ case 'b': case 'B':
+ form.mode = ABDEC_HM; form.hashtype = AB_HT; break;
+ }
+ mode_given = TRUE;
+ break;
+ case 'm': case 'M':
+ case 'p': case 'P':
+ if (minimal_given == TRUE)
+ usage_error();
+ switch(*c)
+ {
+ case 'p': case 'P':
+ form.perfect = NORMAL_HP; break;
+ case 'm': case 'M':
+ form.perfect = MINIMAL_HP; break;
+ }
+ minimal_given = TRUE;
+ break;
+ case 'f': case 'F':
+ case 's': case 'S':
+ if (speed_given == TRUE)
+ usage_error();
+ switch(*c)
+ {
+ case 'f': case 'F':
+ form.speed = FAST_HS; break;
+ case 's': case 'S':
+ form.speed = SLOW_HS; break;
+ }
+ speed_given = TRUE;
+ break;
+ default:
+ usage_error();
+ }
+ break;
+ default:
+ usage_error();
+ }
+
+ /* Generate the [minimal] perfect hash */
+ driver(&form);
+
+ return SUCCESS;
+}
diff --git a/tools/codegen/core/perfect/perfect.h b/tools/codegen/core/perfect/perfect.h
new file mode 100644
index 0000000000..fed5296bb7
--- /dev/null
+++ b/tools/codegen/core/perfect/perfect.h
@@ -0,0 +1,132 @@
+/*
+------------------------------------------------------------------------------
+perfect.h: code to generate code for a hash for perfect hashing.
+(c) Bob Jenkins, September 1996
+You may use this code in any way you wish, and it is free. No warranty.
+I hereby place this in the public domain.
+Source is http://burtleburtle.net/bob/c/perfect.h
+------------------------------------------------------------------------------
+*/
+
+#ifndef STANDARD
+#include "standard.h"
+#endif
+
+#ifndef PERFECT
+#define PERFECT
+
+#define MAXKEYLEN 30 /* maximum length of a key */
+#define USE_SCRAMBLE 4096 /* use scramble if blen >= USE_SCRAMBLE */
+#define SCRAMBLE_LEN ((ub4)1<<16) /* length of *scramble* */
+#define RETRY_INITKEY 2048 /* number of times to try to find distinct (a,b) */
+#define RETRY_PERFECT 1 /* number of times to try to make a perfect hash */
+#define RETRY_HEX 200 /* RETRY_PERFECT when hex keys given */
+
+/* the generated code for the final hash, assumes initial hash is done */
+struct gencode
+{
+ char **line; /* array of text lines, 80 bytes apiece */
+ /*
+ * The code placed here must declare "ub4 rsl"
+ * and assign it the value of the perfect hash using the function inputs.
+ * Later code will be tacked on which returns rsl or manipulates it according
+ * to the user directives.
+ *
+ * This code is at the top of the routine; it may and must declare any
+ * local variables it needs.
+ *
+ * Each way of filling in **line should be given a comment that is a unique
+ * tag. A testcase named with that tag should also be found which tests
+ * the generated code.
+ */
+ ub4 len; /* number of lines available for final hash */
+ ub4 used; /* number of lines used by final hash */
+
+ ub4 lowbit; /* for HEX, lowest interesting bit */
+ ub4 highbit; /* for HEX, highest interesting bit */
+ ub4 diffbits; /* bits which differ for some key */
+ ub4 i,j,k,l,m,n,o; /* state machine used in hexn() */
+};
+typedef struct gencode gencode;
+
+/* user directives: perfect hash? minimal perfect hash? input is an int? */
+struct hashform
+{
+ enum {
+ NORMAL_HM, /* key is a string */
+ INLINE_HM, /* user will do initial hash, we must choose salt for them */
+ HEX_HM, /* key to be hashed is a hexidecimal 4-byte integer */
+ DECIMAL_HM, /* key to be hashed is a decimal 4-byte integer */
+ AB_HM, /* key to be hashed is "A B", where A and B are (A,B) in hex */
+ ABDEC_HM /* like AB_HM, but in decimal */
+ } mode;
+ enum {
+ STRING_HT, /* key is a string */
+ INT_HT, /* key is an integer */
+ AB_HT /* dunno what key is, but input is distinct (A,B) pair */
+ } hashtype;
+ enum {
+ NORMAL_HP, /* just find a perfect hash */
+ MINIMAL_HP /* find a minimal perfect hash */
+ } perfect;
+ enum {
+ FAST_HS, /* fast mode */
+ SLOW_HS /* slow mode */
+ } speed;
+};
+typedef struct hashform hashform;
+
+/* representation of a key */
+struct key
+{
+ ub1 *name_k; /* the actual key */
+ ub4 len_k; /* the length of the actual key */
+ ub4 hash_k; /* the initial hash value for this key */
+ struct key *next_k; /* next key */
+/* beyond this point is mapping-dependent */
+ ub4 a_k; /* a, of the key maps to (a,b) */
+ ub4 b_k; /* b, of the key maps to (a,b) */
+ struct key *nextb_k; /* next key with this b */
+};
+typedef struct key key;
+
+/* things indexed by b of original (a,b) pair */
+struct bstuff
+{
+ ub2 val_b; /* hash=a^tabb[b].val_b */
+ key *list_b; /* tabb[i].list_b is list of keys with b==i */
+ ub4 listlen_b; /* length of list_b */
+ ub4 water_b; /* high watermark of who has visited this map node */
+};
+typedef struct bstuff bstuff;
+
+/* things indexed by final hash value */
+struct hstuff
+{
+ key *key_h; /* tabh[i].key_h is the key with a hash of i */
+};
+typedef struct hstuff hstuff;
+
+/* things indexed by queue position */
+struct qstuff
+{
+ bstuff *b_q; /* b that currently occupies this hash */
+ ub4 parent_q; /* queue position of parent that could use this hash */
+ ub2 newval_q; /* what to change parent tab[b] to to use this hash */
+ ub2 oldval_q; /* original value of tab[b] */
+};
+typedef struct qstuff qstuff;
+
+/* return ceiling(log based 2 of x) */
+ub4 mylog2(/*_ ub4 x _*/);
+
+/* Given the keys, scramble[], and hash mode, find the perfect hash */
+void findhash(/*_ bstuff **tabb, ub4 *alen, ub4 *blen, ub4 *salt,
+ gencode *final, ub4 *scramble, ub4 smax, key *keys, ub4 nkeys,
+ hashform *form _*/);
+
+/* private, but in a different file because it's excessively verbose */
+int inithex(/*_ key *keys, ub4 *alen, ub4 *blen, ub4 smax, ub4 nkeys,
+ ub4 salt, gencode *final, gencode *form _*/);
+
+#endif /* PERFECT */
diff --git a/tools/codegen/core/perfect/perfhex.c b/tools/codegen/core/perfect/perfhex.c
new file mode 100644
index 0000000000..9c28dc734b
--- /dev/null
+++ b/tools/codegen/core/perfect/perfhex.c
@@ -0,0 +1,1308 @@
+/*
+------------------------------------------------------------------------------
+perfhex.c: code to generate code for a hash for perfect hashing.
+(c) Bob Jenkins, December 31 1999
+You may use this code in any way you wish, and it is free. No warranty.
+I hereby place this in the public domain.
+Source is http://burtleburtle.net/bob/c/perfhex.c
+
+The task of this file is to do the minimal amount of mixing needed to
+find distinct (a,b) for each key when each key is a distinct ub4. That
+means trying all possible ways to mix starting with the fastest. The
+output is those (a,b) pairs and code in the *final* structure for producing
+those pairs.
+------------------------------------------------------------------------------
+*/
+
+#ifndef STANDARD
+#include "standard.h"
+#endif
+#ifndef LOOKUPA
+#include "lookupa.h"
+#endif
+#ifndef RECYCLE
+#include "recycle.h"
+#endif
+#ifndef PERFECT
+#include "perfect.h"
+#endif
+
+/*
+ * Find a perfect hash when there is only one key. Zero instructions.
+ * Hint: the one key always hashes to 0
+ */
+static void hexone(keys, final)
+key *keys;
+gencode *final;
+{
+ /* 1 key: the hash is always 0 */
+ keys->a_k = 0;
+ keys->b_k = 0;
+ final->used = 1;
+ sprintf(final->line[0], " ub4 rsl = 0;\n"); /* h1a: 37 */
+}
+
+
+
+/*
+ * Find a perfect hash when there are only two keys. Max 2 instructions.
+ * There exists a bit that is different for the two keys. Test it.
+ * Note that a perfect hash of 2 keys is automatically minimal.
+ */
+static void hextwo(keys, final)
+key *keys;
+gencode *final;
+{
+ ub4 a = keys->hash_k;
+ ub4 b = keys->next_k->hash_k;
+ ub4 i;
+
+ if (a == b)
+ {
+ printf("fatal error: duplicate keys\n");
+ exit(SUCCESS);
+ }
+
+ final->used = 1;
+
+ /* one instruction */
+ if ((a&1) != (b&1))
+ {
+ sprintf(final->line[0], " ub4 rsl = (val & 1);\n"); /* h2a: 3,4 */
+ return;
+ }
+
+ /* two instructions */
+ for (i=0; i<UB4BITS; ++i)
+ {
+ if ((a&((ub4)1<<i)) != (b&((ub4)1<<i))) break;
+ }
+ /* h2b: 4,6 */
+ sprintf(final->line[0], " ub4 rsl = ((val << %ld) & 1);\n", i);
+}
+
+
+
+/*
+ * find the value to xor to a and b and c to make none of them 3
+ * assert, (a,b,c) are three distinct values in (0,1,2,3).
+ */
+static ub4 find_adder(a,b,c)
+ub4 a;
+ub4 b;
+ub4 c;
+{
+ return (a^b^c^3);
+}
+
+
+
+/*
+ * Find a perfect hash when there are only three keys. Max 6 instructions.
+ *
+ * keys a,b,c.
+ * There exists bit i such that a[i] != b[i].
+ * Either c[i] != a[i] or c[i] != b[i], assume c[i] != a[i].
+ * There exists bit j such that b[j] != c[j]. Note i != j.
+ * Final hash should be no longer than val[i]^val[j].
+ *
+ * A minimal perfect hash needs to xor one of 0,1,2,3 afterwards to cause
+ * the hole to land on 3. find_adder() finds that constant
+ */
+static void hexthree(keys, final, form)
+key *keys;
+gencode *final;
+hashform *form;
+{
+ ub4 a = keys->hash_k;
+ ub4 b = keys->next_k->hash_k;
+ ub4 c = keys->next_k->next_k->hash_k;
+ ub4 i,j,x,y,z;
+
+ final->used = 1;
+
+ if (a == b || a == c || b == c)
+ {
+ printf("fatal error: duplicate keys\n");
+ exit(SUCCESS);
+ }
+
+ /* one instruction */
+ x = a&3;
+ y = b&3;
+ z = c&3;
+ if (x != y && x != z && y != z)
+ {
+ if (form->perfect == NORMAL_HP || (x != 3 && y != 3 && z != 3))
+ {
+ /* h3a: 0,1,2 */
+ sprintf(final->line[0], " ub4 rsl = (val & 3);\n");
+ }
+ else
+ {
+ /* h3b: 0,3,2 */
+ sprintf(final->line[0], " ub4 rsl = ((val & 3) ^ %d);\n",
+ find_adder(x,y,z));
+ }
+ return;
+ }
+
+ x = a>>(UB4BITS-2);
+ y = b>>(UB4BITS-2);
+ z = c>>(UB4BITS-2);
+ if (x != y && x != z && y != z)
+ {
+ if (form->perfect == NORMAL_HP || (x != 3 && y != 3 && z != 3))
+ {
+ /* h3c: 3fffffff, 7fffffff, bfffffff */
+ sprintf(final->line[0], " ub4 rsl = (val >> %ld);\n", (ub4)(UB4BITS-2));
+ }
+ else
+ {
+ /* h3d: 7fffffff, bfffffff, ffffffff */
+ sprintf(final->line[0], " ub4 rsl = ((val >> %ld) ^ %ld);\n",
+ (ub4)(UB4BITS-2), find_adder(x,y,z));
+ }
+ return;
+ }
+
+ /* two instructions */
+ for (i=0; i<final->highbit; ++i)
+ {
+ x = (a>>i)&3;
+ y = (b>>i)&3;
+ z = (c>>i)&3;
+ if (x != y && x != z && y != z)
+ {
+ if (form->perfect == NORMAL_HP || (x != 3 && y != 3 && z != 3))
+ {
+ /* h3e: ffff3fff, ffff7fff, ffffbfff */
+ sprintf(final->line[0], " ub4 rsl = ((val >> %ld) & 3);\n", i);
+ }
+ else
+ {
+ /* h3f: ffff7fff, ffffbfff, ffffffff */
+ sprintf(final->line[0], " ub4 rsl = (((val >> %ld) & 3) ^ %ld);\n", i,
+ find_adder(x,y,z));
+ }
+ return;
+ }
+ }
+
+ /* three instructions */
+ for (i=0; i<=final->highbit; ++i)
+ {
+ x = (a+(a>>i))&3;
+ y = (b+(b>>i))&3;
+ z = (c+(c>>i))&3;
+ if (x != y && x != z && y != z)
+ {
+ if (form->perfect == NORMAL_HP || (x != 3 && y != 3 && z != 3))
+ {
+ /* h3g: 0x000, 0x001, 0x100 */
+ sprintf(final->line[0], " ub4 rsl = ((val+(val>>%ld))&3);\n", i);
+ }
+ else
+ {
+ /* h3h: 0x001, 0x100, 0x101 */
+ sprintf(final->line[0], " ub4 rsl = (((val+(val>>%ld))&3)^%ld);\n", i,
+ find_adder(x,y,z));
+ }
+ return;
+ }
+ }
+
+ /*
+ * Four instructions: I can prove this will always work.
+ *
+ * If the three values are distinct, there are two bits which
+ * distinguish them. Choose the two such bits that are closest together.
+ * If those bits are values 001 and 100 for those three values,
+ * then there either aren't any bits in between
+ * or the in-between bits aren't valued 001, 110, 100, 011, 010, or 101,
+ * because that would violate the closest-together assumption.
+ * So any in-between bits must be 000 or 111, and of 000 and 111 with
+ * the distinguishing bits won't cause them to stop being distinguishing.
+ */
+ for (i=final->lowbit; i<=final->highbit; ++i)
+ {
+ for (j=i; j<=final->highbit; ++j)
+ {
+ x = ((a>>i)^(a>>j))&3;
+ y = ((b>>i)^(b>>j))&3;
+ z = ((c>>i)^(c>>j))&3;
+ if (x != y && x != z && y != z)
+ {
+ if (form->perfect == NORMAL_HP || (x != 3 && y != 3 && z != 3))
+ {
+ /* h3i: 0x00, 0x04, 0x10 */
+ sprintf(final->line[0],
+ " ub4 rsl = (((val>>%ld) ^ (val>>%ld)) & 3);\n", i, j);
+ }
+ else
+ {
+ /* h3j: 0x04, 0x10, 0x14 */
+ sprintf(final->line[0],
+ " ub4 rsl = ((((val>>%ld) ^ (val>>%ld)) & 3) ^ %ld);\n",
+ i, j, find_adder(x,y,z));
+ }
+ return;
+ }
+ }
+ }
+
+ printf("fatal error: hexthree\n");
+ exit(SUCCESS);
+}
+
+
+
+/*
+ * Check that a,b,c,d are some permutation of 0,1,2,3
+ * Assume that a,b,c,d are all have values less than 32.
+ */
+static int testfour(a,b,c,d)
+ub4 a;
+ub4 b;
+ub4 c;
+ub4 d;
+{
+ ub4 mask = (1<<a)^(1<<b)^(1<<c)^(1<<d);
+ return (mask == 0xf);
+}
+
+
+
+/*
+ * Find a perfect hash when there are only four keys. Max 10 instructions.
+ * Note that a perfect hash for 4 keys will automatically be minimal.
+ */
+static void hexfour(keys, final)
+key *keys;
+gencode *final;
+{
+ ub4 a = keys->hash_k;
+ ub4 b = keys->next_k->hash_k;
+ ub4 c = keys->next_k->next_k->hash_k;
+ ub4 d = keys->next_k->next_k->next_k->hash_k;
+ ub4 w,x,y,z;
+ ub4 i,j,k;
+
+ if (a==b || a==c || a==d || b==c || b==d || c==d)
+ {
+ printf("fatal error: Duplicate keys\n");
+ exit(SUCCESS);
+ }
+
+ final->used = 1;
+
+ /* one instruction */
+ if ((final->diffbits & 3) == 3)
+ {
+ w = a&3;
+ x = b&3;
+ y = c&3;
+ z = d&3;
+ if (testfour(w,x,y,z))
+ {
+ sprintf(final->line[0], " ub4 rsl = (val & 3);\n"); /* h4a: 0,1,2,3 */
+ return;
+ }
+ }
+
+ if (((final->diffbits >> (UB4BITS-2)) & 3) == 3)
+ {
+ w = a>>(UB4BITS-2);
+ x = b>>(UB4BITS-2);
+ y = c>>(UB4BITS-2);
+ z = d>>(UB4BITS-2);
+ if (testfour(w,x,y,z))
+ { /* h4b: 0fffffff, 4fffffff, 8fffffff, cfffffff */
+ sprintf(final->line[0], " ub4 rsl = (val >> %ld);\n", (ub4)(UB4BITS-2));
+ return;
+ }
+ }
+
+ /* two instructions */
+ for (i=final->lowbit; i<final->highbit; ++i)
+ {
+ if (((final->diffbits >> i) & 3) == 3)
+ {
+ w = (a>>i)&3;
+ x = (b>>i)&3;
+ y = (c>>i)&3;
+ z = (d>>i)&3;
+ if (testfour(w,x,y,z))
+ { /* h4c: 0,2,4,6 */
+ sprintf(final->line[0], " ub4 rsl = ((val >> %ld) & 3);\n", i);
+ return;
+ }
+ }
+ }
+
+ /* three instructions (linear with the number of diffbits) */
+ if ((final->diffbits & 3) != 0)
+ {
+ for (i=final->lowbit; i<=final->highbit; ++i)
+ {
+ if (((final->diffbits >> i) & 3) != 0)
+ {
+ w = (a+(a>>i))&3;
+ x = (b+(b>>i))&3;
+ y = (c+(c>>i))&3;
+ z = (d+(d>>i))&3;
+ if (testfour(w,x,y,z))
+ { /* h4d: 0,1,2,4 */
+ sprintf(final->line[0],
+ " ub4 rsl = ((val + (val >> %ld)) & 3);\n", i);
+ return;
+ }
+
+ w = (a-(a>>i))&3;
+ x = (b-(b>>i))&3;
+ y = (c-(c>>i))&3;
+ z = (d-(d>>i))&3;
+ if (testfour(w,x,y,z))
+ { /* h4e: 0,1,3,5 */
+ sprintf(final->line[0],
+ " ub4 rsl = ((val - (val >> %ld)) & 3);\n", i);
+ return;
+ }
+
+ /* h4f: ((val>>k)-val)&3: redundant with h4e */
+
+ w = (a^(a>>i))&3;
+ x = (b^(b>>i))&3;
+ y = (c^(c>>i))&3;
+ z = (d^(d>>i))&3;
+ if (testfour(w,x,y,z))
+ { /* h4g: 3,4,5,8 */
+ sprintf(final->line[0],
+ " ub4 rsl = ((val ^ (val >> %ld)) & 3);\n", i);
+ return;
+ }
+ }
+ }
+ }
+
+ /* four instructions (linear with the number of diffbits) */
+ if ((final->diffbits & 3) != 0)
+ {
+ for (i=final->lowbit; i<=final->highbit; ++i)
+ {
+ if ((((final->diffbits >> i) & 1) != 0) &&
+ ((final->diffbits & 2) != 0))
+ {
+ w = (a&3)^((a>>i)&1);
+ x = (b&3)^((b>>i)&1);
+ y = (c&3)^((c>>i)&1);
+ z = (d&3)^((d>>i)&1);
+ if (testfour(w,x,y,z))
+ { /* h4h: 1,2,6,8 */
+ sprintf(final->line[0],
+ " ub4 rsl = ((val & 3) ^ ((val >> %ld) & 1));\n", i);
+ return;
+ }
+
+ w = (a&2)^((a>>i)&1);
+ x = (b&2)^((b>>i)&1);
+ y = (c&2)^((c>>i)&1);
+ z = (d&2)^((d>>i)&1);
+ if (testfour(w,x,y,z))
+ { /* h4i: 1,2,8,a */
+ sprintf(final->line[0],
+ " ub4 rsl = ((val & 2) ^ ((val >> %ld) & 1));\n", i);
+ return;
+ }
+ }
+
+ if ((((final->diffbits >> i) & 2) != 0) &&
+ ((final->diffbits & 1) != 0))
+ {
+ w = (a&3)^((a>>i)&2);
+ x = (b&3)^((b>>i)&2);
+ y = (c&3)^((c>>i)&2);
+ z = (d&3)^((d>>i)&2);
+ if (testfour(w,x,y,z))
+ { /* h4j: 0,1,3,4 */
+ sprintf(final->line[0],
+ " ub4 rsl = ((val & 3) ^ ((val >> %ld) & 2));\n", i);
+ return;
+ }
+
+ w = (a&1)^((a>>i)&2);
+ x = (b&1)^((b>>i)&2);
+ y = (c&1)^((c>>i)&2);
+ z = (d&1)^((d>>i)&2);
+ if (testfour(w,x,y,z))
+ { /* h4k: 1,4,7,8 */
+ sprintf(final->line[0],
+ " ub4 rsl = ((val & 1) ^ ((val >> %ld) & 2));\n", i);
+ return;
+ }
+ }
+ }
+ }
+
+ /* four instructions (quadratic in the number of diffbits) */
+ for (i=final->lowbit; i<=final->highbit; ++i)
+ {
+ if (((final->diffbits >> i) & 1) == 1)
+ {
+ for (j=final->lowbit; j<=final->highbit; ++j)
+ {
+ if (((final->diffbits >> j) & 3) != 0)
+ {
+ /* test + */
+ w = ((a>>i)+(a>>j))&3;
+ x = ((b>>i)+(a>>j))&3;
+ y = ((c>>i)+(a>>j))&3;
+ z = ((d>>i)+(a>>j))&3;
+ if (testfour(w,x,y,z))
+ { /* h4l: testcase? */
+ sprintf(final->line[0],
+ " ub4 rsl = (((val >> %ld) + (val >> %ld)) & 3);\n",
+ i, j);
+ return;
+ }
+
+ /* test - */
+ w = ((a>>i)-(a>>j))&3;
+ x = ((b>>i)-(a>>j))&3;
+ y = ((c>>i)-(a>>j))&3;
+ z = ((d>>i)-(a>>j))&3;
+ if (testfour(w,x,y,z))
+ { /* h4m: testcase? */
+ sprintf(final->line[0],
+ " ub4 rsl = (((val >> %ld) - (val >> %ld)) & 3);\n",
+ i, j);
+ return;
+ }
+
+ /* test ^ */
+ w = ((a>>i)^(a>>j))&3;
+ x = ((b>>i)^(a>>j))&3;
+ y = ((c>>i)^(a>>j))&3;
+ z = ((d>>i)^(a>>j))&3;
+ if (testfour(w,x,y,z))
+ { /* h4n: testcase? */
+ sprintf(final->line[0],
+ " ub4 rsl = (((val >> %ld) ^ (val >> %ld)) & 3);\n",
+ i, j);
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ /* five instructions (quadratic in the number of diffbits) */
+ for (i=final->lowbit; i<=final->highbit; ++i)
+ {
+ if (((final->diffbits >> i) & 1) != 0)
+ {
+ for (j=final->lowbit; j<=final->highbit; ++j)
+ {
+ if (((final->diffbits >> j) & 3) != 0)
+ {
+ w = ((a>>j)&3)^((a>>i)&1);
+ x = ((b>>j)&3)^((b>>i)&1);
+ y = ((c>>j)&3)^((c>>i)&1);
+ z = ((d>>j)&3)^((d>>i)&1);
+ if (testfour(w,x,y,z))
+ { /* h4o: 0,4,8,a */
+ sprintf(final->line[0],
+ " ub4 rsl = (((val >> %ld) & 3) ^ ((val >> %ld) & 1));\n",
+ j, i);
+ return;
+ }
+
+ w = ((a>>j)&2)^((a>>i)&1);
+ x = ((b>>j)&2)^((b>>i)&1);
+ y = ((c>>j)&2)^((c>>i)&1);
+ z = ((d>>j)&2)^((d>>i)&1);
+ if (testfour(w,x,y,z))
+ { /* h4p: 0x04, 0x08, 0x10, 0x14 */
+ sprintf(final->line[0],
+ " ub4 rsl = (((val >> %ld) & 2) ^ ((val >> %ld) & 1));\n",
+ j, i);
+ return;
+ }
+ }
+
+ if (i==0)
+ {
+ w = ((a>>j)^(a<<1))&3;
+ x = ((b>>j)^(b<<1))&3;
+ y = ((c>>j)^(c<<1))&3;
+ z = ((d>>j)^(d<<1))&3;
+ }
+ else
+ {
+ w = ((a>>j)&3)^((a>>(i-1))&2);
+ x = ((b>>j)&3)^((b>>(i-1))&2);
+ y = ((c>>j)&3)^((c>>(i-1))&2);
+ z = ((d>>j)&3)^((d>>(i-1))&2);
+ }
+ if (testfour(w,x,y,z))
+ {
+ if (i==0) /* h4q: 0,4,5,8 */
+ {
+ sprintf(final->line[0],
+ " ub4 rsl = (((val >> %ld) ^ (val << 1)) & 3);\n",
+ j);
+ }
+ else if (i==1) /* h4r: 0x01,0x09,0x0b,0x10 */
+ {
+ sprintf(final->line[0],
+ " ub4 rsl = (((val >> %ld) & 3) ^ (val & 2));\n",
+ j);
+ }
+ else /* h4s: 0,2,6,8 */
+ {
+ sprintf(final->line[0],
+ " ub4 rsl = (((val >> %ld) & 3) ^ ((val >> %ld) & 2));\n",
+ j, (i-1));
+ }
+ return;
+ }
+
+ w = ((a>>j)&1)^((a>>i)&2);
+ x = ((b>>j)&1)^((b>>i)&2);
+ y = ((c>>j)&1)^((c>>i)&2);
+ z = ((d>>j)&1)^((d>>i)&2);
+ if (testfour(w,x,y,z)) /* h4t: 0x20,0x14,0x10,0x06 */
+ {
+ sprintf(final->line[0],
+ " ub4 rsl = (((val >> %ld) & 1) ^ ((val >> %ld) & 2));\n",
+ j, i);
+ return;
+ }
+ }
+ }
+ }
+
+ /*
+ * OK, bring out the big guns.
+ * There exist three bits i,j,k which distinguish a,b,c,d.
+ * i^(j<<1)^(k*q) is guaranteed to work for some q in {0,1,2,3},
+ * proven by exhaustive search of all (8 choose 4) cases.
+ * Find three such bits and try the 4 cases.
+ * Linear with the number of diffbits.
+ * Some cases below may duplicate some cases above. I did it that way
+ * so that what is below is guaranteed to work, no matter what was
+ * attempted above.
+ * The generated hash is at most 10 instructions.
+ */
+ for (i=final->lowbit; i<UB4BITS; ++i)
+ {
+ y = (c>>i)&1;
+ z = (d>>i)&1;
+ if (y != z)
+ break;
+ }
+
+ for (j=final->lowbit; j<UB4BITS; ++j)
+ {
+ x = ((b>>i)&1)^(((b>>j)&1)<<1);
+ y = ((c>>i)&1)^(((c>>j)&1)<<1);
+ z = ((d>>i)&1)^(((d>>j)&1)<<1);
+ if (x != y && x != z && y != z)
+ break;
+ }
+
+ for (k=final->lowbit; k<UB4BITS; ++k)
+ {
+ w = ((a>>i)&1)^(((a>>j)&1)<<1)^(((a>>k)&1)<<2);
+ x = ((b>>i)&1)^(((b>>j)&1)<<1)^(((b>>k)&1)<<2);
+ y = ((c>>i)&1)^(((c>>j)&1)<<1)^(((c>>k)&1)<<2);
+ z = ((d>>i)&1)^(((d>>j)&1)<<1)^(((d>>k)&1)<<2);
+ if (w != x && w != y && w != z && x != y && x != z && y != z)
+ break;
+ }
+
+ /* Assert: bits i,j,k were found which distinguish a,b,c,d */
+ if (i==UB4BITS || j==UB4BITS || k==UB4BITS)
+ {
+ printf("Fatal error: hexfour(), i %ld j %ld k %ld\n", i,j,k);
+ exit(SUCCESS);
+ }
+
+ /* now try the four cases */
+ {
+ ub4 m,n,o,p;
+
+ /* if any bit has two 1s and two 0s, make that bit o */
+ if (((a>>i)&1)+((b>>i)&1)+((c>>i)&1)+((d>>i)&1) != 2)
+ { m=j; n=k; o=i; }
+ else if (((a>>j)&1)+((b>>j)&1)+((c>>j)&1)+((d>>j)&1) != 2)
+ { m=i; n=k; o=j; }
+ else
+ { m=i; n=j; o=k; }
+ if (m > n) {p=m; m=n; n=p; } /* guarantee m < n */
+
+ /* printf("m %ld n %ld o %ld %ld %ld %ld %ld\n", m, n, o, w,x,y,z); */
+
+ /* seven instructions, multiply bit o by 1 */
+ w = (((a>>m)^(a>>o))&1)^((a>>(n-1))&2);
+ x = (((b>>m)^(b>>o))&1)^((b>>(n-1))&2);
+ y = (((c>>m)^(c>>o))&1)^((c>>(n-1))&2);
+ z = (((d>>m)^(d>>o))&1)^((d>>(n-1))&2);
+ if (testfour(w,x,y,z))
+ {
+ if (m>o) {p=m; m=o; o=p;} /* make sure m < o and m < n */
+
+ if (m==0) /* 0,2,8,9 */
+ {
+ sprintf(final->line[0],
+ " ub4 rsl = (((val^(val>>%ld))&1)^((val>>%ld)&2));\n", o, n-1);
+ }
+ else /* 0x00,0x04,0x10,0x12 */
+ {
+ sprintf(final->line[0],
+ " ub4 rsl = ((((val>>%ld) ^ (val>>%ld)) & 1) ^ ((val>>%ld) & 2));\n",
+ m, o, n-1);
+ }
+ return;
+ }
+
+ /* six to seven instructions, multiply bit o by 2 */
+ w = ((a>>m)&1)^((((a>>n)^(a>>o))&1)<<1);
+ x = ((b>>m)&1)^((((b>>n)^(b>>o))&1)<<1);
+ y = ((c>>m)&1)^((((c>>n)^(c>>o))&1)<<1);
+ z = ((d>>m)&1)^((((d>>n)^(d>>o))&1)<<1);
+ if (testfour(w,x,y,z))
+ {
+ if (m==o-1) {p=n; n=o; o=p;} /* make m==n-1 if possible */
+
+ if (m==0) /* 0,1,5,8 */
+ {
+ sprintf(final->line[0],
+ " ub4 rsl = ((val & 1) ^ (((val>>%ld) ^ (val>>%ld)) & 2));\n",
+ n-1, o-1);
+ }
+ else if (o==0) /* 0x00,0x04,0x05,0x10 */
+ {
+ sprintf(final->line[0],
+ " ub4 rsl = (((val>>%ld) & 2) ^ (((val>>%ld) ^ val) & 1));\n",
+ m-1, n);
+ }
+ else /* 0x00,0x02,0x0a,0x10 */
+ {
+ sprintf(final->line[0],
+ " ub4 rsl = (((val>>%ld) & 1) ^ (((val>>%ld) ^ (val>>%ld)) & 2));\n",
+ m, n-1, o-1);
+ }
+ return;
+ }
+
+ /* multiplying by 3 is a pain: seven or eight instructions */
+ w = (((a>>m)&1)^((a>>(n-1))&2))^((a>>o)&1)^(((a>>o)&1)<<1);
+ x = (((b>>m)&1)^((b>>(n-1))&2))^((b>>o)&1)^(((b>>o)&1)<<1);
+ y = (((c>>m)&1)^((c>>(n-1))&2))^((c>>o)&1)^(((c>>o)&1)<<1);
+ z = (((d>>m)&1)^((d>>(n-1))&2))^((d>>o)&1)^(((d>>o)&1)<<1);
+ if (testfour(w,x,y,z))
+ {
+ final->used = 2;
+ sprintf(final->line[0], " ub4 b = (val >> %ld) & 1;\n", o);
+ if (m==o-1 && m==0) /* 0x02,0x10,0x11,0x18 */
+ {
+ sprintf(final->line[1],
+ " ub4 rsl = ((val & 3) ^ ((val >> %ld) & 2) ^ b);\n", n-1);
+ }
+ else if (m==o-1) /* 0,4,6,c */
+ {
+ sprintf(final->line[1],
+ " ub4 rsl = (((val >> %ld) & 3) ^ ((val >> %ld) & 2) ^ b);\n",
+ m, n-1);
+ }
+ else if (m==n-1 && m==0) /* 02,0a,0b,18 */
+ {
+ sprintf(final->line[1],
+ " ub4 rsl = ((val & 3) ^ b ^ (b << 1));\n");
+ }
+ else if (m==n-1) /* 0,2,4,8 */
+ {
+ sprintf(final->line[1],
+ " ub4 rsl = (((val >> %ld) & 3) ^ b ^ (b << 1));\n", m);
+ }
+ else if (o==n-1 && m==0) /* h4am: not reached */
+ {
+ sprintf(final->line[1],
+ " ub4 rsl = ((val & 1) ^ ((val >> %ld) & 3) ^ (b <<1 ));\n",
+ o);
+ }
+ else if (o==n-1) /* 0x00,0x02,0x08,0x10 */
+ {
+ sprintf(final->line[1],
+ " ub4 rsl = (((val >> %ld) & 1) ^ ((val >> %ld) & 3) ^ (b << 1));\n",
+ m, o);
+ }
+ else if ((m != o-1) && (m != n-1) && (o != m-1) && (o != n-1))
+ {
+ final->used = 3;
+ sprintf(final->line[0], " ub4 newval = val & 0x%lx;\n",
+ (((ub4)1<<m)^((ub4)1<<n)^((ub4)1<<o)));
+ if (o==0) /* 0x00,0x01,0x04,0x10 */
+ {
+ sprintf(final->line[1], " ub4 b = -newval;\n");
+ }
+ else /* 0x00,0x04,0x09,0x10 */
+ {
+ sprintf(final->line[1], " ub4 b = -(newval >> %ld);\n", o);
+ }
+ if (m==0) /* 0x00,0x04,0x09,0x10 */
+ {
+ sprintf(final->line[2],
+ " ub4 rsl = ((newval ^ (newval>>%ld) ^ b) & 3);\n", n-1);
+ }
+ else /* 0x00,0x03,0x04,0x10 */
+ {
+ sprintf(final->line[2],
+ " ub4 rsl = (((newval>>%ld) ^ (newval>>%ld) ^ b) & 3);\n",
+ m, n-1);
+ }
+ }
+ else if (o == m-1)
+ {
+ if (o==0) /* 0x02,0x03,0x0a,0x10 */
+ {
+ sprintf(final->line[0], " ub4 b = (val<<1) & 2;\n");
+ }
+ else if (o==1) /* 0x00,0x02,0x04,0x10 */
+ {
+ sprintf(final->line[0], " ub4 b = val & 2;\n");
+ }
+ else /* 0x00,0x04,0x08,0x20 */
+ {
+ sprintf(final->line[0], " ub4 b = (val>>%ld) & 2;\n", o-1);
+ }
+
+ if (o==0) /* 0x02,0x03,0x0a,0x10 */
+ {
+ sprintf(final->line[1],
+ " ub4 rsl = ((val & 3) ^ ((val>>%ld) & 1) ^ b);\n",
+ n);
+ }
+ else /* 0x00,0x02,0x04,0x10 */
+ {
+ sprintf(final->line[1],
+ " ub4 rsl = (((val>>%ld) & 3) ^ ((val>>%ld) & 1) ^ b);\n",
+ o, n);
+ }
+ }
+ else /* h4ax: 10 instructions, but not reached */
+ {
+ sprintf(final->line[1],
+ " ub4 rsl = (((val>>%ld) & 1) ^ ((val>>%ld) & 2) ^ b ^ (b<<1));\n",
+ m, n-1);
+ }
+
+ return;
+ }
+
+ /* five instructions, multiply bit o by 0, covered before the big guns */
+ w = ((a>>m)&1)^(a>>(n-1)&2);
+ x = ((b>>m)&1)^(b>>(n-1)&2);
+ y = ((c>>m)&1)^(c>>(n-1)&2);
+ z = ((d>>m)&1)^(d>>(n-1)&2);
+ if (testfour(w,x,y,z))
+ { /* h4v, not reached */
+ sprintf(final->line[0],
+ " ub4 rsl = (((val>>%ld) & 1) ^ ((val>>%ld) & 2));\n", m, n-1);
+ return;
+ }
+ }
+
+ printf("fatal error: bug in hexfour!\n");
+ exit(SUCCESS);
+ return;
+}
+
+
+/* test if a_k is distinct and in range for all keys */
+static int testeight(keys, badmask)
+key *keys; /* keys being hashed */
+ub1 badmask; /* used for minimal perfect hashing */
+{
+ ub1 mask = badmask;
+ key *mykey;
+
+ for (mykey=keys; mykey; mykey=mykey->next_k)
+ {
+ if (bit(mask, 1<<mykey->a_k)) return FALSE;
+ bis(mask, 1<<mykey->a_k);
+ }
+ return TRUE;
+}
+
+
+
+/*
+ * Try to find a perfect hash when there are five to eight keys.
+ *
+ * We can't deterministically find a perfect hash, but there's a reasonable
+ * chance we'll get lucky. Give it a shot. Return TRUE if we succeed.
+ */
+static int hexeight(keys, nkeys, final, form)
+key *keys;
+ub4 nkeys;
+gencode *final;
+hashform *form;
+{
+ key *mykey; /* walk through the keys */
+ ub4 i,j,k;
+ ub1 badmask;
+
+ printf("hexeight\n");
+
+ /* what hash values should never be used? */
+ badmask = 0;
+ if (form->perfect == MINIMAL_HP)
+ {
+ for (i=nkeys; i<8; ++i)
+ bis(badmask,(1<<i));
+ }
+
+ /* one instruction */
+ for (mykey=keys; mykey; mykey=mykey->next_k)
+ mykey->a_k = mykey->hash_k & 7;
+ if (testeight(keys, badmask))
+ { /* h8a */
+ final->used = 1;
+ sprintf(final->line[0], " ub4 rsl = (val & 7);\n");
+ return TRUE;
+ }
+
+ /* two instructions */
+ for (i=final->lowbit; i<=final->highbit-2; ++i)
+ {
+ for (mykey=keys; mykey; mykey=mykey->next_k)
+ mykey->a_k = (mykey->hash_k >> i) & 7;
+ if (testeight(keys, badmask))
+ { /* h8b */
+ final->used = 1;
+ sprintf(final->line[0], " ub4 rsl = ((val >> %ld) & 7);\n", i);
+ return TRUE;
+ }
+ }
+
+ /* four instructions */
+ for (i=final->lowbit; i<=final->highbit; ++i)
+ {
+ for (j=i+1; j<=final->highbit; ++j)
+ {
+ for (mykey=keys; mykey; mykey=mykey->next_k)
+ mykey->a_k = ((mykey->hash_k >> i)+(mykey->hash_k >> j)) & 7;
+ if (testeight(keys, badmask))
+ {
+ final->used = 1;
+ if (i == 0) /* h8c */
+ sprintf(final->line[0],
+ " ub4 rsl = ((val + (val >> %ld)) & 7);\n", j);
+ else /* h8d */
+ sprintf(final->line[0],
+ " ub4 rsl = (((val >> %ld) + (val >> %ld)) & 7);\n", i, j);
+ return TRUE;
+ }
+
+ for (mykey=keys; mykey; mykey=mykey->next_k)
+ mykey->a_k = ((mykey->hash_k >> i)^(mykey->hash_k >> j)) & 7;
+ if (testeight(keys, badmask))
+ {
+ final->used = 1;
+ if (i == 0) /* h8e */
+ sprintf(final->line[0],
+ " ub4 rsl = ((val ^ (val >> %ld)) & 7);\n", j);
+ else /* h8f */
+ sprintf(final->line[0],
+ " ub4 rsl = (((val >> %ld) ^ (val >> %ld)) & 7);\n", i, j);
+
+ return TRUE;
+ }
+
+ for (mykey=keys; mykey; mykey=mykey->next_k)
+ mykey->a_k = ((mykey->hash_k >> i)-(mykey->hash_k >> j)) & 7;
+ if (testeight(keys, badmask))
+ {
+ final->used = 1;
+ if (i == 0) /* h8g */
+ sprintf(final->line[0],
+ " ub4 rsl = ((val - (val >> %ld)) & 7);\n", j);
+ else /* h8h */
+ sprintf(final->line[0],
+ " ub4 rsl = (((val >> %ld) - (val >> %ld)) & 7);\n", i, j);
+
+ return TRUE;
+ }
+ }
+ }
+
+
+ /* six instructions */
+ for (i=final->lowbit; i<=final->highbit; ++i)
+ {
+ for (j=i+1; j<=final->highbit; ++j)
+ {
+ for (k=j+1; k<=final->highbit; ++k)
+ {
+ for (mykey=keys; mykey; mykey=mykey->next_k)
+ mykey->a_k = ((mykey->hash_k >> i) +
+ (mykey->hash_k >> j) +
+ (mykey->hash_k >> k)) & 7;
+ if (testeight(keys, badmask))
+ { /* h8i */
+ final->used = 1;
+ sprintf(final->line[0],
+ " ub4 rsl = (((val >> %ld) + (val >> %ld) + (val >> %ld)) & 7);\n",
+ i, j, k);
+ return TRUE;
+ }
+ }
+ }
+ }
+
+
+ return FALSE;
+}
+
+
+
+/*
+ * Guns aren't enough. Bring out the Bomb. Use tab[].
+ * This finds the initial (a,b) when we need to use tab[].
+ *
+ * We need to produce a different (a,b) every time this is called. Try all
+ * reasonable cases, fastest first.
+ *
+ * The initial mix (which this determines) can be filled into final starting
+ * at line[1]. val is set and a,b are declared. The final hash (at line[7])
+ * is a^tab[b] or a^scramble[tab[b]].
+ *
+ * The code will probably look like this, minus some stuff:
+ * val += CONSTANT;
+ * val ^= (val<<16);
+ * val += (val>>8);
+ * val ^= (val<<4);
+ * b = (val >> l) & 7;
+ * a = (val + (val<<m)) >> 29;
+ * return a^scramble[tab[b]];
+ * Note that *a* and tab[b] will be computed in parallel by most modern chips.
+ *
+ * final->i is the current state of the state machine.
+ * final->j and final->k are counters in the loops the states simulate.
+ */
+static void hexn(keys, salt, alen, blen, final)
+key *keys;
+ub4 salt;
+ub4 alen;
+ub4 blen;
+gencode *final;
+{
+ key *mykey;
+ ub4 highbit = final->highbit;
+ ub4 lowbit = final->lowbit;
+ ub4 alog = mylog2(alen);
+ ub4 blog = mylog2(blen);
+
+ for (;;)
+ {
+ switch(final->i)
+ {
+ case 1:
+ /* a = val>>30; b=val&3 */
+ for (mykey=keys; mykey; mykey=mykey->next_k)
+ {
+ mykey->a_k = (mykey->hash_k << (UB4BITS-(highbit+1)))>>(UB4BITS-alog);
+ mykey->b_k = (mykey->hash_k >> lowbit) & (blen-1);
+ }
+ if (lowbit == 0) /* hna */
+ sprintf(final->line[5], " b = (val & 0x%lx);\n",
+ blen-1);
+ else /* hnb */
+ sprintf(final->line[5], " b = ((val >> %ld) & 0x%lx);\n",
+ lowbit, blen-1);
+ if (highbit+1 == UB4BITS) /* hnc */
+ sprintf(final->line[6], " a = (val >> %ld);\n",
+ UB4BITS-alog);
+ else /* hnd */
+ sprintf(final->line[6], " a = ((val << %ld ) >> %ld);\n",
+ UB4BITS-(highbit+1), UB4BITS-alog);
+
+ ++final->i;
+ return;
+
+ case 2:
+ /* a = val&3; b=val>>30 */
+ for (mykey=keys; mykey; mykey=mykey->next_k)
+ {
+ mykey->a_k = (mykey->hash_k >> lowbit) & (alen-1);
+ mykey->b_k = (mykey->hash_k << (UB4BITS-(highbit+1)))>>(UB4BITS-blog);
+ }
+ if (highbit+1 == UB4BITS) /* hne */
+ sprintf(final->line[5], " b = (val >> %ld);\n",
+ UB4BITS-blog);
+ else /* hnf */
+ sprintf(final->line[5], " b = ((val << %ld ) >> %ld);\n",
+ UB4BITS-(highbit+1), UB4BITS-blog);
+ if (lowbit == 0) /* hng */
+ sprintf(final->line[6], " a = (val & 0x%lx);\n",
+ alen-1);
+ else /* hnh */
+ sprintf(final->line[6], " a = ((val >> %ld) & 0x%lx);\n",
+ lowbit, alen-1);
+
+ ++final->i;
+ return;
+
+ case 3:
+ /*
+ * cases 3,4,5:
+ * for (k=lowbit; k<=highbit; ++k)
+ * for (j=lowbit; j<=highbit; ++j)
+ * b = (val>>j)&3;
+ * a = (val<<k)>>30;
+ */
+ final->k = lowbit;
+ final->j = lowbit;
+ ++final->i;
+ break;
+
+ case 4:
+ if (!(final->j < highbit))
+ {
+ ++final->i;
+ break;
+ }
+ for (mykey=keys; mykey; mykey=mykey->next_k)
+ {
+ mykey->b_k = (mykey->hash_k >> (final->j)) & (blen-1);
+ mykey->a_k = (mykey->hash_k << (UB4BITS-final->k-1)) >> (UB4BITS-alog);
+ }
+ if (final->j == 0) /* hni */
+ sprintf(final->line[5], " b = val & 0x%lx;\n",
+ blen-1);
+ else if (blog+final->j == UB4BITS) /* hnja */
+ sprintf(final->line[5], " b = val >> %ld;\n",
+ final->j);
+ else
+ sprintf(final->line[5], " b = (val >> %ld) & 0x%lx;\n", /* hnj */
+ final->j, blen-1);
+ if (UB4BITS-final->k-1 == 0) /* hnk */
+ sprintf(final->line[6], " a = (val >> %ld);\n",
+ UB4BITS-alog);
+ else /* hnl */
+ sprintf(final->line[6], " a = ((val << %ld) >> %ld);\n",
+ UB4BITS-final->k-1, UB4BITS-alog);
+ while (++final->j < highbit)
+ {
+ if (((final->diffbits>>(final->j)) & (blen-1)) > 2)
+ break;
+ }
+ return;
+
+ case 5:
+ while (++final->k < highbit)
+ {
+ if ((((final->diffbits<<(UB4BITS-final->k-1))>>alog) & (alen-1)) > 0)
+ break;
+ }
+ if (!(final->k < highbit))
+ {
+ ++final->i;
+ break;
+ }
+ final->j = lowbit;
+ final->i = 4;
+ break;
+
+
+ case 6:
+ /*
+ * cases 6,7,8:
+ * for (k=0; k<UB4BITS-alog; ++k)
+ * for (j=0; j<UB4BITS-blog; ++j)
+ * val = val+f(salt);
+ * val ^= (val >> 16);
+ * val += (val << 8);
+ * val ^= (val >> 4);
+ * b = (val >> j) & 3;
+ * a = (val + (val << k)) >> 30;
+ */
+ final->k = 0;
+ final->j = 0;
+ ++final->i;
+ break;
+
+ case 7:
+ /* Just do something that will surely work */
+ {
+ ub4 addk = 0x9e3779b9*salt;
+
+ if (!(final->j <= UB4BITS-blog))
+ {
+ ++final->i;
+ break;
+ }
+ for (mykey=keys; mykey; mykey=mykey->next_k)
+ {
+ ub4 val = mykey->hash_k + addk;
+ if (final->highbit+1 - final->lowbit > 16)
+ val ^= (val >> 16);
+ if (final->highbit+1 - final->lowbit > 8)
+ val += (val << 8);
+ val ^= (val >> 4);
+ mykey->b_k = (val >> final->j) & (blen-1);
+ if (final->k == 0)
+ mykey->a_k = val >> (UB4BITS-alog);
+ else
+ mykey->a_k = (val + (val << final->k)) >> (UB4BITS-alog);
+ }
+ sprintf(final->line[1], " val += 0x%lx;\n", addk);
+ if (final->highbit+1 - final->lowbit > 16) /* hnm */
+ sprintf(final->line[2], " val ^= (val >> 16);\n");
+ if (final->highbit+1 - final->lowbit > 8) /* hnn */
+ sprintf(final->line[3], " val += (val << 8);\n");
+ sprintf(final->line[4], " val ^= (val >> 4);\n");
+ if (final->j == 0) /* hno: don't know how to reach this */
+ sprintf(final->line[5], " b = val & 0x%lx;\n", blen-1);
+ else /* hnp */
+ sprintf(final->line[5], " b = (val >> %ld) & 0x%lx;\n",
+ final->j, blen-1);
+ if (final->k == 0) /* hnq */
+ sprintf(final->line[6], " a = val >> %ld;\n", UB4BITS-alog);
+ else /* hnr */
+ sprintf(final->line[6], " a = (val + (val << %ld)) >> %ld;\n",
+ final->k, UB4BITS-alog);
+
+ ++final->j;
+ return;
+ }
+
+ case 8:
+ ++final->k;
+ if (!(final->k <= UB4BITS-alog))
+ {
+ ++final->i;
+ break;
+ }
+ final->j = 0;
+ final->i = 7;
+ break;
+
+ case 9:
+ final->i = 6;
+ break;
+ }
+ }
+}
+
+
+
+/* find the highest and lowest bit where any key differs */
+static void setlow(keys, final)
+key *keys;
+gencode *final;
+{
+ ub4 lowbit;
+ ub4 highbit;
+ ub4 i;
+ key *mykey;
+ ub4 firstkey;
+
+ /* mark the interesting bits in final->mask */
+ final->diffbits = (ub4)0;
+ if (keys) firstkey = keys->hash_k;
+ for (mykey=keys; mykey!=(key *)0; mykey=mykey->next_k)
+ final->diffbits |= (firstkey ^ mykey->hash_k);
+
+ /* find the lowest interesting bit */
+ for (i=0; i<UB4BITS; ++i)
+ if (final->diffbits & (((ub4)1)<<i))
+ break;
+ final->lowbit = i;
+
+ /* find the highest interesting bit */
+ for (i=UB4BITS; --i; )
+ if (final->diffbits & (((ub4)1)<<i))
+ break;
+ final->highbit = i;
+}
+
+/*
+ * Initialize (a,b) when keys are integers.
+ *
+ * Normally there's an initial hash which produces a number. That hash takes
+ * an initializer. Changing the initializer causes the initial hash to
+ * produce a different (uniformly distributed) number without any extra work.
+ *
+ * Well, here we start with a number. There's no initial hash. Any mixing
+ * costs extra work. So we go through a lot of special cases to minimize the
+ * mixing needed to get distinct (a,b). For small sets of keys, it's often
+ * fastest to skip the final hash and produce the perfect hash from the number
+ * directly.
+ *
+ * The target user for this is switch statement optimization. The common case
+ * is 3 to 16 keys, and instruction counts matter. The competition is a
+ * binary tree of branches.
+ *
+ * Return TRUE if we found a perfect hash and no more work is needed.
+ * Return FALSE if we just did an initial hash and more work is needed.
+ */
+int inithex(keys, nkeys, alen, blen, smax, salt, final, form)
+key *keys; /* list of all keys */
+ub4 nkeys; /* number of keys to hash */
+ub4 alen; /* (a,b) has a in 0..alen-1, a power of 2 */
+ub4 blen; /* (a,b) has b in 0..blen-1, a power of 2 */
+ub4 smax; /* maximum range of computable hash values */
+ub4 salt; /* used to initialize the hash function */
+gencode *final; /* output, code for the final hash */
+hashform *form; /* user directives */
+{
+ setlow(keys, final);
+
+ switch (nkeys)
+ {
+ case 1:
+ hexone(keys, final);
+ return TRUE;
+ case 2:
+ hextwo(keys, final);
+ return TRUE;
+ case 3:
+ hexthree(keys, final, form);
+ return TRUE;
+ case 4:
+ hexfour(keys, final);
+ return TRUE;
+ case 5: case 6: case 7: case 8:
+ if (salt == 1 && /* first time through */
+ hexeight(keys, nkeys, final, form)) /* get lucky, don't need tab[] ? */
+ return TRUE;
+ /* fall through */
+ default:
+ if (salt == 1)
+ {
+ final->used = 8;
+ final->i = 1;
+ final->j = final->k = final->l = final->m = final->n = final->o = 0;
+ sprintf(final->line[0], " ub4 a, b, rsl;\n");
+ sprintf(final->line[1], "\n");
+ sprintf(final->line[2], "\n");
+ sprintf(final->line[3], "\n");
+ sprintf(final->line[4], "\n");
+ sprintf(final->line[5], "\n");
+ sprintf(final->line[6], "\n");
+ if (blen < USE_SCRAMBLE)
+ { /* hns */
+ sprintf(final->line[7], " rsl = (a^tab[b]);\n");
+ }
+ else
+ { /* hnt */
+ sprintf(final->line[7], " rsl = (a^scramble[tab[b]]);\n");
+ }
+ }
+ hexn(keys, salt, alen, blen, final);
+ return FALSE;
+ }
+}
diff --git a/tools/codegen/core/perfect/recycle.c b/tools/codegen/core/perfect/recycle.c
new file mode 100644
index 0000000000..3f857cba7d
--- /dev/null
+++ b/tools/codegen/core/perfect/recycle.c
@@ -0,0 +1,87 @@
+/*
+--------------------------------------------------------------------
+By Bob Jenkins, September 1996. recycle.c
+You may use this code in any way you wish, and it is free. No warranty.
+
+This manages memory for commonly-allocated structures.
+It allocates RESTART to REMAX items at a time.
+Timings have shown that, if malloc is used for every new structure,
+ malloc will consume about 90% of the time in a program. This
+ module cuts down the number of mallocs by an order of magnitude.
+This also decreases memory fragmentation, and freeing structures
+ only requires freeing the root.
+--------------------------------------------------------------------
+*/
+
+#ifndef STANDARD
+# include "standard.h"
+#endif
+#ifndef RECYCLE
+# include "recycle.h"
+#endif
+
+reroot *remkroot(size)
+size_t size;
+{
+ reroot *r = (reroot *)remalloc(sizeof(reroot), "recycle.c, root");
+ r->list = (recycle *)0;
+ r->trash = (recycle *)0;
+ r->size = align(size);
+ r->logsize = RESTART;
+ r->numleft = 0;
+ return r;
+}
+
+void refree(r)
+struct reroot *r;
+{
+ recycle *temp;
+ if (temp = r->list) while (r->list)
+ {
+ temp = r->list->next;
+ free((char *)r->list);
+ r->list = temp;
+ }
+ free((char *)r);
+ return;
+}
+
+/* to be called from the macro renew only */
+char *renewx(r)
+struct reroot *r;
+{
+ recycle *temp;
+ if (r->trash)
+ { /* pull a node off the trash heap */
+ temp = r->trash;
+ r->trash = temp->next;
+ (void)memset((void *)temp, 0, r->size);
+ }
+ else
+ { /* allocate a new block of nodes */
+ r->numleft = r->size*((ub4)1<<r->logsize);
+ if (r->numleft < REMAX) ++r->logsize;
+ temp = (recycle *)remalloc(sizeof(recycle) + r->numleft,
+ "recycle.c, data");
+ temp->next = r->list;
+ r->list = temp;
+ r->numleft-=r->size;
+ temp = (recycle *)((char *)(r->list+1)+r->numleft);
+ }
+ return (char *)temp;
+}
+
+char *remalloc(len, purpose)
+size_t len;
+char *purpose;
+{
+ char *x = (char *)malloc(len);
+ if (!x)
+ {
+ fprintf(stderr, "malloc of %d failed for %s\n",
+ len, purpose);
+ exit(SUCCESS);
+ }
+ return x;
+}
+
diff --git a/tools/codegen/core/perfect/recycle.h b/tools/codegen/core/perfect/recycle.h
new file mode 100644
index 0000000000..7472495e84
--- /dev/null
+++ b/tools/codegen/core/perfect/recycle.h
@@ -0,0 +1,65 @@
+/*
+--------------------------------------------------------------------
+By Bob Jenkins, September 1996. recycle.h
+You may use this code in any way you wish, and it is free. No warranty.
+
+This manages memory for commonly-allocated structures.
+It allocates RESTART to REMAX items at a time.
+Timings have shown that, if malloc is used for every new structure,
+ malloc will consume about 90% of the time in a program. This
+ module cuts down the number of mallocs by an order of magnitude.
+This also decreases memory fragmentation, and freeing all structures
+ only requires freeing the root.
+--------------------------------------------------------------------
+*/
+
+#ifndef STANDARD
+#include "standard.h"
+#endif
+
+#ifndef RECYCLE
+#define RECYCLE
+
+#define RESTART 0
+#define REMAX 32000
+
+struct recycle
+{
+ struct recycle *next;
+};
+typedef struct recycle recycle;
+
+struct reroot
+{
+ struct recycle *list; /* list of malloced blocks */
+ struct recycle *trash; /* list of deleted items */
+ size_t size; /* size of an item */
+ size_t logsize; /* log_2 of number of items in a block */
+ word numleft; /* number of bytes left in this block */
+};
+typedef struct reroot reroot;
+
+/* make a new recycling root */
+reroot *remkroot(/*_ size_t mysize _*/);
+
+/* free a recycling root and all the items it has made */
+void refree(/*_ struct reroot *r _*/);
+
+/* get a new (cleared) item from the root */
+#define renew(r) ((r)->numleft ? \
+ (((char *)((r)->list+1))+((r)->numleft-=(r)->size)) : renewx(r))
+
+char *renewx(/*_ struct reroot *r _*/);
+
+/* delete an item; let the root recycle it */
+/* void redel(/o_ struct reroot *r, struct recycle *item _o/); */
+#define redel(root,item) { \
+ ((recycle *)item)->next=(root)->trash; \
+ (root)->trash=(recycle *)(item); \
+}
+
+/* malloc, but complain to stderr and exit program if no joy */
+/* use plain free() to free memory allocated by remalloc() */
+char *remalloc(/*_ size_t len, char *purpose _*/);
+
+#endif /* RECYCLE */
diff --git a/tools/codegen/core/perfect/run.sh b/tools/codegen/core/perfect/run.sh
new file mode 100755
index 0000000000..c0d1fc3b81
--- /dev/null
+++ b/tools/codegen/core/perfect/run.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -e
+cd $(dirname $0)
+fn=$1
+shift
+./perfect $* < $fn
diff --git a/tools/codegen/core/perfect/standard.h b/tools/codegen/core/perfect/standard.h
new file mode 100644
index 0000000000..202a5d658c
--- /dev/null
+++ b/tools/codegen/core/perfect/standard.h
@@ -0,0 +1,57 @@
+/*
+------------------------------------------------------------------------------
+Standard definitions and types, Bob Jenkins
+------------------------------------------------------------------------------
+*/
+#ifndef STANDARD
+# define STANDARD
+# ifndef STDIO
+# include <stdio.h>
+# define STDIO
+# endif
+# ifndef STDDEF
+# include <stddef.h>
+# define STDDEF
+# endif
+typedef unsigned long long ub8;
+#define UB8MAXVAL 0xffffffffffffffffLL
+#define UB8BITS 64
+typedef signed long long sb8;
+#define SB8MAXVAL 0x7fffffffffffffffLL
+typedef unsigned long int ub4; /* unsigned 4-byte quantities */
+#define UB4MAXVAL 0xffffffff
+typedef signed long int sb4;
+#define UB4BITS 32
+#define SB4MAXVAL 0x7fffffff
+typedef unsigned short int ub2;
+#define UB2MAXVAL 0xffff
+#define UB2BITS 16
+typedef signed short int sb2;
+#define SB2MAXVAL 0x7fff
+typedef unsigned char ub1;
+#define UB1MAXVAL 0xff
+#define UB1BITS 8
+typedef signed char sb1; /* signed 1-byte quantities */
+#define SB1MAXVAL 0x7f
+typedef int word; /* fastest type available */
+
+#define bis(target,mask) ((target) |= (mask))
+#define bic(target,mask) ((target) &= ~(mask))
+#define bit(target,mask) ((target) & (mask))
+#ifndef min
+# define min(a,b) (((a)<(b)) ? (a) : (b))
+#endif /* min */
+#ifndef max
+# define max(a,b) (((a)<(b)) ? (b) : (a))
+#endif /* max */
+#ifndef align
+# define align(a) (((ub4)a+(sizeof(void *)-1))&(~(sizeof(void *)-1)))
+#endif /* align */
+#ifndef abs
+# define abs(a) (((a)>0) ? (a) : -(a))
+#endif
+#define TRUE 1
+#define FALSE 0
+#define SUCCESS 0 /* 1 on VAX */
+
+#endif /* STANDARD */
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index ff3a0e381d..62d6e794f9 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -840,6 +840,7 @@ include/grpc/impl/codegen/atm.h \
include/grpc/impl/codegen/atm_gcc_atomic.h \
include/grpc/impl/codegen/atm_gcc_sync.h \
include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
include/grpc/impl/codegen/gpr_types.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/slice.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 04e8f4e7f2..52c406cba8 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -840,6 +840,7 @@ include/grpc/impl/codegen/atm.h \
include/grpc/impl/codegen/atm_gcc_atomic.h \
include/grpc/impl/codegen/atm_gcc_sync.h \
include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
include/grpc/impl/codegen/gpr_types.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/slice.h \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index 1e748ba4a8..4a1378eeaa 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -779,6 +779,7 @@ include/grpc/impl/codegen/atm.h \
include/grpc/impl/codegen/atm_gcc_atomic.h \
include/grpc/impl/codegen/atm_gcc_sync.h \
include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
include/grpc/impl/codegen/gpr_types.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/slice.h \
@@ -818,6 +819,7 @@ include/grpc/impl/codegen/atm.h \
include/grpc/impl/codegen/atm_gcc_atomic.h \
include/grpc/impl/codegen/atm_gcc_sync.h \
include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
include/grpc/impl/codegen/gpr_types.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/slice.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index a629bdc542..bf19ebcfb6 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -779,6 +779,7 @@ include/grpc/impl/codegen/atm.h \
include/grpc/impl/codegen/atm_gcc_atomic.h \
include/grpc/impl/codegen/atm_gcc_sync.h \
include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
include/grpc/impl/codegen/gpr_types.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/slice.h \
@@ -862,6 +863,7 @@ src/core/lib/json/json_common.h \
src/core/lib/json/json_reader.h \
src/core/lib/json/json_writer.h \
src/core/lib/slice/percent_encoding.h \
+src/core/lib/slice/slice_hash_table.h \
src/core/lib/slice/slice_string_helpers.h \
src/core/lib/surface/api_trace.h \
src/core/lib/surface/call.h \
@@ -876,7 +878,6 @@ src/core/lib/surface/lame_client.h \
src/core/lib/surface/server.h \
src/core/lib/transport/byte_stream.h \
src/core/lib/transport/connectivity_state.h \
-src/core/lib/transport/mdstr_hash_table.h \
src/core/lib/transport/metadata.h \
src/core/lib/transport/metadata_batch.h \
src/core/lib/transport/pid_controller.h \
@@ -1048,6 +1049,8 @@ src/core/lib/json/json_writer.c \
src/core/lib/slice/percent_encoding.c \
src/core/lib/slice/slice.c \
src/core/lib/slice/slice_buffer.c \
+src/core/lib/slice/slice_hash_table.c \
+src/core/lib/slice/slice_intern.c \
src/core/lib/slice/slice_string_helpers.c \
src/core/lib/surface/alarm.c \
src/core/lib/surface/api_trace.c \
@@ -1069,7 +1072,6 @@ src/core/lib/surface/validate_metadata.c \
src/core/lib/surface/version.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
-src/core/lib/transport/mdstr_hash_table.c \
src/core/lib/transport/metadata.c \
src/core/lib/transport/metadata_batch.c \
src/core/lib/transport/pid_controller.c \
@@ -1208,6 +1210,7 @@ include/grpc/impl/codegen/atm.h \
include/grpc/impl/codegen/atm_gcc_atomic.h \
include/grpc/impl/codegen/atm_gcc_sync.h \
include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/exec_ctx_fwd.h \
include/grpc/impl/codegen/gpr_types.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/slice.h \
diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py
new file mode 100755
index 0000000000..cf88c42d46
--- /dev/null
+++ b/tools/run_tests/sanity/core_banned_functions.py
@@ -0,0 +1,31 @@
+#!/usr/bin/python
+
+import os
+import sys
+
+os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../..'))
+
+# map of banned function signature to whitelist
+BANNED_EXCEPT = {
+ 'grpc_resource_quota_ref(': ['src/core/lib/iomgr/resource_quota.c'],
+ 'grpc_resource_quota_unref(': ['src/core/lib/iomgr/resource_quota.c'],
+ 'grpc_slice_buffer_destroy(': ['src/core/lib/slice/slice_buffer.c'],
+ 'grpc_slice_buffer_reset_and_unref(': ['src/core/lib/slice/slice_buffer.c'],
+ 'grpc_slice_ref(': ['src/core/lib/slice/slice.c'],
+ 'grpc_slice_unref(': ['src/core/lib/slice/slice.c'],
+}
+
+errors = 0
+for root, dirs, files in os.walk('src/core'):
+ for filename in files:
+ path = os.path.join(root, filename)
+ if os.path.splitext(path)[1] != '.c': continue
+ with open(path) as f:
+ text = f.read()
+ for banned, exceptions in BANNED_EXCEPT.items():
+ if path in exceptions: continue
+ if banned in text:
+ print 'Illegal use of "%s" in %s' % (banned, path)
+ errors += 1
+
+assert errors == 0
diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml
index 32e62dd529..37819166e3 100644
--- a/tools/run_tests/sanity/sanity_tests.yaml
+++ b/tools/run_tests/sanity/sanity_tests.yaml
@@ -3,6 +3,7 @@
- script: tools/run_tests/sanity/check_sources_and_headers.py
- script: tools/run_tests/sanity/check_submodules.sh
- script: tools/run_tests/sanity/check_test_filtering.py
+- script: tools/run_tests/sanity/core_banned_functions.py
- script: tools/buildgen/generate_projects.sh -j 3
cpu_cost: 3
- script: tools/distrib/check_copyright.py
@@ -12,3 +13,4 @@
- script: tools/distrib/check_nanopb_output.sh
- script: tools/distrib/check_include_guards.py
- script: tools/distrib/python/check_grpcio_tools.py
+
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 9be07941d7..fa00ca214f 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -6628,6 +6628,7 @@
"include/grpc/impl/codegen/atm_gcc_atomic.h",
"include/grpc/impl/codegen/atm_gcc_sync.h",
"include/grpc/impl/codegen/atm_windows.h",
+ "include/grpc/impl/codegen/exec_ctx_fwd.h",
"include/grpc/impl/codegen/gpr_types.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/slice.h",
@@ -6644,6 +6645,7 @@
"include/grpc/impl/codegen/atm_gcc_atomic.h",
"include/grpc/impl/codegen/atm_gcc_sync.h",
"include/grpc/impl/codegen/atm_windows.h",
+ "include/grpc/impl/codegen/exec_ctx_fwd.h",
"include/grpc/impl/codegen/gpr_types.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/slice.h",
@@ -6744,6 +6746,7 @@
"src/core/lib/json/json_reader.h",
"src/core/lib/json/json_writer.h",
"src/core/lib/slice/percent_encoding.h",
+ "src/core/lib/slice/slice_hash_table.h",
"src/core/lib/slice/slice_string_helpers.h",
"src/core/lib/surface/api_trace.h",
"src/core/lib/surface/call.h",
@@ -6758,7 +6761,6 @@
"src/core/lib/surface/server.h",
"src/core/lib/transport/byte_stream.h",
"src/core/lib/transport/connectivity_state.h",
- "src/core/lib/transport/mdstr_hash_table.h",
"src/core/lib/transport/metadata.h",
"src/core/lib/transport/metadata_batch.h",
"src/core/lib/transport/pid_controller.h",
@@ -6937,6 +6939,9 @@
"src/core/lib/slice/percent_encoding.h",
"src/core/lib/slice/slice.c",
"src/core/lib/slice/slice_buffer.c",
+ "src/core/lib/slice/slice_hash_table.c",
+ "src/core/lib/slice/slice_hash_table.h",
+ "src/core/lib/slice/slice_intern.c",
"src/core/lib/slice/slice_string_helpers.c",
"src/core/lib/slice/slice_string_helpers.h",
"src/core/lib/surface/alarm.c",
@@ -6972,8 +6977,6 @@
"src/core/lib/transport/byte_stream.h",
"src/core/lib/transport/connectivity_state.c",
"src/core/lib/transport/connectivity_state.h",
- "src/core/lib/transport/mdstr_hash_table.c",
- "src/core/lib/transport/mdstr_hash_table.h",
"src/core/lib/transport/metadata.c",
"src/core/lib/transport/metadata.h",
"src/core/lib/transport/metadata_batch.c",
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj b/vsprojects/vcxproj/gpr/gpr.vcxproj
index ce593473c0..f87e9be543 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj
@@ -177,6 +177,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
index a50a9f4200..ffa89d77cc 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
@@ -225,6 +225,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index f281db72b6..3dd4da1e01 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -338,6 +338,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index f359e4ef31..f589efbf55 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -354,6 +354,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
index d2305b2e25..75997b6498 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
@@ -185,6 +185,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
index d1aaba7092..421ab760b3 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
@@ -147,6 +147,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index 1511a2cfe4..a11510e360 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -338,6 +338,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index bed77b25a4..747f1ca71b 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -339,6 +339,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 81b43f7a87..da24dd58e5 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -286,6 +286,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
@@ -371,6 +372,7 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h" />
+ <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h" />
@@ -385,7 +387,6 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\server.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h" />
- <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\mdstr_hash_table.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h" />
@@ -642,6 +643,10 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_buffer.c">
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.c">
+ </ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_intern.c">
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\alarm.c">
@@ -684,8 +689,6 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.c">
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\mdstr_hash_table.c">
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index 2f4a659aaa..9adff1667a 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -250,6 +250,12 @@
<ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_buffer.c">
<Filter>src\core\lib\slice</Filter>
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.c">
+ <Filter>src\core\lib\slice</Filter>
+ </ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_intern.c">
+ <Filter>src\core\lib\slice</Filter>
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.c">
<Filter>src\core\lib\slice</Filter>
</ClCompile>
@@ -313,9 +319,6 @@
<ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.c">
<Filter>src\core\lib\transport</Filter>
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\mdstr_hash_table.c">
- <Filter>src\core\lib\transport</Filter>
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata.c">
<Filter>src\core\lib\transport</Filter>
</ClCompile>
@@ -699,6 +702,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
@@ -950,6 +956,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h">
<Filter>src\core\lib\slice</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.h">
+ <Filter>src\core\lib\slice</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h">
<Filter>src\core\lib\slice</Filter>
</ClInclude>
@@ -992,9 +1001,6 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h">
<Filter>src\core\lib\transport</Filter>
</ClInclude>
- <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\mdstr_hash_table.h">
- <Filter>src\core\lib\transport</Filter>
- </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h">
<Filter>src\core\lib\transport</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index 2acdd32cf3..a9a5d72372 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -166,6 +166,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
@@ -264,6 +265,7 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h" />
+ <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h" />
@@ -278,7 +280,6 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\server.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h" />
- <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\mdstr_hash_table.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h" />
@@ -493,6 +494,10 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_buffer.c">
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.c">
+ </ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_intern.c">
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\alarm.c">
@@ -535,8 +540,6 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.c">
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\mdstr_hash_table.c">
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c">
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
index 6c918f1254..ab79e8dc53 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -307,6 +307,12 @@
<ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_buffer.c">
<Filter>src\core\lib\slice</Filter>
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.c">
+ <Filter>src\core\lib\slice</Filter>
+ </ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_intern.c">
+ <Filter>src\core\lib\slice</Filter>
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.c">
<Filter>src\core\lib\slice</Filter>
</ClCompile>
@@ -370,9 +376,6 @@
<ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.c">
<Filter>src\core\lib\transport</Filter>
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\mdstr_hash_table.c">
- <Filter>src\core\lib\transport</Filter>
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata.c">
<Filter>src\core\lib\transport</Filter>
</ClCompile>
@@ -456,6 +459,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
@@ -746,6 +752,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h">
<Filter>src\core\lib\slice</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.h">
+ <Filter>src\core\lib\slice</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h">
<Filter>src\core\lib\slice</Filter>
</ClInclude>
@@ -788,9 +797,6 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h">
<Filter>src\core\lib\transport</Filter>
</ClInclude>
- <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\mdstr_hash_table.h">
- <Filter>src\core\lib\transport</Filter>
- </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h">
<Filter>src\core\lib\transport</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index c96d48db58..1d6e4394f4 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -277,6 +277,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
@@ -361,6 +362,7 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h" />
+ <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h" />
@@ -375,7 +377,6 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\server.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h" />
- <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\mdstr_hash_table.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h" />
@@ -610,6 +611,10 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_buffer.c">
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.c">
+ </ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_intern.c">
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\alarm.c">
@@ -652,8 +657,6 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.c">
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\mdstr_hash_table.c">
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 4b75288b2b..3792df7a9c 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -253,6 +253,12 @@
<ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_buffer.c">
<Filter>src\core\lib\slice</Filter>
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.c">
+ <Filter>src\core\lib\slice</Filter>
+ </ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_intern.c">
+ <Filter>src\core\lib\slice</Filter>
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.c">
<Filter>src\core\lib\slice</Filter>
</ClCompile>
@@ -316,9 +322,6 @@
<ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.c">
<Filter>src\core\lib\transport</Filter>
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\mdstr_hash_table.c">
- <Filter>src\core\lib\transport</Filter>
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata.c">
<Filter>src\core\lib\transport</Filter>
</ClCompile>
@@ -615,6 +618,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
@@ -863,6 +869,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\percent_encoding.h">
<Filter>src\core\lib\slice</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_hash_table.h">
+ <Filter>src\core\lib\slice</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\slice\slice_string_helpers.h">
<Filter>src\core\lib\slice</Filter>
</ClInclude>
@@ -905,9 +914,6 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h">
<Filter>src\core\lib\transport</Filter>
</ClInclude>
- <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\mdstr_hash_table.h">
- <Filter>src\core\lib\transport</Filter>
- </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h">
<Filter>src\core\lib\transport</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
index a2b2a1dfa0..8e4c71fc3f 100644
--- a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
@@ -198,6 +198,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
index 94b6c2530e..cc0286af9f 100644
--- a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
+++ b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
@@ -135,6 +135,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
index 1a3c157983..1a6829b09f 100644
--- a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
@@ -198,6 +198,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
index 1f4b60ca4d..bfe435aa04 100644
--- a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
+++ b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
@@ -138,6 +138,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
index 1e3cc3ca04..ea33eef9b4 100644
--- a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
+++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
@@ -199,6 +199,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
diff --git a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
index 1c308c5881..6cd6b07394 100644
--- a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
+++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
@@ -129,6 +129,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\exec_ctx_fwd.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>